+
+(defun naturalize-bounded-c-string (pointer offset &optional max-length)
+ "Return the 0-terminated string starting at (+ POINTER OFFSET) with
+maximum length MAX-LENGTH, as a lisp object."
+ (let* ((ptr
+ (typecase pointer
+ (sb-sys:system-area-pointer
+ (sap-alien (sb-sys:sap+ pointer offset) (* sb-alien:char)))
+ (t
+ (sap-alien (sb-sys:sap+ (alien-sap pointer) offset) (* sb-alien:char)))))
+ (length (loop for i upfrom 0
+ until (or (and max-length
+ (= i (1- max-length)))
+ (= (sb-alien:deref ptr i) 0))
+ finally (return i)))
+ (result (make-string length
+ :element-type 'base-char)))
+ (sb-kernel:copy-from-system-area (alien-sap ptr) 0
+ result (* sb-vm:vector-data-offset
+ sb-vm:n-word-bits)
+ (* length sb-vm:n-byte-bits))
+ result))
+
+(defun set-bounded-c-string (pointer offset max-length value)
+ "Set the range from POINTER + OFFSET to at most POINTER + OFFSET +
+MAX-LENGTH to the string contained in VALUE."
+ (assert (numberp max-length) nil
+ "Structure field must have a grovelable maximum length.")
+ (assert (< (length value) max-length))
+ (let* ((ptr
+ (typecase pointer
+ (sb-sys:system-area-pointer
+ (sap-alien (sb-sys:sap+ pointer offset) (* sb-alien:char)))
+ (t
+ (sap-alien (sb-sys:sap+ (alien-sap pointer) offset) (* sb-alien:char)))))
+ (length (length value)))
+ (sb-kernel:copy-to-system-area value (* sb-vm:vector-data-offset
+ sb-vm:n-word-bits)
+ (alien-sap ptr) 0
+ (* length sb-vm:n-byte-bits))
+ (setf (sb-alien:deref ptr length) 0)
+ value))