0
; Frequently used functions in erlang binary takes a single unsigned byte and maps it to an int.
0
-(define (byte->uint byte) (integer-bytes->integer (bytes-append #"\0" bytes) #f #t))
0
-(define (bytes->int bytes) (integer-bytes->integer bytes #t #t))
0
+(define (byte->uint byte)
0
+ (integer-bytes->integer (bytes-append #"\0" byte) #f #t))
0
+(define (bytes->int bytes)
0
+ (integer-bytes->integer bytes #t #t))
0
; Specification language macro
0
(define-syntax define-binary-parser
0
(xform processor-spec)] ...
0
[else (raise `(unknown-data-type ,identifier ,bytes))])))))]))
0
-(define (parse-raw-entity bytes size processor)
0
- (let [(rem-bytes (subbytes bytes size))
0
- (data-bytes (subbytes bytes 0 size))]
0
- (cons (processor data-bytes) rem-bytes)))
0
-(define (parse-sized-entity bytes size-field-length processor)
0
- (let* [(sizebytes (subbytes bytes 0 size-field-length))
0
- (size (integer-bytes->integer sizebytes #f #t))]
0
- (parse-raw-entity (subbytes bytes size-field-length) size processor)))
0
(define-binary-parser erlang-term-parser
0
[ERL_LIST (custom list-parser)]
0
[ERL_SMALL_TUPLE (custom small-tuple-parser)]
0
; Recursive datatype parsers
0
(define (repeat-parser dbytes size-field-size size-field-converter finalizer)
0
(let* [(sbytes (subbytes dbytes 0 size-field-size))
0
(ebytes (subbytes dbytes size-field-size))
0
(nelems (size-field-converter sbytes))]
0
- ; input is: bytes, countdown, accumulated elements
0
- (letrec [(loop (lambda (b c accum)
0
- (fprintf (current-error-port) "Inner loop (~s) with ~s~n" c accum)
0
- (cond ((equal? c 0) (cons (finalizer (reverse accum)) b))
0
- (match-let [((val . rbytes) (erlang-term-parser b))]
0
- (loop rbytes (sub1 c) (cons val accum)))))
0
- (loop ebytes nelems (list)))))
0
+ (let loop ([b ebytes] [c nelems] [accum (list)])
0
+ (cond ((equal? c 0) (cons (finalizer (reverse accum)) b))
0
+ (match-let [((val . rbytes) (erlang-term-parser b))]
0
+ (loop rbytes (sub1 c) (cons val accum))))))))
0
(define (small-tuple-parser dbytes) (repeat-parser dbytes 1 byte->uint (lambda (x) (list->vector x))))
0
(define (large-tuple-parser dbytes) (repeat-parser dbytes 4 bytes->int (lambda (x) (list->vector x))))
0
(match-let [((val . rbytes) (repeat-parser dbytes 4 bytes->int (lambda (x) x)))]
0
(cons val (subbytes rbytes 1)))) ; Skip the trailing nil in lists.
0
+(define (parse-raw-entity bytes size processor)
0
+ (let [(rem-bytes (subbytes bytes size))
0
+ (data-bytes (subbytes bytes 0 size))]
0
+ (cons (processor data-bytes) rem-bytes)))
0
+(define (parse-sized-entity bytes size-field-length processor)
0
+ (let* [(sizebytes (subbytes bytes 0 size-field-length))
0
+ (size (integer-bytes->integer sizebytes #f #t))]
0
+ (parse-raw-entity (subbytes bytes size-field-length) size processor)))
0
(define (read-size-field)
0
(let ([size-bytes (read-stream 4)])
Comments
No one has commented yet.