Skip to content

Commit 3177fa3

Browse files
authored
Implement readavailable and bytesavailable (#53)
These are used notably by the fallback `write(::IO, ::IO)` implementation. Their absence makes `CSV.File(open(f, enc"..."))` fail with recent CSV.jl versions.
1 parent 2085821 commit 3177fa3

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

src/StringEncodings.jl

+15-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ using Libiconv_jll
66

77
using Base.Libc: errno, strerror, E2BIG, EINVAL, EILSEQ
88

9-
import Base: close, eachline, eof, flush, isreadable, iswritable,
10-
open, read, readbytes!, readline, readlines, readuntil, show, write
9+
import Base: bytesavailable, close, eachline, eof, flush, isreadable, iswritable,
10+
open, read, readavailable, readbytes!, readline, readlines,
11+
readuntil, show, write
1112

1213
export StringEncoder, StringDecoder, encode, decode, encodings
1314
export StringEncodingError, OutputBufferError, IConvError
@@ -339,6 +340,18 @@ function read(s::StringDecoder, ::Type{UInt8})
339340
eof(s) ? throw(EOFError()) : s.outbuf[s.skip+=1]
340341
end
341342

343+
bytesavailable(s::StringDecoder) =
344+
Int(BUFSIZE - s.outbytesleft[] - s.skip)
345+
346+
function readavailable(s::StringDecoder)
347+
s.cd == C_NULL && throw(ArgumentError("cannot read from closed StringDecoder"))
348+
eof(s) # Load more data into buffer if it is empty
349+
ob = s.outbytesleft[]
350+
res = s.outbuf[(s.skip+1):(BUFSIZE - ob)]
351+
s.skip = BUFSIZE - ob
352+
return res
353+
end
354+
342355
isreadable(s::StringDecoder) = s.cd != C_NULL && isreadable(s.stream)
343356
iswritable(s::StringDecoder) = false
344357

test/runtests.jl

+24
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,30 @@ end
246246
end
247247
end
248248

249+
@testset "readavailable and bytesavailable" begin
250+
s = "a string チャネルパートナーの選択"^10
251+
b = IOBuffer(encode(s, "UTF-16LE"))
252+
p = StringDecoder(b, "UTF-16LE")
253+
@test read(p, String) == s
254+
255+
b = IOBuffer(encode(s, "UTF-16LE"))
256+
p = StringDecoder(b, "UTF-16LE")
257+
@test bytesavailable(p) == 0
258+
@test read(p, UInt8) === 0x61
259+
@test bytesavailable(p) == 197
260+
@test String(readavailable(p)) == s[2:196]
261+
@test bytesavailable(p) == 0
262+
@test String(readavailable(p)) == s[199:394]
263+
@test bytesavailable(p) == 0
264+
@test String(readavailable(p)) == s[397:end]
265+
@test isempty(readavailable(p))
266+
@test bytesavailable(p) == 0
267+
@test eof(p)
268+
close(p)
269+
@test bytesavailable(p) == 0
270+
@test_throws ArgumentError readavailable(p)
271+
end
272+
249273

250274
## Test encodings support
251275
b = IOBuffer()

0 commit comments

Comments
 (0)