1 ! Copyright (C) 2011 Doug Coleman.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors alien combinators combinators.short-circuit
4 destructors io io.ports io.private kernel locals math namespaces
8 TUPLE: peek-stream stream peeked ;
9 INSTANCE: peek-stream input-stream
10 INSTANCE: peek-stream output-stream
12 M: peek-stream dispose stream>> dispose ;
14 : stream-new-resizable ( n stream -- exemplar )
15 stream-exemplar new-resizable ; inline
17 : stream-like ( sequence stream -- sequence' )
18 stream-exemplar like ; inline
20 : stream-clone-resizable ( sequence stream -- sequence' )
21 stream-exemplar-growable clone-like ; inline
23 : <peek-stream> ( stream -- stream )
26 64 over stream-new-resizable >>peeked ; inline
28 M: peek-stream stream-element-type
29 stream>> stream-element-type ;
31 M: peek-stream stream-read1
38 M:: peek-stream stream-read-unsafe ( n buf stream -- count )
39 stream peeked>> :> peeked
40 peeked length :> #peeked
42 n buf stream stream>> stream-read-unsafe
45 peeked <reversed> n head-slice 0 buf copy
46 peeked [ length n - ] keep shorten
49 peeked <reversed> 0 buf copy
52 stream stream>> input-port? [
53 #peeked buf <displaced-alien>
55 buf #peeked tail-slice
57 n' buf' stream stream-read-unsafe #peeked +
61 : peek-stream-read-until ( stream seps buf -- stream seps buf sep/f )
62 3dup [ [ stream-read1 dup ] dip member-eq? ] dip swap
63 [ drop ] [ over [ push peek-stream-read-until ] [ drop ] if ] if ;
65 M: peek-stream stream-read-until
66 swap 64 pick stream-new-resizable
67 peek-stream-read-until [ nip swap stream-like ] dip ;
69 M: peek-stream stream-write stream>> stream-write ;
70 M: peek-stream stream-write1 stream>> stream-write1 ;
71 M: peek-stream stream-flush stream>> stream-flush ;
72 M: peek-stream stream-tell stream>> stream-tell ;
73 M: peek-stream stream-seek stream>> stream-seek ;
75 : stream-peek1 ( stream -- elt )
77 dup stream>> stream-read1 [
78 [ 1vector over stream-clone-resizable >>peeked drop ] keep
86 : stream-peek ( n stream -- seq )
87 2dup peeked>> { [ length <= ] [ length 0 > ] } 1&& [
88 [ peeked>> <reversed> swap head ] [ stream-exemplar like ] bi
92 [ reverse swap peeked>> push-all ] keep
95 : peek1 ( -- elt ) input-stream get stream-peek1 ; inline
96 : peek ( n -- seq ) input-stream get stream-peek ; inline