#lang racket (require "packing.rkt" "number.rkt") (define (with-size/p size packing #:adjustment [adjustment 0]) (let ([size-packing (integer/p size #f)]) (make-packing (λ (in) (let ([size ((packing-reader size-packing) in)]) (if (not (eof-object? size)) ((packing-reader packing) (make-limited-input-port in (+ size adjustment))) eof))) (λ (v out) (let ([b (call-with-output-bytes (curry (packing-writer packing) v))]) ((packing-writer size-packing) (- (bytes-length b) adjustment) out) (write-bytes b out))) (packing-contract packing)))) (define (with-count/p size packing #:adjustment [adjustment 0]) (let ([count-packing (integer/p size #f)]) (make-packing (λ (in) (let ([count ((packing-reader count-packing) in)]) (if (not (eof-object? count)) (let ([count (+ count adjustment)]) (let/ec esc (do ([vs (make-vector count #f)] [i 0 (+ i 1)]) ((>= i count) vs) (let ([v ((packing-reader packing) in)]) (if (not (eof-object? v)) (vector-set! vs i v) (esc eof)))))) eof))) (λ (v out) ((packing-writer count-packing) (- (vector-length v) adjustment) out) (for ([v (in-vector v)]) ((packing-writer packing) v out))) (vectorof (packing-contract packing))))) (define bytes/p (make-packing port->bytes write-bytes bytes?)) (define string/p (make-packing port->string write-string string?)) (define symbol/p (wrap/p string->symbol symbol->string string/p symbol?)) (provide/contract [with-size/p (->* ((or/c 1 2 4 8) packing?) (#:adjustment exact-integer?) packing?)] [with-count/p (->* ((or/c 1 2 4 8) packing?) (#:adjustment exact-integer?) packing?)]) (provide bytes/p string/p symbol/p)