factor/extra/io/streams/peek/peek.factor

97 lines
2.9 KiB
Factor
Raw Normal View History

2011-09-16 22:34:19 -04:00
! Copyright (C) 2011 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien combinators combinators.short-circuit
destructors io io.ports io.private kernel locals math namespaces
2013-01-21 21:09:40 -05:00
sequences vectors ;
2011-09-16 22:34:19 -04:00
IN: io.streams.peek
TUPLE: peek-stream stream peeked ;
INSTANCE: peek-stream input-stream
INSTANCE: peek-stream output-stream
2011-09-16 22:34:19 -04:00
M: peek-stream dispose stream>> dispose ;
: stream-new-resizable ( n stream -- exemplar )
stream-exemplar new-resizable ; inline
2011-09-16 22:34:19 -04:00
: stream-like ( sequence stream -- sequence' )
stream-exemplar like ; inline
2011-09-16 22:34:19 -04:00
: stream-clone-resizable ( sequence stream -- sequence' )
stream-exemplar-growable clone-like ; inline
: <peek-stream> ( stream -- stream )
peek-stream new
swap >>stream
64 over stream-new-resizable >>peeked ; inline
M: peek-stream stream-element-type
stream>> stream-element-type ;
M: peek-stream stream-read1
dup peeked>> [
stream>> stream-read1
] [
pop nip
] if-empty ;
2011-10-13 17:09:13 -04:00
M:: peek-stream stream-read-unsafe ( n buf stream -- count )
2011-09-16 22:34:19 -04:00
stream peeked>> :> peeked
peeked length :> #peeked
#peeked 0 = [
2011-10-13 17:09:13 -04:00
n buf stream stream>> stream-read-unsafe
2011-09-16 22:34:19 -04:00
] [
2011-10-13 17:09:13 -04:00
#peeked n >= [
peeked <reversed> n head-slice 0 buf copy
peeked [ length n - ] keep shorten
n
2011-09-16 22:34:19 -04:00
] [
2011-10-13 17:09:13 -04:00
peeked <reversed> 0 buf copy
0 peeked shorten
n #peeked - :> n'
stream stream>> input-port? [
#peeked buf <displaced-alien>
] [
buf #peeked tail-slice
] if :> buf'
2011-10-13 17:09:13 -04:00
n' buf' stream stream-read-unsafe #peeked +
2011-09-16 22:34:19 -04:00
] if
] if ;
: peek-stream-read-until ( stream seps buf -- stream seps buf sep/f )
3dup [ [ stream-read1 dup ] dip member-eq? ] dip swap
[ drop ] [ over [ push peek-stream-read-until ] [ drop ] if ] if ;
M: peek-stream stream-read-until
swap 64 pick stream-new-resizable
peek-stream-read-until [ nip swap stream-like ] dip ;
M: peek-stream stream-write stream>> stream-write ;
M: peek-stream stream-write1 stream>> stream-write1 ;
M: peek-stream stream-flush stream>> stream-flush ;
M: peek-stream stream-tell stream>> stream-tell ;
M: peek-stream stream-seek stream>> stream-seek ;
2011-09-16 22:34:19 -04:00
: stream-peek1 ( stream -- elt )
2011-09-16 22:34:19 -04:00
dup peeked>> [
dup stream>> stream-read1 [
[ 1vector over stream-clone-resizable >>peeked drop ] keep
] [
drop f
] if*
] [
last nip
] if-empty ;
: stream-peek ( n stream -- seq )
2dup peeked>> { [ length <= ] [ length 0 > ] } 1&& [
[ peeked>> <reversed> swap head ] [ stream-exemplar like ] bi
2011-09-16 22:34:19 -04:00
] [
[ nip ]
[ stream-read ] 2bi
[ reverse swap peeked>> push-all ] keep
] if ;
: peek1 ( -- elt ) input-stream get stream-peek1 ; inline
: peek ( n -- seq ) input-stream get stream-peek ; inline