diff options
| -rw-r--r-- | lisp/emacs-lisp/bindat.el | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/lisp/emacs-lisp/bindat.el b/lisp/emacs-lisp/bindat.el index c58c286ef75..1e491697430 100644 --- a/lisp/emacs-lisp/bindat.el +++ b/lisp/emacs-lisp/bindat.el | |||
| @@ -147,7 +147,7 @@ | |||
| 147 | ;; | u16r | u24r | u32r -- little endian byte order. | 147 | ;; | u16r | u24r | u32r -- little endian byte order. |
| 148 | ;; | str LEN -- LEN byte string | 148 | ;; | str LEN -- LEN byte string |
| 149 | ;; | strz LEN -- LEN byte (zero-terminated) string | 149 | ;; | strz LEN -- LEN byte (zero-terminated) string |
| 150 | ;; | vec LEN -- LEN byte vector | 150 | ;; | vec LEN [TYPE] -- vector of LEN items of TYPE (default: u8) |
| 151 | ;; | ip -- 4 byte vector | 151 | ;; | ip -- 4 byte vector |
| 152 | ;; | bits LEN -- List with bits set in LEN bytes. | 152 | ;; | bits LEN -- List with bits set in LEN bytes. |
| 153 | ;; | 153 | ;; |
| @@ -207,30 +207,24 @@ | |||
| 207 | (setq bindat-idx (1+ bindat-idx)))) | 207 | (setq bindat-idx (1+ bindat-idx)))) |
| 208 | 208 | ||
| 209 | (defun bindat--unpack-u16 () | 209 | (defun bindat--unpack-u16 () |
| 210 | (let* ((a (bindat--unpack-u8)) (b (bindat--unpack-u8))) | 210 | (logior (lsh (bindat--unpack-u8) 8) (bindat--unpack-u8))) |
| 211 | (logior (lsh a 8) b))) | ||
| 212 | 211 | ||
| 213 | (defun bindat--unpack-u24 () | 212 | (defun bindat--unpack-u24 () |
| 214 | (let* ((a (bindat--unpack-u16)) (b (bindat--unpack-u8))) | 213 | (logior (lsh (bindat--unpack-u16) 8) (bindat--unpack-u8))) |
| 215 | (logior (lsh a 8) b))) | ||
| 216 | 214 | ||
| 217 | (defun bindat--unpack-u32 () | 215 | (defun bindat--unpack-u32 () |
| 218 | (let* ((a (bindat--unpack-u16)) (b (bindat--unpack-u16))) | 216 | (logior (lsh (bindat--unpack-u16) 16) (bindat--unpack-u16))) |
| 219 | (logior (lsh a 16) b))) | ||
| 220 | 217 | ||
| 221 | (defun bindat--unpack-u16r () | 218 | (defun bindat--unpack-u16r () |
| 222 | (let* ((a (bindat--unpack-u8)) (b (bindat--unpack-u8))) | 219 | (logior (bindat--unpack-u8) (lsh (bindat--unpack-u8) 8))) |
| 223 | (logior a (lsh b 8)))) | ||
| 224 | 220 | ||
| 225 | (defun bindat--unpack-u24r () | 221 | (defun bindat--unpack-u24r () |
| 226 | (let* ((a (bindat--unpack-u16r)) (b (bindat--unpack-u8))) | 222 | (logior (bindat--unpack-u16r) (lsh (bindat--unpack-u8) 16))) |
| 227 | (logior a (lsh b 16)))) | ||
| 228 | 223 | ||
| 229 | (defun bindat--unpack-u32r () | 224 | (defun bindat--unpack-u32r () |
| 230 | (let* ((a (bindat--unpack-u16r)) (b (bindat--unpack-u16r))) | 225 | (logior (bindat--unpack-u16r) (lsh (bindat--unpack-u16r) 16))) |
| 231 | (logior a (lsh b 16)))) | ||
| 232 | 226 | ||
| 233 | (defun bindat--unpack-item (type len) | 227 | (defun bindat--unpack-item (type len &optional vectype) |
| 234 | (if (eq type 'ip) | 228 | (if (eq type 'ip) |
| 235 | (setq type 'vec len 4)) | 229 | (setq type 'vec len 4)) |
| 236 | (cond | 230 | (cond |
| @@ -274,9 +268,14 @@ | |||
| 274 | (if (stringp s) s | 268 | (if (stringp s) s |
| 275 | (string-make-unibyte (concat s))))) | 269 | (string-make-unibyte (concat s))))) |
| 276 | ((eq type 'vec) | 270 | ((eq type 'vec) |
| 277 | (let ((v (make-vector len 0)) (i 0)) | 271 | (let ((v (make-vector len 0)) (i 0) (vlen 1)) |
| 272 | (if (consp vectype) | ||
| 273 | (setq vlen (nth 1 vectype) | ||
| 274 | vectype (nth 2 vectype)) | ||
| 275 | (setq type (or vectype 'u8) | ||
| 276 | vectype nil)) | ||
| 278 | (while (< i len) | 277 | (while (< i len) |
| 279 | (aset v i (bindat--unpack-u8)) | 278 | (aset v i (bindat--unpack-item type vlen vectype)) |
| 280 | (setq i (1+ i))) | 279 | (setq i (1+ i))) |
| 281 | v)) | 280 | v)) |
| 282 | (t nil))) | 281 | (t nil))) |
| @@ -288,6 +287,7 @@ | |||
| 288 | (field (car item)) | 287 | (field (car item)) |
| 289 | (type (nth 1 item)) | 288 | (type (nth 1 item)) |
| 290 | (len (nth 2 item)) | 289 | (len (nth 2 item)) |
| 290 | (vectype (and (eq type 'vec) (nth 3 item))) | ||
| 291 | (tail 3) | 291 | (tail 3) |
| 292 | data) | 292 | data) |
| 293 | (setq spec (cdr spec)) | 293 | (setq spec (cdr spec)) |
| @@ -335,7 +335,7 @@ | |||
| 335 | (setq data (bindat--unpack-group (cdr case)) | 335 | (setq data (bindat--unpack-group (cdr case)) |
| 336 | cases nil))))) | 336 | cases nil))))) |
| 337 | (t | 337 | (t |
| 338 | (setq data (bindat--unpack-item type len) | 338 | (setq data (bindat--unpack-item type len vectype) |
| 339 | last data))) | 339 | last data))) |
| 340 | (if data | 340 | (if data |
| 341 | (if field | 341 | (if field |
| @@ -384,6 +384,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 384 | (field (car item)) | 384 | (field (car item)) |
| 385 | (type (nth 1 item)) | 385 | (type (nth 1 item)) |
| 386 | (len (nth 2 item)) | 386 | (len (nth 2 item)) |
| 387 | (vectype (and (eq type 'vec) (nth 3 item))) | ||
| 387 | (tail 3)) | 388 | (tail 3)) |
| 388 | (setq spec (cdr spec)) | 389 | (setq spec (cdr spec)) |
| 389 | (if (and (consp field) (eq (car field) 'eval)) | 390 | (if (and (consp field) (eq (car field) 'eval)) |
| @@ -401,6 +402,13 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 401 | (setq len (apply 'bindat-get-field struct len))) | 402 | (setq len (apply 'bindat-get-field struct len))) |
| 402 | (if (not len) | 403 | (if (not len) |
| 403 | (setq len 1)) | 404 | (setq len 1)) |
| 405 | (while (eq type 'vec) | ||
| 406 | (let ((vlen 1)) | ||
| 407 | (if (consp vectype) | ||
| 408 | (setq len (* len (nth 1 vectype)) | ||
| 409 | type (nth 2 vectype)) | ||
| 410 | (setq type (or vectype 'u8) | ||
| 411 | vectype nil)))) | ||
| 404 | (cond | 412 | (cond |
| 405 | ((eq type 'eval) | 413 | ((eq type 'eval) |
| 406 | (if field | 414 | (if field |
| @@ -434,7 +442,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 434 | (setq cases nil)))))) | 442 | (setq cases nil)))))) |
| 435 | (t | 443 | (t |
| 436 | (if (setq type (assq type bindat--fixed-length-alist)) | 444 | (if (setq type (assq type bindat--fixed-length-alist)) |
| 437 | (setq len (cdr type))) | 445 | (setq len (* len (cdr type)))) |
| 438 | (if field | 446 | (if field |
| 439 | (setq last (bindat-get-field struct field))) | 447 | (setq last (bindat-get-field struct field))) |
| 440 | (setq bindat-idx (+ bindat-idx len)))))))) | 448 | (setq bindat-idx (+ bindat-idx len)))))))) |
| @@ -478,7 +486,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 478 | (bindat--pack-u16r v) | 486 | (bindat--pack-u16r v) |
| 479 | (bindat--pack-u16r (lsh v -16))) | 487 | (bindat--pack-u16r (lsh v -16))) |
| 480 | 488 | ||
| 481 | (defun bindat--pack-item (v type len) | 489 | (defun bindat--pack-item (v type len &optional vectype) |
| 482 | (if (eq type 'ip) | 490 | (if (eq type 'ip) |
| 483 | (setq type 'vec len 4)) | 491 | (setq type 'vec len 4)) |
| 484 | (cond | 492 | (cond |
| @@ -511,13 +519,24 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 511 | (setq bnum (1- bnum) | 519 | (setq bnum (1- bnum) |
| 512 | j (lsh j -1)))) | 520 | j (lsh j -1)))) |
| 513 | (bindat--pack-u8 m)))) | 521 | (bindat--pack-u8 m)))) |
| 514 | ((memq type '(str strz vec)) | 522 | ((memq type '(str strz)) |
| 515 | (let ((l (length v)) (i 0)) | 523 | (let ((l (length v)) (i 0)) |
| 516 | (if (> l len) (setq l len)) | 524 | (if (> l len) (setq l len)) |
| 517 | (while (< i l) | 525 | (while (< i l) |
| 518 | (aset bindat-raw (+ bindat-idx i) (aref v i)) | 526 | (aset bindat-raw (+ bindat-idx i) (aref v i)) |
| 519 | (setq i (1+ i))) | 527 | (setq i (1+ i))) |
| 520 | (setq bindat-idx (+ bindat-idx len)))) | 528 | (setq bindat-idx (+ bindat-idx len)))) |
| 529 | ((eq type 'vec) | ||
| 530 | (let ((l (length v)) (i 0) (vlen 1)) | ||
| 531 | (if (consp vectype) | ||
| 532 | (setq vlen (nth 1 vectype) | ||
| 533 | vectype (nth 2 vectype)) | ||
| 534 | (setq type (or vectype 'u8) | ||
| 535 | vectype nil)) | ||
| 536 | (if (> l len) (setq l len)) | ||
| 537 | (while (< i l) | ||
| 538 | (bindat--pack-item (aref v i) type vlen vectype) | ||
| 539 | (setq i (1+ i))))) | ||
| 521 | (t | 540 | (t |
| 522 | (setq bindat-idx (+ bindat-idx len))))) | 541 | (setq bindat-idx (+ bindat-idx len))))) |
| 523 | 542 | ||
| @@ -528,6 +547,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 528 | (field (car item)) | 547 | (field (car item)) |
| 529 | (type (nth 1 item)) | 548 | (type (nth 1 item)) |
| 530 | (len (nth 2 item)) | 549 | (len (nth 2 item)) |
| 550 | (vectype (and (eq type 'vec) (nth 3 item))) | ||
| 531 | (tail 3)) | 551 | (tail 3)) |
| 532 | (setq spec (cdr spec)) | 552 | (setq spec (cdr spec)) |
| 533 | (if (and (consp field) (eq (car field) 'eval)) | 553 | (if (and (consp field) (eq (car field) 'eval)) |
| @@ -578,7 +598,7 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..." | |||
| 578 | (setq cases nil)))))) | 598 | (setq cases nil)))))) |
| 579 | (t | 599 | (t |
| 580 | (setq last (bindat-get-field struct field)) | 600 | (setq last (bindat-get-field struct field)) |
| 581 | (bindat--pack-item last type len) | 601 | (bindat--pack-item last type len vectype) |
| 582 | )))))) | 602 | )))))) |
| 583 | 603 | ||
| 584 | (defun bindat-pack (spec struct &optional bindat-raw bindat-idx) | 604 | (defun bindat-pack (spec struct &optional bindat-raw bindat-idx) |