housekeeping for indefinite streams

main
Matthew Butterick 6 years ago
parent 4798afa5b5
commit 31cb060e02

@ -1,6 +1,8 @@
#lang racket/base
#lang debug racket/base
(require racket/class
racket/contract
racket/match
racket/sequence
"base.rkt" "util.rkt" "number.rkt" "list.rkt" racket/stream sugar/unstable/dict)
(provide (all-defined-out))
@ -16,7 +18,7 @@ https://github.com/mbutterick/restructure/blob/master/src/LazyArray.coffee
(define/override (x:decode port parent)
(define starting-pos (pos port)) ; ! placement matters. `resolve-length` will change `pos`
(define len (resolve-length @len port parent))
(define maybe-len (resolve-length @len port parent))
(define new-parent (if (x:int? @len)
(mhasheq x:parent-key parent
x:start-offset-key starting-pos
@ -24,17 +26,35 @@ https://github.com/mbutterick/restructure/blob/master/src/LazyArray.coffee
x:length-key @len)
parent))
(define stream-starting-pos (pos port))
(define item-size (send @type x:size #f new-parent))
;; have to be able to retreive nth item of stream, random access
(define item-indexes-retrieved null)
(begin0
(for/stream ([index (in-range len)])
(define orig-pos (pos port))
(pos port (+ stream-starting-pos (* (send @type x:size #f new-parent) index)))
(for*/stream ([index (in-range (or maybe-len +inf.0))]
[orig-pos (in-value (pos port))]
[index-pos (in-value (pos port (+ stream-starting-pos (* item-size index))))]
[_ (in-value (begin (pos port index-pos) void))]
;; for streams of indefinite length, stop gathering when we're at eof
#:break (and (not maybe-len) (eof-object? (peek-byte port))))
(when (eof-object? (peek-byte port))
(raise-argument-error 'decode (format "bytes for ~a items" index) (pos port)))
(begin0
(send @type x:decode port new-parent)
(set! item-indexes-retrieved (cons index item-indexes-retrieved))
(pos port orig-pos)))
(pos port (+ (pos port) (* len (send @type x:size #f new-parent))))))
(let ([items-to-skip (or maybe-len (if (pair? item-indexes-retrieved)
(add1 (apply max item-indexes-retrieved))
0))])
(pos port (+ (pos port) (* items-to-skip item-size))))))
(define/override (x:encode val port [parent #f])
(super x:encode (if (stream? val) (stream->list val) val) port parent))
(define/override (x:encode val-arg port [parent #f])
(unless (or (stream? val-arg) (sequence? val-arg))
(raise-argument-error 'encode "sequence or stream" val-arg))
(define vals (match val-arg
[(? list?) val-arg]
[(? stream?) (stream->list val-arg)]
[_ (sequence->list val-arg)]))
(super x:encode vals port parent))
(define/override (x:size [val #f] [parent #f])
(super x:size (if (stream? val) (stream->list val) val) parent))))
@ -60,10 +80,10 @@ https://github.com/mbutterick/restructure/blob/master/src/LazyArray.coffee
. ->* .
x:stream?)
(define type (or type-arg type-kwarg))
(unless (xenomorphic? type)
(unless (xenomorphic? type)
(raise-argument-error 'x:stream "xenomorphic type" type))
(define len (or len-arg len-kwarg))
(unless (length-resolvable? len)
(unless (length-resolvable? len)
(raise-argument-error 'x:stream "resolvable length" len))
(new (generate-subclass base-class pre-proc post-proc) [type type]
[len len]

Loading…
Cancel
Save