pack-length-bytes

Started by Sammo, March 31, 2006, 10:48:14 AM

Previous topic - Next topic

Sammo

In case anyone's interested, here is function 'pack-length-bytes' to compute and return the number of bytes that a proper 'pack' format string would produce. It works by cleverly replacing the elements of the format string with the number of bytes for each element, then summing those numbers.
;; pack-length-bytes
;; return the number of bytes defined by a well-formed
;; 'pack' format string
;;
;; e.g.,
;; (pack-length-bytes ">ucc c s27 s4 n1 s3 n22 n2") --> 64
;; (pack-length-bytes "cccccs27s4n1s3n22n2") --> 64
;;
;; Knowing that 'replace' is destructive is the key to
;; understanding this function.
;;
;; The (cons 0 (map ...)) hack returns 0 for the
;; legal "" str-format.
;;
(define (pack-length-bytes str-format)
  (let
    ( TABLE '((">"  ""  )   ;order of table entries matters
              ("<"  ""  )
              ("ld" "4 ")   ;"ld" must precede "d"
              ("lf" "8 ")   ;"lf" must precede "f"
              ("lu" "4 ")   ;"lu" must precede "u"
              ("b"  "1 ")
              ("c"  "1 ")
              ("d"  "2 ")
              ("f"  "4 ")
              ("u"  "2 ")
              ("s"  " " )
              ("n"  " " ))
    )
  ;body of let
    (map (fn (x) (replace (x 0) str-format (x 1))) TABLE)
    (apply + (cons 0 (map integer (parse str-format)))) ))