[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 0c3ce42: * lisp/emacs-lisp/bindat.el: Allow non-fixed size of `st
From: |
Stefan Monnier |
Subject: |
master 0c3ce42: * lisp/emacs-lisp/bindat.el: Allow non-fixed size of `strz` |
Date: |
Thu, 15 Apr 2021 11:28:10 -0400 (EDT) |
branch: master
commit 0c3ce42c8f12f1865a3327448bc58f472f153bf9
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>
* 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.
---
doc/lispref/processes.texi | 5 +++--
lisp/emacs-lisp/bindat.el | 33 ++++++++++++++++++++++++---------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index 6786ac2..0dfdac7 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -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
diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el
index 9899496..247fb91 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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 0c3ce42: * lisp/emacs-lisp/bindat.el: Allow non-fixed size of `strz`,
Stefan Monnier <=