mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-26 07:33:47 +00:00
* lisp/emacs-lisp/bindat.el: Allow non-fixed size of strz
(bindat--unpack-strz): Allow `len` to be nil. (bindat--pack-strz): New function. (bindat--type) <strz>: Make `len` arg optional. (bindat-type): Adjust debug spec and docstring accordingly. * doc/lispref/processes.texi (Bindat Types): Adjust accordingly.
This commit is contained in:
parent
7893945cc8
commit
0c3ce42c8f
@ -3410,8 +3410,9 @@ Unsigned integer in little endian order, with @var{bitlen} bits.
|
||||
@item str @var{len}
|
||||
String of bytes of length @var{len}.
|
||||
|
||||
@item strz @var{len}
|
||||
Zero-terminated string of bytes, in a fixed-size field with length @var{len}.
|
||||
@item strz &optional @var{len}
|
||||
Zero-terminated string of bytes, can be of arbitrary length or in a fixed-size
|
||||
field with length @var{len}.
|
||||
|
||||
@item vec @var{len} [@var{type}]
|
||||
Vector of @var{len} elements. The type of the elements is given by
|
||||
|
@ -167,7 +167,7 @@
|
||||
|
||||
(defun bindat--unpack-strz (len)
|
||||
(let ((i 0) s)
|
||||
(while (and (< i len) (/= (aref bindat-raw (+ bindat-idx i)) 0))
|
||||
(while (and (if len (< i len) t) (/= (aref bindat-raw (+ bindat-idx i)) 0))
|
||||
(setq i (1+ i)))
|
||||
(setq s (substring bindat-raw bindat-idx (+ bindat-idx i)))
|
||||
(setq bindat-idx (+ bindat-idx len))
|
||||
@ -439,6 +439,12 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
||||
(aset bindat-raw (+ bindat-idx i) (aref v i)))
|
||||
(setq bindat-idx (+ bindat-idx len)))
|
||||
|
||||
(defun bindat--pack-strz (v)
|
||||
(let ((len (length v)))
|
||||
(dotimes (i len)
|
||||
(aset bindat-raw (+ bindat-idx i) (aref v i)))
|
||||
(setq bindat-idx (+ bindat-idx len 1))))
|
||||
|
||||
(defun bindat--pack-bits (len v)
|
||||
(let ((bnum (1- (* 8 len))) j m)
|
||||
(while (>= bnum 0)
|
||||
@ -677,14 +683,23 @@ is the name of a variable that will hold the value we need to pack.")
|
||||
(`(length . ,_) `(cl-incf bindat-idx ,len))
|
||||
(`(pack . ,args) `(bindat--pack-str ,len . ,args))))
|
||||
|
||||
(cl-defmethod bindat--type (op (_ (eql strz)) len)
|
||||
(cl-defmethod bindat--type (op (_ (eql strz)) &optional len)
|
||||
(bindat--pcase op
|
||||
('unpack `(bindat--unpack-strz ,len))
|
||||
(`(length . ,_) `(cl-incf bindat-idx ,len))
|
||||
;; Here we don't add the terminating zero because we rely
|
||||
;; on the fact that `bindat-raw' was presumably initialized with
|
||||
;; all-zeroes before we started.
|
||||
(`(pack . ,args) `(bindat--pack-str ,len . ,args))))
|
||||
(`(length ,val)
|
||||
`(cl-incf bindat-idx ,(cond
|
||||
((null len) `(length ,val))
|
||||
((numberp len) len)
|
||||
(t `(or ,len (length ,val))))))
|
||||
(`(pack . ,args)
|
||||
(macroexp-let2 nil len len
|
||||
`(if ,len
|
||||
;; Same as non-zero terminated strings 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).
|
||||
(bindat--pack-str ,len . ,args)
|
||||
(bindat--pack-strz . ,args))))))
|
||||
|
||||
(cl-defmethod bindat--type (op (_ (eql bits)) len)
|
||||
(bindat--pcase op
|
||||
@ -812,7 +827,7 @@ is the name of a variable that will hold the value we need to pack.")
|
||||
'(&or ["uint" def-form]
|
||||
["uintr" def-form]
|
||||
["str" def-form]
|
||||
["strz" def-form]
|
||||
["strz" &optional def-form]
|
||||
["bits" def-form]
|
||||
["fill" def-form]
|
||||
["align" def-form]
|
||||
@ -832,7 +847,7 @@ TYPE is a Bindat type expression. It can take the following forms:
|
||||
uint BITLEN - Big-endian unsigned integer
|
||||
uintr BITLEN - Little-endian unsigned integer
|
||||
str LEN - Byte string
|
||||
strz LEN - Zero-terminated byte-string
|
||||
strz [LEN] - Zero-terminated byte-string
|
||||
bits LEN - Bit vector (LEN is counted in bytes)
|
||||
fill LEN - Just a filler
|
||||
align LEN - Fill up to the next multiple of LEN bytes
|
||||
|
Loading…
Reference in New Issue
Block a user