(but excluding) the null byte that terminated the input string.
If @var{len} is provided, @code{strz} behaves the same as @code{str},
-but with one difference: when unpacking, the first null byte
-encountered in the packed string is interpreted as the terminating
-byte, and it and all subsequent bytes are excluded from the result of
-the unpacking.
+but with a couple of differences:
-@quotation Caution
-The packed output will not be null-terminated unless one of the
-following is true:
-@itemize
+@itemize @bullet
@item
-The input string is shorter than @var{len} bytes and either no pre-allocated
-string was provided to @code{bindat-pack} or the appropriate byte in
-the pre-allocated string was already null.
+When packing, a null terminator is written after the packed input
+string if the number of characters in the input string is less than
+@var{len}.
+
@item
-The input string contains a null byte within the first @var{len}
-bytes.
+When unpacking, the first null byte encountered in the packed string
+is interpreted as the terminating byte, and it and all subsequent
+bytes are excluded from the result of the unpacking.
@end itemize
+
+@quotation Caution
+The packed output will not be null-terminated unless the input string
+is shorter than @var{len} bytes or it contains a null byte within the
+first @var{len} bytes.
@end quotation
@item vec @var{len} [@var{type}]
(defun bindat--pack-strz (len v)
(let* ((v (string-to-unibyte v))
(vlen (length v)))
+ ;; Explicitly write a null terminator (if there's room) in case
+ ;; the user provided a pre-allocated string to `bindat-pack' that
+ ;; wasn't already zeroed.
+ (when (or (null len) (< vlen len))
+ (aset bindat-raw (+ bindat-idx vlen) 0))
(if len
;; When len is specified, behave the same as the str type
- ;; since we don't actually add the terminating zero anyway
- ;; (because we rely on the fact that `bindat-raw' was
- ;; presumably initialized with all-zeroes before we started).
+ ;; (except for the null terminator possibly written above).
(bindat--pack-str len v)
(dotimes (i vlen)
(when (= (aref v i) 0)
;; need to scan the input string looking for a null byte.
(error "Null byte encountered in input strz string"))
(aset bindat-raw (+ bindat-idx i) (aref v i)))
- ;; Explicitly write a null terminator in case the user provided
- ;; a pre-allocated string to `bindat-pack' that wasn't already
- ;; zeroed.
- (aset bindat-raw (+ bindat-idx vlen) 0)
(setq bindat-idx (+ bindat-idx vlen 1)))))
(defun bindat--pack-bits (len v)
((((x str 2)) ((x . "a"))) . "ax")
((((x str 2)) ((x . "ab"))) . "ab")
((((x str 2)) ((x . "abc"))) . "ab")
- ((,(bindat-type strz 1) "") . "xx")
- ((,(bindat-type strz 2) "") . "xx")
- ((,(bindat-type strz 2) "a") . "ax")
+ ((,(bindat-type strz 1) "") . "\0x")
+ ((,(bindat-type strz 2) "") . "\0x")
+ ((,(bindat-type strz 2) "a") . "a\0")
((,(bindat-type strz 2) "ab") . "ab")
((,(bindat-type strz 2) "abc") . "ab")
- ((((x strz 1)) ((x . ""))) . "xx")
- ((((x strz 2)) ((x . ""))) . "xx")
- ((((x strz 2)) ((x . "a"))) . "ax")
+ ((((x strz 1)) ((x . ""))) . "\0x")
+ ((((x strz 2)) ((x . ""))) . "\0x")
+ ((((x strz 2)) ((x . "a"))) . "a\0")
((((x strz 2)) ((x . "ab"))) . "ab")
((((x strz 2)) ((x . "abc"))) . "ab")
((,(bindat-type strz) "") . "\0x")