Split off io.streams.throwing from io.streams.limited and update usages of limited streams

db4
Doug Coleman 2010-07-09 13:30:57 -05:00
parent e752b4ff62
commit 2ca509a8fe
13 changed files with 181 additions and 285 deletions

View File

@ -14,6 +14,7 @@ io.encodings.ascii
io.encodings.binary io.encodings.binary
io.streams.limited io.streams.limited
io.streams.string io.streams.string
io.streams.throwing
io.servers.connection io.servers.connection
io.timeouts io.timeouts
io.crlf io.crlf
@ -50,13 +51,14 @@ ERROR: no-boundary ;
SYMBOL: upload-limit SYMBOL: upload-limit
: read-multipart-data ( request -- mime-parts ) : read-multipart-data ( request -- mime-parts )
[ "content-type" header ]
[ "content-length" header string>number ] bi
unlimited-input unlimited-input
upload-limit get stream-throws limit-input upload-limit get limited-input
stream-eofs limit-input [ "content-type" header ]
binary decode-input [ "content-length" header string>number limited-input ] bi
parse-multipart-form-data parse-multipart ; [
binary decode-input
parse-multipart-form-data parse-multipart
] input-throws-on-eof ;
: read-content ( request -- bytes ) : read-content ( request -- bytes )
"content-length" header string>number read ; "content-length" header string>number read ;
@ -277,15 +279,17 @@ TUPLE: http-server < threaded-server ;
SYMBOL: request-limit SYMBOL: request-limit
64 1024 * request-limit set-global request-limit [ 64 1024 * ] initialize
M: http-server handle-client* M: http-server handle-client*
drop [ drop [
request-limit get stream-throws limit-input request-limit get limited-input
?refresh-all [
[ read-request ] ?benchmark ?refresh-all
[ do-request ] ?benchmark [ read-request ] ?benchmark
[ do-response ] ?benchmark [ do-request ] ?benchmark
[ do-response ] ?benchmark
] input-throws-on-eof
] with-destructors ; ] with-destructors ;
: <http-server> ( -- server ) : <http-server> ( -- server )

View File

@ -1,11 +1,9 @@
! Copyright (C) 2007, 2009 Doug Coleman. ! Copyright (C) 2007, 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien alien.c-types arrays byte-arrays columns USING: accessors alien.c-types arrays byte-arrays combinators
combinators compression.run-length endian fry grouping images compression.run-length fry grouping images images.loader
images.loader images.normalization io io.binary images.normalization io io.binary io.encodings.8-bit.latin1
io.encodings.8-bit.latin1 io.encodings.binary io.encodings.string kernel math math.bitwise sequences
io.encodings.string io.files io.streams.limited kernel locals
macros math math.bitwise math.functions namespaces sequences
specialized-arrays summary ; specialized-arrays summary ;
QUALIFIED-WITH: bitstreams b QUALIFIED-WITH: bitstreams b
SPECIALIZED-ARRAYS: uint ushort ; SPECIALIZED-ARRAYS: uint ushort ;

View File

@ -1 +0,0 @@
Doug Coleman

View File

@ -1,7 +0,0 @@
! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types arrays byte-arrays combinators
compression.run-length fry grouping images images.loader io
io.binary io.encodings.binary
io.encodings.string io.streams.limited kernel math math.bitwise
io.encodings.8-bit.latin1 sequences specialized-arrays summary images.bitmap ;

View File

@ -1,15 +1,15 @@
! Copyright (C) 2009 Marc Fauconneau. ! Copyright (C) 2009 Marc Fauconneau.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays byte-arrays combinators USING: accessors arrays byte-arrays combinators
grouping compression.huffman images fry compression.huffman fry grouping images images.loader
images.processing io io.binary io.encodings.binary io.files images.processing io io.binary io.encodings.binary
io.streams.byte-array kernel locals math math.bitwise io.streams.byte-array io.streams.limited io.streams.throwing
math.constants math.functions math.matrices math.order kernel locals math math.bitwise math.blas.matrices
math.ranges math.vectors memoize multiline namespaces math.blas.vectors math.constants math.functions math.matrices
sequences sequences.deep images.loader io.streams.limited ; math.order math.vectors memoize namespaces sequences
IN: images.jpeg sequences.deep ;
QUALIFIED-WITH: bitstreams bs QUALIFIED-WITH: bitstreams bs
IN: images.jpeg
SINGLETON: jpeg-image SINGLETON: jpeg-image
@ -121,7 +121,7 @@ TUPLE: jpeg-color-info
: decode-huff-table ( chunk -- ) : decode-huff-table ( chunk -- )
data>> [ binary <byte-reader> ] [ length ] bi data>> [ binary <byte-reader> ] [ length ] bi
stream-throws limit limit-stream <throws-on-eof>
[ [
[ input-stream get [ count>> ] [ limit>> ] bi < ] [ input-stream get [ count>> ] [ limit>> ] bi < ]
[ [
@ -219,9 +219,6 @@ MEMO: dct-matrix ( -- m ) 64 iota [ 8 /mod dct-vect flatten ] map ;
: idct-factor ( b -- b' ) dct-matrix v.m ; : idct-factor ( b -- b' ) dct-matrix v.m ;
USE: math.blas.vectors
USE: math.blas.matrices
MEMO: dct-matrix-blas ( -- m ) dct-matrix >float-blas-matrix ; MEMO: dct-matrix-blas ( -- m ) dct-matrix >float-blas-matrix ;
: V.M ( x A -- x.A ) Mtranspose swap M.V ; : V.M ( x A -- x.A ) Mtranspose swap M.V ;
: idct-blas ( b -- b' ) >float-blas-vector dct-matrix-blas V.M ; : idct-blas ( b -- b' ) >float-blas-vector dct-matrix-blas V.M ;

View File

@ -1,9 +1,9 @@
! Copyright (C) 2009 Doug Coleman, Daniel Ehrenberg. ! Copyright (C) 2009 Doug Coleman, Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs byte-arrays combinators images USING: assocs byte-arrays io.encodings.binary io.files
io.encodings.binary io.files io.pathnames io.streams.byte-array io.pathnames io.streams.byte-array io.streams.limited
io.streams.limited kernel namespaces sequences splitting io.streams.throwing kernel namespaces sequences strings
strings unicode.case ; unicode.case fry ;
IN: images.loader IN: images.loader
ERROR: unknown-image-extension extension ; ERROR: unknown-image-extension extension ;
@ -18,7 +18,7 @@ types [ H{ } clone ] initialize
[ unknown-image-extension ] unless ; [ unknown-image-extension ] unless ;
: open-image-file ( path -- stream ) : open-image-file ( path -- stream )
binary stream-throws <limited-file-reader> ; binary <limited-file-reader> ;
PRIVATE> PRIVATE>
@ -36,9 +36,9 @@ GENERIC: stream>image ( stream class -- image )
M: byte-array load-image* M: byte-array load-image*
[ [
[ binary <byte-reader> ] [ binary <byte-reader> ] [ length ] bi
[ length stream-throws <limited-stream> ] bi <limited-stream> dup
] dip stream>image ; ] dip '[ _ stream>image ] throws-on-eof ;
M: limited-stream load-image* stream>image ; M: limited-stream load-image* stream>image ;

View File

@ -5,53 +5,29 @@ IN: io.streams.limited
HELP: <limited-stream> HELP: <limited-stream>
{ $values { $values
{ "stream" "an input stream" } { "limit" integer } { "mode" { $link stream-throws } " or " { $link stream-eofs } } { "stream" "an input stream" } { "limit" integer }
{ "stream'" "an input stream" } { "stream'" "an input stream" }
} }
{ $description "Constructs a new " { $link limited-stream } " from an existing stream. User code should use " { $link limit } " or " { $link limit-input } "." } ; { $description "Constructs a new " { $link limited-stream } " from an existing stream. User code should use " { $link limit-stream } " or " { $link limited-input } "." } ;
HELP: limit HELP: limit-stream
{ $values { $values
{ "stream" "an input stream" } { "limit" integer } { "mode" { $link stream-throws } " or " { $link stream-eofs } } { "stream" "an input stream" } { "limit" integer }
{ "stream'" "a stream" } { "stream'" "a stream" }
} }
{ $description "Changes a decoder's stream to be a limited stream, or wraps " { $snippet "stream" } " in a " { $link limited-stream } "." } { $description "Changes a decoder's stream to be a limited stream, or wraps " { $snippet "stream" } " in a " { $link limited-stream } "." }
{ $examples "Throwing an exception:" { $examples
{ $example "Limiting a longer stream to length three:"
"USING: continuations io io.streams.limited io.streams.string"
"kernel prettyprint ;"
"["
" \"123456\" <string-reader> 3 stream-throws limit"
" 100 swap stream-read ."
"] [ ] recover ."
"""T{ limit-exceeded
{ n 1 }
{ stream
T{ limited-stream
{ stream
T{ string-reader
{ underlying "123456" }
{ i 3 }
}
}
{ mode stream-throws }
{ count 4 }
{ limit 3 }
}
}
}"""
}
"Returning " { $link f } " on exhaustion:"
{ $example { $example
"USING: accessors continuations io io.streams.limited" "USING: accessors continuations io io.streams.limited"
"io.streams.string kernel prettyprint ;" "io.streams.string kernel prettyprint ;"
"\"123456\" <string-reader> 3 stream-eofs limit" "\"123456\" <string-reader> 3 limit-stream"
"100 swap stream-read ." "100 swap stream-read ."
"\"123\"" "\"123\""
} }
} ; } ;
HELP: unlimited HELP: unlimit-stream
{ $values { $values
{ "stream" "an input stream" } { "stream" "an input stream" }
{ "stream'" "a stream" } { "stream'" "a stream" }
@ -64,42 +40,22 @@ HELP: limited-stream
} }
{ $description "Limited streams wrap other streams, changing their behavior to throw an exception or return " { $link f } " upon exhaustion." } ; { $description "Limited streams wrap other streams, changing their behavior to throw an exception or return " { $link f } " upon exhaustion." } ;
HELP: limit-input HELP: limited-input
{ $values { $values { "limit" integer } }
{ "limit" integer } { "mode" { $link stream-throws } " or " { $link stream-eofs } }
}
{ $description "Wraps the current " { $link input-stream } " in a " { $link limited-stream } "." } ; { $description "Wraps the current " { $link input-stream } " in a " { $link limited-stream } "." } ;
HELP: unlimited-input HELP: unlimited-input
{ $description "Returns the underlying stream of the limited-stream stored in " { $link input-stream } "." } ; { $description "Returns the underlying stream of the limited-stream stored in " { $link input-stream } "." } ;
HELP: stream-eofs
{ $values
{ "value" { $link stream-throws } " or " { $link stream-eofs } }
}
{ $description "If the " { $slot "mode" } " of a limited stream is set to this singleton, the stream will return " { $link f } " upon exhaustion." } ;
HELP: stream-throws
{ $values
{ "value" { $link stream-throws } " or " { $link stream-eofs } }
}
{ $description "If the " { $slot "mode" } " of a limited stream is set to this singleton, the stream will throw " { $link limit-exceeded } " upon exhaustion." } ;
{ stream-eofs stream-throws } related-words
ARTICLE: "io.streams.limited" "Limited input streams" ARTICLE: "io.streams.limited" "Limited input streams"
"The " { $vocab-link "io.streams.limited" } " vocabulary wraps a stream to behave as if it had only a limited number of bytes, either throwing an error or returning " { $link f } " upon reaching the end. Limiting a non-seekable stream keeps a byte count and triggers the end-of-stream behavior when this byte count has been reached. However, limiting a seekable stream creates a window of bytes that supports seeking and re-reading of bytes in that window." $nl "The " { $vocab-link "io.streams.limited" } " vocabulary wraps a stream to behave as if it had only a limited number of bytes, either throwing an error or returning " { $link f } " upon reaching the end. Limiting a non-seekable stream keeps a byte count and triggers the end-of-stream behavior when this byte count has been reached. However, limiting a seekable stream creates a window of bytes that supports seeking and re-reading of bytes in that window." $nl
"Wrap a stream in a limited stream:" "Wrap a stream in a limited stream:"
{ $subsections limit } { $subsections limited-stream }
"Wrap the current " { $link input-stream } " in a limited stream:" "Wrap the current " { $link input-stream } " in a limited stream:"
{ $subsections limit-input } { $subsections limited-input }
"Unlimits a limited stream:" "Unlimits a limited stream:"
{ $subsections unlimited } { $subsections unlimit-stream }
"Unlimits the current " { $link input-stream } ":" "Unlimits the current " { $link input-stream } ":"
{ $subsections unlimited-input } { $subsections unlimited-input } ;
"Make a limited stream throw an exception on exhaustion:"
{ $subsections stream-throws }
"Make a limited stream return " { $link f } " on exhaustion:"
{ $subsections stream-eofs } ;
ABOUT: "io.streams.limited" ABOUT: "io.streams.limited"

View File

@ -11,7 +11,7 @@ IN: io.streams.limited.tests
ascii encode binary <byte-reader> "data" set ascii encode binary <byte-reader> "data" set
] unit-test ] unit-test
[ ] [ "data" get 24 stream-throws <limited-stream> "limited" set ] unit-test [ ] [ "data" get 24 <limited-stream> "limited" set ] unit-test
[ CHAR: h ] [ "limited" get stream-read1 ] unit-test [ CHAR: h ] [ "limited" get stream-read1 ] unit-test
@ -21,51 +21,48 @@ IN: io.streams.limited.tests
[ "how " ] [ 4 "decoded" get stream-read ] unit-test [ "how " ] [ 4 "decoded" get stream-read ] unit-test
[ "decoded" get stream-readln ] [ limit-exceeded? ] must-fail-with [ "are you " ] [ "decoded" get stream-readln ] unit-test
[ f ] [ "decoded" get stream-readln ] unit-test
[ ] [ [ ] [
"abc\ndef\nghi" "abc\ndef\nghi"
ascii encode binary <byte-reader> "data" set ascii encode binary <byte-reader> "data" set
] unit-test ] unit-test
[ ] [ "data" get 7 stream-throws <limited-stream> "limited" set ] unit-test [ ] [ "data" get 4 <limited-stream> "limited" set ] unit-test
[ "abc" CHAR: \n ] [ "\n" "limited" get stream-read-until [ >string ] dip ] unit-test [ "abc" CHAR: \n ]
[ "\n" "limited" get stream-read-until [ >string ] dip ] unit-test
[ "\n" "limited" get stream-read-until ] [ limit-exceeded? ] must-fail-with [ "" f ] [ "\n" "limited" get stream-read-until [ >string ] dip ] unit-test
[ "he" CHAR: l ] [
B{ CHAR: h CHAR: e CHAR: l CHAR: l CHAR: o }
ascii <byte-reader> [
5 stream-throws limit-input
"l" read-until
] with-input-stream
] unit-test
[ CHAR: a ] [ CHAR: a ]
[ "a" <string-reader> 1 stream-eofs <limited-stream> stream-read1 ] unit-test [ "a" <string-reader> 1 <limited-stream> stream-read1 ] unit-test
[ "abc" ] [ "abc" ]
[ [
"abc" <string-reader> 3 stream-eofs <limited-stream> "abc" <string-reader> 3 <limited-stream>
4 swap stream-read 4 swap stream-read
] unit-test ] unit-test
[ f ] [ f ]
[ [
"abc" <string-reader> 3 stream-eofs <limited-stream> "abc" <string-reader> 3 <limited-stream>
4 over stream-read drop 10 swap stream-read 4 over stream-read drop 10 swap stream-read
] unit-test ] unit-test
[ t ] [ t ]
[ [
"abc" <string-reader> 3 stream-eofs limit unlimited "abc" <string-reader> 3 limit-stream unlimit-stream
"abc" <string-reader> = "abc" <string-reader> =
] unit-test ] unit-test
[ t ] [ t ]
[ [
"abc" <string-reader> 3 stream-eofs limit unlimited "abc" <string-reader> 3 limit-stream unlimit-stream
"abc" <string-reader> = "abc" <string-reader> =
] unit-test ] unit-test
@ -73,145 +70,41 @@ IN: io.streams.limited.tests
[ [
[ [
"resource:license.txt" utf8 <file-reader> &dispose "resource:license.txt" utf8 <file-reader> &dispose
3 stream-eofs limit unlimited 3 limit-stream unlimit-stream
"resource:license.txt" utf8 <file-reader> &dispose "resource:license.txt" utf8 <file-reader> &dispose
[ decoder? ] both? [ decoder? ] both?
] with-destructors ] with-destructors
] unit-test ] unit-test
[ "HELL" ] [
"HELLO"
[ f stream-throws limit-input 4 read ]
with-string-reader
] unit-test
[ "asdf" ] [ [ "asdf" ] [
"asdf" <string-reader> 2 stream-eofs <limited-stream> [ "asdf" <string-reader> 2 <limited-stream> [
unlimited-input contents unlimited-input contents
] with-input-stream ] with-input-stream
] unit-test ] unit-test
[ 4 ] [ ! pipes are duplex and not seekable
"abcdefgh" <string-reader> 4 stream-throws <limited-stream> [
4 seek-relative seek-input tell-input
] with-input-stream
] unit-test
[
"abcdefgh" <string-reader> 4 stream-throws <limited-stream> [
4 seek-relative seek-input
4 read
] with-input-stream
] [
limit-exceeded?
] must-fail-with
[
"abcdefgh" <string-reader> 4 stream-throws <limited-stream> [
4 seek-relative seek-input
-2 seek-relative
2 read
] with-input-stream
] [
limit-exceeded?
] must-fail-with
[
"abcdefgh" <string-reader> [
4 seek-relative seek-input
2 stream-throws limit-input
-2 seek-relative seek-input
2 read
] with-input-stream
] [
limit-exceeded?
] must-fail-with
[ "ef" ] [
"abcdefgh" <string-reader> [
4 seek-relative seek-input
2 stream-throws limit-input
4 seek-absolute seek-input
2 read
] with-input-stream
] unit-test
[ "ef" ] [
"abcdefgh" <string-reader> [
4 seek-absolute seek-input
2 stream-throws limit-input
2 seek-absolute seek-input
4 seek-absolute seek-input
2 read
] with-input-stream
] unit-test
! stream-throws, pipes are duplex and not seekable
[ "as" ] [ [ "as" ] [
latin1 <pipe> [ 2 stream-throws <limited-stream> ] change-in latin1 <pipe> [ 2 <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush
2 swap stream-read
] unit-test
[
latin1 <pipe> [ 2 stream-throws <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush
3 swap stream-read
] [
limit-exceeded?
] must-fail-with
! stream-eofs, pipes are duplex and not seekable
[ "as" ] [
latin1 <pipe> [ 2 stream-eofs <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush "asdf" over stream-write dup stream-flush
2 swap stream-read 2 swap stream-read
] unit-test ] unit-test
[ "as" ] [ [ "as" ] [
latin1 <pipe> [ 2 stream-eofs <limited-stream> ] change-in latin1 <pipe> [ 2 <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush "asdf" over stream-write dup stream-flush
3 swap stream-read 3 swap stream-read
] unit-test ] unit-test
! test seeking on limited unseekable streams ! test seeking on limited unseekable streams
[ "as" ] [ [ "as" ] [
latin1 <pipe> [ 2 stream-eofs <limited-stream> ] change-in latin1 <pipe> [ 2 <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush "asdf" over stream-write dup stream-flush
2 swap stream-read 2 swap stream-read
] unit-test ] unit-test
[ "as" ] [ [ "as" ] [
latin1 <pipe> [ 2 stream-eofs <limited-stream> ] change-in latin1 <pipe> [ 2 <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush "asdf" over stream-write dup stream-flush
3 swap stream-read 3 swap stream-read
] unit-test ] unit-test
[
latin1 <pipe> [ 2 stream-throws <limited-stream> ] change-in
2 seek-absolute rot in>> stream-seek
] must-fail
[
"as"
] [
latin1 <pipe> [ 2 stream-throws <limited-stream> ] change-in
"asdf" over stream-write dup stream-flush
[ 2 seek-absolute rot in>> stream-seek ] [ drop ] recover
2 swap stream-read
] unit-test
[ 7 ] [
image binary stream-throws <limited-file-reader> [
7 read drop
tell-input
] with-input-stream
] unit-test
[ 70000 ] [
image binary stream-throws <limited-file-reader> [
70000 read drop
tell-input
] with-input-stream
] unit-test

View File

@ -6,87 +6,67 @@ io.encodings io.files io.files.info kernel locals math
namespaces sequences ; namespaces sequences ;
IN: io.streams.limited IN: io.streams.limited
TUPLE: limited-stream TUPLE: limited-stream stream count limit current start stop ;
stream mode
count limit
current start stop ;
SINGLETONS: stream-throws stream-eofs ; : <limited-stream> ( stream limit -- stream' )
: <limited-stream> ( stream limit mode -- stream' )
limited-stream new limited-stream new
swap >>mode
swap >>limit swap >>limit
swap >>stream swap >>stream
0 >>count ; 0 >>count ;
: <limited-file-reader> ( path encoding mode -- stream' ) : <limited-file-reader> ( path encoding -- stream' )
[ [ <file-reader> ]
[ <file-reader> ] [ drop file-info size>> ] 2bi
[ drop file-info size>> ] 2bi <limited-stream> ;
] dip <limited-stream> ;
GENERIC# limit 2 ( stream limit mode -- stream' ) GENERIC# limit-stream 1 ( stream limit -- stream' )
M: decoder limit ( stream limit mode -- stream' ) M: decoder limit-stream ( stream limit -- stream' )
[ clone ] 2dip '[ _ _ limit ] change-stream ; [ clone ] dip '[ _ limit-stream ] change-stream ;
M: object limit ( stream limit mode -- stream' ) M: object limit-stream ( stream limit -- stream' )
over [ <limited-stream> ] [ 2drop ] if ; <limited-stream> ;
GENERIC: unlimited ( stream -- stream' ) GENERIC: unlimit-stream ( stream -- stream' )
M: decoder unlimited ( stream -- stream' ) M: decoder unlimit-stream ( stream -- stream' )
[ stream>> ] change-stream ; [ stream>> ] change-stream ;
M: object unlimited ( stream -- stream' ) M: limited-stream unlimit-stream ( stream -- stream' ) stream>> ;
stream>> ;
: limit-input ( limit mode -- ) M: object unlimit-stream ( stream -- stream' ) ;
[ input-stream ] 2dip '[ _ _ limit ] change ;
: limited-input ( limit -- )
[ input-stream ] dip '[ _ limit-stream ] change ;
: unlimited-input ( -- ) : unlimited-input ( -- )
input-stream [ unlimited ] change ; input-stream [ unlimit-stream ] change ;
: with-unlimited-stream ( stream quot -- ) : with-unlimited-stream ( stream quot -- )
[ clone unlimited ] dip call ; inline [ clone unlimit-stream ] dip call ; inline
: with-limited-stream ( stream limit mode quot -- ) : with-limited-stream ( stream limit quot -- )
[ limit ] dip call ; inline [ limit-stream ] dip call ; inline
ERROR: limit-exceeded n stream ; ERROR: limit-exceeded n stream ;
ERROR: bad-stream-mode mode ;
<PRIVATE <PRIVATE
: adjust-current-limit ( n stream -- n' stream ) : adjust-current-limit ( n stream -- n' stream )
2dup [ + ] change-current 2dup [ + ] change-current
[ current>> ] [ stop>> ] bi > [ current>> ] [ stop>> ] bi >
[ [
dup mode>> { dup [ current>> ] [ stop>> ] bi -
{ stream-throws [ limit-exceeded ] } '[ _ - ] dip
{ stream-eofs [
dup [ current>> ] [ stop>> ] bi -
'[ _ - ] dip
] }
[ bad-stream-mode ]
} case
] when ; inline ] when ; inline
: adjust-count-limit ( n stream -- n' stream ) : adjust-count-limit ( n stream -- n' stream )
2dup [ + ] change-count 2dup [ + ] change-count
[ count>> ] [ limit>> ] bi > [ count>> ] [ limit>> ] bi >
[ [
dup mode>> { dup [ count>> ] [ limit>> ] bi -
{ stream-throws [ limit-exceeded ] } '[ _ - ] dip
{ stream-eofs [ dup limit>> >>count
dup [ count>> ] [ limit>> ] bi -
'[ _ - ] dip
dup limit>> >>count
] }
[ bad-stream-mode ]
} case
] when ; inline ] when ; inline
: check-count-bounds ( n stream -- n stream ) : check-count-bounds ( n stream -- n stream )
@ -124,7 +104,11 @@ M: limited-stream stream-read-partial
: (read-until) ( stream seps buf -- stream seps buf sep/f ) : (read-until) ( stream seps buf -- stream seps buf sep/f )
3dup [ [ stream-read1 dup ] dip member-eq? ] dip 3dup [ [ stream-read1 dup ] dip member-eq? ] dip
swap [ drop ] [ push (read-until) ] if ; swap [
drop
] [
over [ push (read-until) ] [ drop ] if
] if ;
:: limited-stream-seek ( n seek-type stream -- ) :: limited-stream-seek ( n seek-type stream -- )
seek-type { seek-type {

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1,36 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: io io.streams.limited io.streams.string
io.streams.throwing tools.test ;
IN: io.streams.throwing.tests
[ "as" ]
[
"asdf" <string-reader> 2 <limited-stream>
[ 6 read-partial ] throws-on-eof
] unit-test
[
"asdf" <string-reader> 2 <limited-stream>
[ contents ] throws-on-eof
] [ stream-exhausted? ] must-fail-with
[
"asdf" <string-reader> 2 <limited-stream>
[ 2 read read1 ] throws-on-eof
] [ stream-exhausted? ] must-fail-with
[
"asdf" <string-reader> 2 <limited-stream>
[ 3 read ] throws-on-eof
] [ stream-exhausted? ] must-fail-with
[
"asdf" <string-reader> 2 <limited-stream>
[ 2 read 2 read ] throws-on-eof
] [ stream-exhausted? ] must-fail-with
[
"asdf" <string-reader> 2 <limited-stream>
[ contents contents ] throws-on-eof
] [ stream-exhausted? ] must-fail-with

View File

@ -0,0 +1,37 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors destructors io kernel locals namespaces
sequences ;
IN: io.streams.throwing
ERROR: stream-exhausted n stream word ;
<PRIVATE
TUPLE: throws-on-eof stream ;
C: <throws-on-eof> throws-on-eof
M: throws-on-eof stream-element-type stream>> stream-element-type ;
M: throws-on-eof dispose stream>> dispose ;
M:: throws-on-eof stream-read1 ( stream -- obj )
stream stream>> stream-read1
[ 1 stream \ read1 stream-exhausted ] unless* ;
M:: throws-on-eof stream-read ( n stream -- seq )
n stream stream>> stream-read
dup length n = [ n stream \ read stream-exhausted ] unless ;
M:: throws-on-eof stream-read-partial ( n stream -- seq )
n stream stream>> stream-read-partial
[ n stream \ read-partial stream-exhausted ] unless* ;
PRIVATE>
: throws-on-eof ( stream quot -- )
[ <throws-on-eof> ] dip with-input-stream ; inline
: input-throws-on-eof ( quot -- )
[ input-stream get <throws-on-eof> ] dip with-input-stream ; inline

View File

@ -1,11 +1,9 @@
! Copyrigt (C) 2009 Doug Coleman, Keith Lazuka ! Copyrigt (C) 2009 Doug Coleman, Keith Lazuka
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs combinators compression.lzw USING: accessors arrays combinators compression.lzw
constructors destructors grouping images images.loader io constructors destructors grouping images images.loader io
io.binary io.buffers io.encodings.binary io.encodings.string io.binary io.buffers io.encodings.string io.encodings.utf8
io.encodings.utf8 io.files io.files.info io.ports io.ports kernel make math math.bitwise namespaces sequences ;
io.streams.limited kernel make math math.bitwise math.functions
multiline namespaces prettyprint sequences ;
IN: images.gif IN: images.gif
SINGLETON: gif-image SINGLETON: gif-image