mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 10:31:37 -08: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
2 changed files with 27 additions and 11 deletions
|
|
@ -3410,8 +3410,9 @@ Unsigned integer in little endian order, with @var{bitlen} bits.
|
||||||
@item str @var{len}
|
@item str @var{len}
|
||||||
String of bytes of length @var{len}.
|
String of bytes of length @var{len}.
|
||||||
|
|
||||||
@item strz @var{len}
|
@item strz &optional @var{len}
|
||||||
Zero-terminated string of bytes, in a fixed-size field with length @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}]
|
@item vec @var{len} [@var{type}]
|
||||||
Vector of @var{len} elements. The type of the elements is given by
|
Vector of @var{len} elements. The type of the elements is given by
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@
|
||||||
|
|
||||||
(defun bindat--unpack-strz (len)
|
(defun bindat--unpack-strz (len)
|
||||||
(let ((i 0) s)
|
(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 i (1+ i)))
|
||||||
(setq s (substring bindat-raw bindat-idx (+ bindat-idx i)))
|
(setq s (substring bindat-raw bindat-idx (+ bindat-idx i)))
|
||||||
(setq bindat-idx (+ bindat-idx len))
|
(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)))
|
(aset bindat-raw (+ bindat-idx i) (aref v i)))
|
||||||
(setq bindat-idx (+ bindat-idx len)))
|
(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)
|
(defun bindat--pack-bits (len v)
|
||||||
(let ((bnum (1- (* 8 len))) j m)
|
(let ((bnum (1- (* 8 len))) j m)
|
||||||
(while (>= bnum 0)
|
(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))
|
(`(length . ,_) `(cl-incf bindat-idx ,len))
|
||||||
(`(pack . ,args) `(bindat--pack-str ,len . ,args))))
|
(`(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
|
(bindat--pcase op
|
||||||
('unpack `(bindat--unpack-strz ,len))
|
('unpack `(bindat--unpack-strz ,len))
|
||||||
(`(length . ,_) `(cl-incf bindat-idx ,len))
|
(`(length ,val)
|
||||||
;; Here we don't add the terminating zero because we rely
|
`(cl-incf bindat-idx ,(cond
|
||||||
;; on the fact that `bindat-raw' was presumably initialized with
|
((null len) `(length ,val))
|
||||||
;; all-zeroes before we started.
|
((numberp len) len)
|
||||||
(`(pack . ,args) `(bindat--pack-str ,len . ,args))))
|
(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)
|
(cl-defmethod bindat--type (op (_ (eql bits)) len)
|
||||||
(bindat--pcase op
|
(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]
|
'(&or ["uint" def-form]
|
||||||
["uintr" def-form]
|
["uintr" def-form]
|
||||||
["str" def-form]
|
["str" def-form]
|
||||||
["strz" def-form]
|
["strz" &optional def-form]
|
||||||
["bits" def-form]
|
["bits" def-form]
|
||||||
["fill" def-form]
|
["fill" def-form]
|
||||||
["align" 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
|
uint BITLEN - Big-endian unsigned integer
|
||||||
uintr BITLEN - Little-endian unsigned integer
|
uintr BITLEN - Little-endian unsigned integer
|
||||||
str LEN - Byte string
|
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)
|
bits LEN - Bit vector (LEN is counted in bytes)
|
||||||
fill LEN - Just a filler
|
fill LEN - Just a filler
|
||||||
align LEN - Fill up to the next multiple of LEN bytes
|
align LEN - Fill up to the next multiple of LEN bytes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue