(bindat-idx, bindat-raw): Rename dynamic variables
`pos' and `raw-data' for clarity, as eval forms may access these.
This commit is contained in:
parent
16ddb1aeb7
commit
98d0738d27
1 changed files with 54 additions and 54 deletions
|
@ -188,21 +188,20 @@
|
|||
;; ([FIELD] eval FORM)
|
||||
;; is interpreted by evalling FORM for its side effects only.
|
||||
;; If FIELD is specified, the value is bound to that field.
|
||||
;; The FORM may access and update `raw-data' and `pos' (see `bindat-unpack'),
|
||||
;; as well as the lisp data structure in `struct'.
|
||||
;; The FORM may access and update `bindat-raw' and `bindat-idx' (see `bindat-unpack').
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; Helper functions for structure unpacking.
|
||||
;; Relies on dynamic binding of RAW-DATA and POS
|
||||
;; Relies on dynamic binding of BINDAT-RAW and BINDAT-IDX
|
||||
|
||||
(defvar raw-data)
|
||||
(defvar pos)
|
||||
(defvar bindat-raw)
|
||||
(defvar bindat-idx)
|
||||
|
||||
(defun bindat--unpack-u8 ()
|
||||
(prog1
|
||||
(aref raw-data pos)
|
||||
(setq pos (1+ pos))))
|
||||
(aref bindat-raw bindat-idx)
|
||||
(setq bindat-idx (1+ bindat-idx))))
|
||||
|
||||
(defun bindat--unpack-u16 ()
|
||||
(let* ((a (bindat--unpack-u8)) (b (bindat--unpack-u8)))
|
||||
|
@ -259,16 +258,16 @@
|
|||
j (lsh j -1)))))
|
||||
bits))
|
||||
((eq type 'str)
|
||||
(let ((s (substring raw-data pos (+ pos len))))
|
||||
(setq pos (+ pos len))
|
||||
(let ((s (substring bindat-raw bindat-idx (+ bindat-idx len))))
|
||||
(setq bindat-idx (+ bindat-idx len))
|
||||
(if (stringp s) s
|
||||
(string-make-unibyte (concat s)))))
|
||||
((eq type 'strz)
|
||||
(let ((i 0) s)
|
||||
(while (and (< i len) (/= (aref raw-data (+ pos i)) 0))
|
||||
(while (and (< i len) (/= (aref bindat-raw (+ bindat-idx i)) 0))
|
||||
(setq i (1+ i)))
|
||||
(setq s (substring raw-data pos (+ pos i)))
|
||||
(setq pos (+ pos len))
|
||||
(setq s (substring bindat-raw bindat-idx (+ bindat-idx i)))
|
||||
(setq bindat-idx (+ bindat-idx len))
|
||||
(if (stringp s) s
|
||||
(string-make-unibyte (concat s)))))
|
||||
((eq type 'vec)
|
||||
|
@ -310,10 +309,10 @@
|
|||
(setq data (eval len))
|
||||
(eval len)))
|
||||
((eq type 'fill)
|
||||
(setq pos (+ pos len)))
|
||||
(setq bindat-idx (+ bindat-idx len)))
|
||||
((eq type 'align)
|
||||
(while (/= (% pos len) 0)
|
||||
(setq pos (1+ pos))))
|
||||
(while (/= (% bindat-idx len) 0)
|
||||
(setq bindat-idx (1+ bindat-idx))))
|
||||
((eq type 'struct)
|
||||
(setq data (bindat--unpack-group (eval len))))
|
||||
((eq type 'repeat)
|
||||
|
@ -341,13 +340,13 @@
|
|||
(setq struct (append data struct))))))
|
||||
struct))
|
||||
|
||||
(defun bindat-unpack (spec raw-data &optional pos)
|
||||
"Return structured data according to SPEC for binary data in RAW-DATA.
|
||||
RAW-DATA is a unibyte string or vector. Optional third arg POS specifies
|
||||
the starting offset in RAW-DATA."
|
||||
(when (multibyte-string-p raw-data)
|
||||
(defun bindat-unpack (spec bindat-raw &optional bindat-idx)
|
||||
"Return structured data according to SPEC for binary data in BINDAT-RAW.
|
||||
BINDAT-RAW is a unibyte string or vector. Optional third arg BINDAT-IDX specifies
|
||||
the starting offset in BINDAT-RAW."
|
||||
(when (multibyte-string-p bindat-raw)
|
||||
(error "String is multibyte"))
|
||||
(unless pos (setq pos 0))
|
||||
(unless bindat-idx (setq bindat-idx 0))
|
||||
(bindat--unpack-group spec))
|
||||
|
||||
(defun bindat-get-field (struct &rest field)
|
||||
|
@ -366,7 +365,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
struct)
|
||||
|
||||
|
||||
;; Calculate raw-data length of structured data
|
||||
;; Calculate bindat-raw length of structured data
|
||||
|
||||
(defvar bindat--fixed-length-alist
|
||||
'((u8 . 1) (byte . 1)
|
||||
|
@ -405,10 +404,10 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(setq struct (cons (cons field (eval len)) struct))
|
||||
(eval len)))
|
||||
((eq type 'fill)
|
||||
(setq pos (+ pos len)))
|
||||
(setq bindat-idx (+ bindat-idx len)))
|
||||
((eq type 'align)
|
||||
(while (/= (% pos len) 0)
|
||||
(setq pos (1+ pos))))
|
||||
(while (/= (% bindat-idx len) 0)
|
||||
(setq bindat-idx (1+ bindat-idx))))
|
||||
((eq type 'struct)
|
||||
(bindat--length-group
|
||||
(if field (bindat-get-field struct field) struct) (eval len)))
|
||||
|
@ -435,25 +434,25 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(setq len (cdr type)))
|
||||
(if field
|
||||
(setq last (bindat-get-field struct field)))
|
||||
(setq pos (+ pos len))))))))
|
||||
(setq bindat-idx (+ bindat-idx len))))))))
|
||||
|
||||
(defun bindat-length (spec struct)
|
||||
"Calculate raw-data length for STRUCT according to bindat SPEC."
|
||||
(let ((pos 0))
|
||||
"Calculate bindat-raw length for STRUCT according to bindat SPEC."
|
||||
(let ((bindat-idx 0))
|
||||
(bindat--length-group struct spec)
|
||||
pos))
|
||||
bindat-idx))
|
||||
|
||||
|
||||
;; Pack structured data into raw-data
|
||||
;; Pack structured data into bindat-raw
|
||||
|
||||
(defun bindat--pack-u8 (v)
|
||||
(aset raw-data pos (logand v 255))
|
||||
(setq pos (1+ pos)))
|
||||
(aset bindat-raw bindat-idx (logand v 255))
|
||||
(setq bindat-idx (1+ bindat-idx)))
|
||||
|
||||
(defun bindat--pack-u16 (v)
|
||||
(aset raw-data pos (logand (lsh v -8) 255))
|
||||
(aset raw-data (1+ pos) (logand v 255))
|
||||
(setq pos (+ pos 2)))
|
||||
(aset bindat-raw bindat-idx (logand (lsh v -8) 255))
|
||||
(aset bindat-raw (1+ bindat-idx) (logand v 255))
|
||||
(setq bindat-idx (+ bindat-idx 2)))
|
||||
|
||||
(defun bindat--pack-u24 (v)
|
||||
(bindat--pack-u8 (lsh v -16))
|
||||
|
@ -464,9 +463,9 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(bindat--pack-u16 v))
|
||||
|
||||
(defun bindat--pack-u16r (v)
|
||||
(aset raw-data (1+ pos) (logand (lsh v -8) 255))
|
||||
(aset raw-data pos (logand v 255))
|
||||
(setq pos (+ pos 2)))
|
||||
(aset bindat-raw (1+ bindat-idx) (logand (lsh v -8) 255))
|
||||
(aset bindat-raw bindat-idx (logand v 255))
|
||||
(setq bindat-idx (+ bindat-idx 2)))
|
||||
|
||||
(defun bindat--pack-u24r (v)
|
||||
(bindat--pack-u16r v)
|
||||
|
@ -481,7 +480,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(setq type 'vec len 4))
|
||||
(cond
|
||||
((null v)
|
||||
(setq pos (+ pos len)))
|
||||
(setq bindat-idx (+ bindat-idx len)))
|
||||
((memq type '(u8 byte))
|
||||
(bindat--pack-u8 v))
|
||||
((memq type '(u16 word short))
|
||||
|
@ -513,11 +512,11 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(let ((l (length v)) (i 0))
|
||||
(if (> l len) (setq l len))
|
||||
(while (< i l)
|
||||
(aset raw-data (+ pos i) (aref v i))
|
||||
(aset bindat-raw (+ bindat-idx i) (aref v i))
|
||||
(setq i (1+ i)))
|
||||
(setq pos (+ pos len))))
|
||||
(setq bindat-idx (+ bindat-idx len))))
|
||||
(t
|
||||
(setq pos (+ pos len)))))
|
||||
(setq bindat-idx (+ bindat-idx len)))))
|
||||
|
||||
(defun bindat--pack-group (struct spec)
|
||||
(let (last)
|
||||
|
@ -549,10 +548,10 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(setq struct (cons (cons field (eval len)) struct))
|
||||
(eval len)))
|
||||
((eq type 'fill)
|
||||
(setq pos (+ pos len)))
|
||||
(setq bindat-idx (+ bindat-idx len)))
|
||||
((eq type 'align)
|
||||
(while (/= (% pos len) 0)
|
||||
(setq pos (1+ pos))))
|
||||
(while (/= (% bindat-idx len) 0)
|
||||
(setq bindat-idx (1+ bindat-idx))))
|
||||
((eq type 'struct)
|
||||
(bindat--pack-group
|
||||
(if field (bindat-get-field struct field) struct) (eval len)))
|
||||
|
@ -579,18 +578,19 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
|
|||
(bindat--pack-item last type len)
|
||||
))))))
|
||||
|
||||
(defun bindat-pack (spec struct &optional raw-data pos)
|
||||
(defun bindat-pack (spec struct &optional bindat-raw bindat-idx)
|
||||
"Return binary data packed according to SPEC for structured data STRUCT.
|
||||
Optional third arg RAW-DATA is a pre-allocated unibyte string or vector to
|
||||
pack into. Optional fourth arg POS is the starting offset into RAW-DATA."
|
||||
(when (multibyte-string-p raw-data)
|
||||
Optional third arg BINDAT-RAW is a pre-allocated unibyte string or vector to
|
||||
pack into.
|
||||
Optional fourth arg BINDAT-IDX is the starting offset into BINDAT-RAW."
|
||||
(when (multibyte-string-p bindat-raw)
|
||||
(error "Pre-allocated string is multibyte"))
|
||||
(let ((no-return raw-data))
|
||||
(unless pos (setq pos 0))
|
||||
(unless raw-data
|
||||
(setq raw-data (make-vector (+ pos (bindat-length spec struct)) 0)))
|
||||
(let ((no-return bindat-raw))
|
||||
(unless bindat-idx (setq bindat-idx 0))
|
||||
(unless bindat-raw
|
||||
(setq bindat-raw (make-vector (+ bindat-idx (bindat-length spec struct)) 0)))
|
||||
(bindat--pack-group struct spec)
|
||||
(if no-return nil (concat raw-data))))
|
||||
(if no-return nil (concat bindat-raw))))
|
||||
|
||||
|
||||
;; Misc. format conversions
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue