Skip to content

Commit 670ebca

Browse files
nhz2mkitti
andauthored
BREAKING: eof errors if stream isn't readable (#230)
Co-authored-by: Mark Kittisopikul <[email protected]>
1 parent f62b761 commit 670ebca

File tree

5 files changed

+51
-37
lines changed

5 files changed

+51
-37
lines changed

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using TranscodingStreams
44
makedocs(
55
sitename="TranscodingStreams.jl",
66
modules=[TranscodingStreams],
7-
pages=["index.md", "examples.md", "reference.md", "devnotes.md"],
7+
pages=["index.md", "examples.md", "reference.md", "migrating.md", "devnotes.md"],
88
format=Documenter.HTML(; assets=["assets/custom.css"]),
99
)
1010

docs/src/migrating.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Migration
2+
=========
3+
4+
How to migrate from v0.10 to v0.11
5+
----------------------------------
6+
7+
v0.11 has a few subtle breaking changes to `eof` and `seekend`.
8+
9+
### `Memory(data::ByteData)`
10+
11+
The `Memory(data::ByteData)` constructor was removed.
12+
Use `Memory(pointer(data), sizeof(data))` instead.
13+
14+
### `seekend(stream::TranscodingStream)`
15+
16+
Generic `seekend` for `TranscodingStream` was removed.
17+
If the objective is to discard all remaining data in the stream, use `skip(stream, typemax(Int64))` instead where `typemax(Int64)` is meant to be a large number to exhaust the stream.
18+
Ideally, specific implementations of `TranscodingStream` will implement `seekend` only if efficient means exist to avoid fully processing the stream.
19+
`NoopStream` still supports `seekend`.
20+
21+
The previous behavior of the generic `seekend` was something like
22+
`(seekstart(stream); seekend(stream.stream); stream)` but this led to
23+
inconsistencies with the position of the stream.
24+
25+
### `eof(stream::TranscodingStream)`
26+
27+
`eof` now throws an error if called on a stream that is closed or in writing mode.
28+
Use `!isreadable(stream) || eof(stream)` if you need to more closely match previous behavior.

src/stream.jl

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -206,31 +206,24 @@ function Base.eof(stream::TranscodingStream)
206206
eof = buffersize(stream.buffer1) == 0
207207
state = stream.state
208208
mode = state.mode
209-
if !(mode == :read || mode == :stop) || eof
209+
if !(mode === :read || mode === :stop)
210+
changemode!(stream, :read)
211+
end
212+
if eof
210213
eof = sloweof(stream)
211214
end
212215
return eof
213216
end
214217
@noinline function sloweof(stream::TranscodingStream)
215-
while true
216-
state = stream.state
217-
mode = state.mode
218-
if mode == :read
219-
return (buffersize(stream.buffer1) == 0 && fillbuffer(stream) == 0)
220-
elseif mode == :idle
221-
changemode!(stream, :read)
222-
continue
223-
elseif mode == :write
224-
return eof(stream.stream)
225-
elseif mode == :close
226-
return true
227-
elseif mode == :stop
228-
return buffersize(stream.buffer1) == 0
229-
elseif mode == :panic
230-
throw_panic_error()
231-
end
232-
@assert false
218+
state = stream.state
219+
mode = state.mode
220+
@assert mode == :read || mode == :stop
221+
if mode == :read
222+
return (buffersize(stream.buffer1) == 0 && fillbuffer(stream) == 0)
223+
elseif mode == :stop
224+
return buffersize(stream.buffer1) == 0
233225
end
226+
@assert false
234227
end
235228

236229
function Base.ismarked(stream::TranscodingStream)::Bool
@@ -316,14 +309,7 @@ end
316309

317310
# needed for `peek(stream, Char)` to work
318311
function Base.peek(stream::TranscodingStream, ::Type{UInt8})::UInt8
319-
# eof and ready_to_read! are inlined here because ready_to_read! is very slow and eof is broken
320-
eof = buffersize(stream.buffer1) == 0
321-
state = stream.state
322-
mode = state.mode
323-
if !(mode == :read || mode == :stop)
324-
changemode!(stream, :read)
325-
end
326-
if eof && sloweof(stream)
312+
if eof(stream)
327313
throw(EOFError())
328314
end
329315
buf = stream.buffer1

test/codecnoop.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,9 @@ using FillArrays: Zeros
442442

443443
stream = NoopStream(IOBuffer(""))
444444
unsafe_write(stream, C_NULL, 0)
445-
@test eof(stream) # write
445+
@test_throws ArgumentError eof(stream) # write
446446
close(stream)
447-
@test eof(stream) # close
447+
@test_throws ArgumentError eof(stream) # close
448448

449449
@testset "readuntil" begin
450450
stream = NoopStream(IOBuffer(""))

test/codecquadruple.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,21 +205,21 @@ end
205205
end
206206
end
207207

208-
@testset "eof is true after write" begin
208+
@testset "eof throws ArgumentError after write" begin
209209
sink = IOBuffer()
210210
stream = TranscodingStream(QuadrupleCodec(), sink, bufsize=16)
211211
write(stream, "x")
212-
@test eof(stream)
212+
@test_throws ArgumentError eof(stream)
213213
@test_throws ArgumentError read(stream, UInt8)
214-
@test eof(stream)
214+
@test_throws ArgumentError eof(stream)
215215
write(stream, "y")
216-
@test eof(stream)
216+
@test_throws ArgumentError eof(stream)
217217
write(stream, TranscodingStreams.TOKEN_END)
218-
@test eof(stream)
218+
@test_throws ArgumentError eof(stream)
219219
flush(stream)
220-
@test eof(stream)
220+
@test_throws ArgumentError eof(stream)
221221
@test take!(sink) == b"xxxxyyyy"
222222
close(stream)
223-
@test eof(stream)
223+
@test_throws ArgumentError eof(stream)
224224
end
225225
end

0 commit comments

Comments
 (0)