Changeset 4098 for trunk/lisp/emacs-lisp/bindat.el
- Timestamp:
- 07/01/06 08:27:06 (2 years ago)
- Files:
-
- trunk/lisp/emacs-lisp/bindat.el (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/lisp/emacs-lisp/bindat.el
r4091 r4098 189 189 ;; is interpreted by evalling FORM for its side effects only. 190 190 ;; If FIELD is specified, the value is bound to that field. 191 ;; The FORM may access and update `raw-data' and `pos' (see `bindat-unpack'), 192 ;; as well as the lisp data structure in `struct'. 191 ;; The FORM may access and update `bindat-raw' and `bindat-idx' (see `bindat-unpack'). 193 192 194 193 ;;; Code: 195 194 196 195 ;; Helper functions for structure unpacking. 197 ;; Relies on dynamic binding of RAW-DATA and POS198 199 (defvar raw-data)200 (defvar pos)196 ;; Relies on dynamic binding of BINDAT-RAW and BINDAT-IDX 197 198 (defvar bindat-raw) 199 (defvar bindat-idx) 201 200 202 201 (defun bindat--unpack-u8 () 203 202 (prog1 204 (if (stringp raw-data) 205 (string-to-char (substring raw-data pos (1+ pos))) 206 (aref raw-data pos)) 207 (setq pos (1+ pos)))) 203 (aref bindat-raw bindat-idx) 204 (setq bindat-idx (1+ bindat-idx)))) 208 205 209 206 (defun bindat--unpack-u16 () … … 262 259 bits)) 263 260 ((eq type 'str) 264 (let ((s (substring raw-data pos (+ poslen))))265 (setq pos (+ poslen))261 (let ((s (substring bindat-raw bindat-idx (+ bindat-idx len)))) 262 (setq bindat-idx (+ bindat-idx len)) 266 263 (if (stringp s) s 267 264 (string-make-unibyte (concat s))))) 268 265 ((eq type 'strz) 269 266 (let ((i 0) s) 270 (while (and (< i len) (/= (aref raw-data (+ posi)) 0))267 (while (and (< i len) (/= (aref bindat-raw (+ bindat-idx i)) 0)) 271 268 (setq i (1+ i))) 272 (setq s (substring raw-data pos (+ posi)))273 (setq pos (+ poslen))269 (setq s (substring bindat-raw bindat-idx (+ bindat-idx i))) 270 (setq bindat-idx (+ bindat-idx len)) 274 271 (if (stringp s) s 275 272 (string-make-unibyte (concat s))))) … … 313 310 (eval len))) 314 311 ((eq type 'fill) 315 (setq pos (+ poslen)))312 (setq bindat-idx (+ bindat-idx len))) 316 313 ((eq type 'align) 317 (while (/= (% poslen) 0)318 (setq pos (1+ pos))))314 (while (/= (% bindat-idx len) 0) 315 (setq bindat-idx (1+ bindat-idx)))) 319 316 ((eq type 'struct) 320 317 (setq data (bindat--unpack-group (eval len)))) … … 344 341 struct)) 345 342 346 (defun bindat-unpack (spec raw-data &optional pos)347 "Return structured data according to SPEC for binary data in RAW-DATA.348 RAW-DATA is a unibyte string or vector. Optional third arg POSspecifies349 the starting offset in RAW-DATA."350 (when (multibyte-string-p raw-data)343 (defun bindat-unpack (spec bindat-raw &optional bindat-idx) 344 "Return structured data according to SPEC for binary data in BINDAT-RAW. 345 BINDAT-RAW is a unibyte string or vector. Optional third arg BINDAT-IDX specifies 346 the starting offset in BINDAT-RAW." 347 (when (multibyte-string-p bindat-raw) 351 348 (error "String is multibyte")) 352 (unless pos (setq pos0))349 (unless bindat-idx (setq bindat-idx 0)) 353 350 (bindat--unpack-group spec)) 354 351 … … 369 366 370 367 371 ;; Calculate raw-datalength of structured data368 ;; Calculate bindat-raw length of structured data 372 369 373 370 (defvar bindat--fixed-length-alist … … 408 405 (eval len))) 409 406 ((eq type 'fill) 410 (setq pos (+ poslen)))407 (setq bindat-idx (+ bindat-idx len))) 411 408 ((eq type 'align) 412 (while (/= (% poslen) 0)413 (setq pos (1+ pos))))409 (while (/= (% bindat-idx len) 0) 410 (setq bindat-idx (1+ bindat-idx)))) 414 411 ((eq type 'struct) 415 412 (bindat--length-group … … 438 435 (if field 439 436 (setq last (bindat-get-field struct field))) 440 (setq pos (+ poslen))))))))437 (setq bindat-idx (+ bindat-idx len)))))))) 441 438 442 439 (defun bindat-length (spec struct) 443 "Calculate raw-datalength for STRUCT according to bindat SPEC."444 (let (( pos0))440 "Calculate bindat-raw length for STRUCT according to bindat SPEC." 441 (let ((bindat-idx 0)) 445 442 (bindat--length-group struct spec) 446 pos))447 448 449 ;; Pack structured data into raw-data443 bindat-idx)) 444 445 446 ;; Pack structured data into bindat-raw 450 447 451 448 (defun bindat--pack-u8 (v) 452 (aset raw-data pos(logand v 255))453 (setq pos (1+ pos)))449 (aset bindat-raw bindat-idx (logand v 255)) 450 (setq bindat-idx (1+ bindat-idx))) 454 451 455 452 (defun bindat--pack-u16 (v) 456 (aset raw-data pos(logand (lsh v -8) 255))457 (aset raw-data (1+ pos) (logand v 255))458 (setq pos (+ pos2)))453 (aset bindat-raw bindat-idx (logand (lsh v -8) 255)) 454 (aset bindat-raw (1+ bindat-idx) (logand v 255)) 455 (setq bindat-idx (+ bindat-idx 2))) 459 456 460 457 (defun bindat--pack-u24 (v) … … 467 464 468 465 (defun bindat--pack-u16r (v) 469 (aset raw-data (1+ pos) (logand (lsh v -8) 255))470 (aset raw-data pos(logand v 255))471 (setq pos (+ pos2)))466 (aset bindat-raw (1+ bindat-idx) (logand (lsh v -8) 255)) 467 (aset bindat-raw bindat-idx (logand v 255)) 468 (setq bindat-idx (+ bindat-idx 2))) 472 469 473 470 (defun bindat--pack-u24r (v) … … 484 481 (cond 485 482 ((null v) 486 (setq pos (+ poslen)))483 (setq bindat-idx (+ bindat-idx len))) 487 484 ((memq type '(u8 byte)) 488 485 (bindat--pack-u8 v)) … … 516 513 (if (> l len) (setq l len)) 517 514 (while (< i l) 518 (aset raw-data (+ posi) (aref v i))515 (aset bindat-raw (+ bindat-idx i) (aref v i)) 519 516 (setq i (1+ i))) 520 (setq pos (+ poslen))))517 (setq bindat-idx (+ bindat-idx len)))) 521 518 (t 522 (setq pos (+ poslen)))))519 (setq bindat-idx (+ bindat-idx len))))) 523 520 524 521 (defun bindat--pack-group (struct spec) … … 552 549 (eval len))) 553 550 ((eq type 'fill) 554 (setq pos (+ poslen)))551 (setq bindat-idx (+ bindat-idx len))) 555 552 ((eq type 'align) 556 (while (/= (% poslen) 0)557 (setq pos (1+ pos))))553 (while (/= (% bindat-idx len) 0) 554 (setq bindat-idx (1+ bindat-idx)))) 558 555 ((eq type 'struct) 559 556 (bindat--pack-group … … 582 579 )))))) 583 580 584 (defun bindat-pack (spec struct &optional raw-data pos)581 (defun bindat-pack (spec struct &optional bindat-raw bindat-idx) 585 582 "Return binary data packed according to SPEC for structured data STRUCT. 586 Optional third arg RAW-DATA is a pre-allocated unibyte string or vector to 587 pack into. Optional fourth arg POS is the starting offset into RAW-DATA." 588 (when (multibyte-string-p raw-data) 583 Optional third arg BINDAT-RAW is a pre-allocated unibyte string or vector to 584 pack into. 585 Optional fourth arg BINDAT-IDX is the starting offset into BINDAT-RAW." 586 (when (multibyte-string-p bindat-raw) 589 587 (error "Pre-allocated string is multibyte")) 590 (let ((no-return raw-data))591 (unless pos (setq pos0))592 (unless raw-data593 (setq raw-data (make-vector (+ pos(bindat-length spec struct)) 0)))588 (let ((no-return bindat-raw)) 589 (unless bindat-idx (setq bindat-idx 0)) 590 (unless bindat-raw 591 (setq bindat-raw (make-vector (+ bindat-idx (bindat-length spec struct)) 0))) 594 592 (bindat--pack-group struct spec) 595 (if no-return nil (concat raw-data))))593 (if no-return nil (concat bindat-raw)))) 596 594 597 595
