#lang racket
(provide (all-defined-out))
(define ((join-parsers . parsers) bytes offset)
(cond [(empty? parsers) (values empty offset)]
[else
(define-values (parsed new-offset)
((first parsers) bytes offset))
(define-values (rest-parsed final-offset)
((apply join-parsers (rest parsers)) bytes new-offset))
(values (cons parsed rest-parsed) final-offset)]))
(define ((parse-many parser) bytes offset)
(define len (integer-bytes->integer bytes #f #t offset
(+ offset 2)))
((parse-n-things len parser) bytes (+ offset 2)))
(define ((parse-n-things n parser) bytes offset)
(cond [(= n 0) (values empty offset)]
[else
(define-values (parsed new-offset)
(parser bytes offset))
(define-values (rest-parsed final-offset)
((parse-n-things (sub1 n) parser) bytes new-offset))
(values (cons parsed rest-parsed) final-offset)]))
(define (parse-float32 bytes offset)
(values (floating-point-bytes->real bytes #t offset (+ offset 4))
(+ offset 4)))
(define (parse-uint16 bytes offset)
(values (integer-bytes->integer bytes #f #t offset (+ offset 2))
(+ offset 2)))
(define (parse-uint8 bytes offset)
(values (bytes-ref bytes offset)
(+ offset 1)))
(define (parse-pstring bytes offset)
(define strlen (bytes-ref bytes offset))
(values (subbytes bytes (+ offset 1) (+ offset 1 strlen))
(+ offset 1 strlen)))
(module+ test
(require rackunit)
(check-equal? (call-with-values
(lambda ()
(parse-pstring #"5\24system_link_audio_1234" 1))
list)
(list #"system_link_audio_12" 22)))