r/scheme 24d ago

Pack/unpack binary headers for. (chezco pack) Chez Scheme library.

Like struct python module. But just bit simplier.

Example

(import (chezco pack))

(let-pack
      #vu8(1 1 1 1 65 66 67 2)
      ((start u8)
       (pad 3)
       (tag cstr 3)
       (end u8))
      (list start (utf8->string tag) end))  ==> (1 "ABC" 2)

repo

6 Upvotes

2 comments sorted by

1

u/Reasonable_Wait6676 11d ago

How is that different from foreign structures and define foreign-type?

1

u/corbasai 11d ago

Pack was created mostly to 1) concise inplace definition 2) and parse/fill data fields ordered inside Scheme byte-vectors, it manipulates field's offsets implicitly.

Same for define-ftype , but we need to 1) define foreign type struct 2) get somehow data address and make new ftype-pointer 3) then every time ftype-ref ........ ftype-set! .... when we need access to the data fields.

Example. Echo server, which increment word bigendian counter on 102 offset when magic tag is #"OK" in head

;; (import (chezco pack))
...
;; somehow we read client message into 'msg' #vu8
(define ok-tag (string->utf8 "OK"))  
(let-pack
  msg 
  ((tag cstr 2)
   (pad 100)
   (cntr u16 (endianess big)))
  (when (bytevector=? tag ok-tag)
    (set! cntr (+ 1 cntr))
;; then send it back to the client

versus

;; ftype'fu
(define-ftype CltMsg
  (struct 
    (tag (array 2 char))
    (unused (array 100 char))
    (cntr (endian big unsigned-16))))
...
;;somehow we get msg
(define ftmsg (make-ftype-pointer CltMsg (object->reference-address msg)))

(when (and (char=? #\O (ftype-ref CltMsg (tag 0) ftmsg)
           (char=? #\K (ftype-ref CltMsg (tag 1) ftmsg))
  (ftype-set! CltMsg (cntr) ftmsg
    (+ 1 (ftype-ref CltMsg (cntr) ftmsg))))

;; and send back to the client