* Change the interface of read-into to return a slice and an eof boolean separately so the compiler can optimize the slice.
* Add an each-stream-block-slice combinator that behaves like each-block but reuses a preallocated buffer for every iteration.
* Pull some strings in the stream-read-into implementation to further improve type propagation and bounds check elimination.
$io-error ;
HELP: read-into
-{ $values { "buf" { $or byte-array specialized-array string } } { "buf-slice/f" { $or slice f } } }
-{ $contract "Reads from the current " { $link input-stream } " into the sequence " { $snippet "buf" } ", until either the length of " { $snippet "buf" } " is reached or the stream is exhausted. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, or " { $link f } " if the stream was exhausted." }
+{ $values { "buf" { $or byte-array specialized-array string } } { "buf-slice" slice } { "more?" boolean } }
+{ $contract "Reads from the current " { $link input-stream } " into the sequence " { $snippet "buf" } ", until either the length of " { $snippet "buf" } " is reached or the stream is exhausted. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, and a boolean value that will be " { $link f } " if the stream was exhausted." }
$io-error ;
HELP: stream-read-into
-{ $values { "buf" { $or byte-array specialized-array string } } { "stream" "an input stream" } { "buf-slice/f" { $or slice f } } }
-{ $contract "Reads from the stream into the sequence " { $snippet "buf" } ", until either the length of " { $snippet "buf" } " is reached or the stream is exhausted. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, or " { $link f } " if the stream was exhausted." }
+{ $values { "buf" { $or byte-array specialized-array string } } { "stream" "an input stream" } { "buf-slice" slice } { "more?" boolean } }
+{ $contract "Reads from the stream into the sequence " { $snippet "buf" } ", until either the length of " { $snippet "buf" } " is reached or the stream is exhausted. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, and a boolean value that will be " { $link f } " if the stream was exhausted." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link read-into } "; see " { $link "stdio" } "." }
$io-error ;
$io-error ;
HELP: read-partial-into
-{ $values { "buf" { $or byte-array specialized-array string } } { "buf-slice/f" { $or slice f } } }
-{ $contract "Reads available data from the current " { $link input-stream } " into the sequence " { $snippet "buf" } " without blocking until all immediately available data is read or the length of " { $snippet "buf" } " is reached. If no data is immediately available, blocks until data is available. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, or " { $link f } " if the stream was exhausted." }
+{ $values { "buf" { $or byte-array specialized-array string } } { "buf-slice" slice } { "more?" boolean } }
+{ $contract "Reads available data from the current " { $link input-stream } " into the sequence " { $snippet "buf" } " without blocking until all immediately available data is read or the length of " { $snippet "buf" } " is reached. If no data is immediately available, blocks until data is available. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, and a boolean that will be " { $link f } " if the stream was exhausted." }
$io-error ;
HELP: stream-read-partial-into
-{ $values { "buf" { $or byte-array specialized-array string } } { "stream" "an input stream" } { "buf-slice/f" { $or slice f } } }
-{ $contract "Reads available data from the stream into the sequence " { $snippet "buf" } " without blocking until all immediately available data is read or the length of " { $snippet "buf" } " is reached. If no data is immediately available, blocks until data is available. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, or " { $link f } " if the stream was exhausted." }
+{ $values { "buf" { $or byte-array specialized-array string } } { "stream" "an input stream" } { "buf-slice" slice } { "more?" boolean } }
+{ $contract "Reads available data from the stream into the sequence " { $snippet "buf" } " without blocking until all immediately available data is read or the length of " { $snippet "buf" } " is reached. If no data is immediately available, blocks until data is available. Returns a " { $link slice } " over the part of " { $snippet "buf" } " that was written to, and a boolean that will be " { $link f } " if the stream was exhausted." }
{ $notes "Most code only works on one stream at a time and should instead use " { $link read-partial-into } "; see " { $link "stdio" } "." }
$io-error ;
[ up-to-13-reader new [ 20 swap stream-read ] [ 20 swap stream-read ] bi ] unit-test
{
- T{ slice f 0 8 B{ 0 1 2 3 4 5 6 7 } }
- T{ slice f 0 5 B{ 8 9 10 11 12 205 206 207 } }
- f
+ T{ slice f 0 8 B{ 0 1 2 3 4 5 6 7 } } t
+ T{ slice f 0 5 B{ 8 9 10 11 12 205 206 207 } } t
+ T{ slice f 0 0 B{ 8 9 10 11 12 205 206 207 } } f
} [
up-to-13-reader new
[ B{ 200 201 202 203 204 205 206 207 } swap stream-read-into ]
: (read-into) ( buf stream quot -- buf-slice/f )
[ dup length over ] 2dip call
- [ drop f ] [ head-slice ] if-zero ; inline
+ [ (head) <slice-unsafe> ] [ zero? not ] bi ; inline
+
+: fast>fixnum ( n -- n' )
+ dup fixnum? [ >fixnum ] unless ; inline
PRIVATE>
ERROR: invalid-read-buffer buf stream ;
-: stream-read-into ( buf stream -- buf-slice/f )
- [ stream-read-unsafe ] (read-into) ; inline
+USE: kernel.private
+: stream-read-into ( buf stream -- buf-slice more? )
+ [ stream-read-unsafe { fixnum } declare ] (read-into) ; inline
-: stream-read-partial-into ( buf stream -- buf-slice/f )
- [ stream-read-partial-unsafe ] (read-into) ; inline
+: stream-read-partial-into ( buf stream -- buf-slice more? )
+ [ stream-read-partial-unsafe { fixnum } declare ] (read-into) ; inline
: read ( n -- seq ) input-stream get stream-read ; inline
: read-partial ( n -- seq ) input-stream get stream-read-partial ; inline
-: read-into ( buf -- buf-slice/f )
+: read-into ( buf -- buf-slice more? )
input-stream get stream-read-into ; inline
-: read-partial-into ( buf -- buf-slice/f )
+: read-partial-into ( buf -- buf-slice more? )
input-stream get stream-read-partial-into ; inline
: each-stream-line ( ... stream quot: ( ... line -- ... ) -- ... )
: lines ( -- seq )
input-stream get stream-lines ; inline
+: each-stream-block-slice ( ... stream quot: ( ... block-slice -- ... ) -- ... )
+ [ drop ] prepose
+ swap [ 65536 swap (new-sequence-for-stream) ] keep
+ [ stream-read-partial-into ] 2curry each-morsel drop ; inline
+
: each-stream-block ( ... stream quot: ( ... block -- ... ) -- ... )
swap [ 65536 swap stream-read-partial ] curry each-morsel ; inline
+: each-block-slice ( ... quot: ( ... block -- ... ) -- ... )
+ input-stream get swap each-stream-block ; inline
+
: each-block ( ... quot: ( ... block -- ... ) -- ... )
input-stream get swap each-stream-block ; inline
[ drop > "start > end" slice-error ]
3tri ; inline
+<PRIVATE
+
+: <slice-unsafe> ( from to seq -- slice )
+ slice boa ; inline
+
+PRIVATE>
+
: <slice> ( from to seq -- slice )
check-slice
dup slice? [ collapse-slice ] when