diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2021-04-15 11:27:52 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2021-04-15 11:28:06 -0400 |
commit | 0c3ce42c8f12f1865a3327448bc58f472f153bf9 (patch) | |
tree | 6641c458249f3900adc64b4b0e33a8b56aad1d91 /lisp/emacs-lisp/bindat.el | |
parent | 7893945cc8f9421d0be5b07b9ed404bdf25ce140 (diff) | |
download | emacs-0c3ce42c8f12f1865a3327448bc58f472f153bf9.tar.gz emacs-0c3ce42c8f12f1865a3327448bc58f472f153bf9.tar.bz2 emacs-0c3ce42c8f12f1865a3327448bc58f472f153bf9.zip |
* 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.
Diffstat (limited to 'lisp/emacs-lisp/bindat.el')
-rw-r--r-- | lisp/emacs-lisp/bindat.el | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index 98994963e3e..247fb91379e 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el @@ -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 |