Skip to content

Commit

Permalink
handle and test incomplete char at eof stream
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKarpinski committed Nov 3, 2017
1 parent d7bb372 commit 15d5497
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 14 deletions.
2 changes: 1 addition & 1 deletion base/filesystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ function read(f::File, ::Type{Char})
n = leading_ones(b0)
c = UInt32(b0)
if n <= 4
while 1 < n
while 1 < n && !eof(f)
p = position(f)
b = read(f, UInt8)
if b & 0xc0 != 0x80
Expand Down
2 changes: 1 addition & 1 deletion base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ function read(s::IO, ::Type{Char})
n = leading_ones(b0)
c = UInt32(b0)
if n <= 4
while 1 < n
while 1 < n && !eof(s)
peek(s) & 0xc0 == 0x80 || break
b = read(s, UInt8)
c <<= 8
Expand Down
17 changes: 5 additions & 12 deletions base/iostream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,13 @@ end

## low-level calls ##

write(s::IOStream, b::UInt8) = Int(ccall(:ios_putc, Cint, (Cint, Ptr{Void}), b, s.ios))
function write(s::IOStream, b::UInt8)
iswritable(s) || throw(ArgumentError("write failed, IOStream is not writeable"))
Int(ccall(:ios_putc, Cint, (Cint, Ptr{Void}), b, s.ios))
end

function unsafe_write(s::IOStream, p::Ptr{UInt8}, nb::UInt)
if !iswritable(s)
throw(ArgumentError("write failed, IOStream is not writeable"))
end
iswritable(s) || throw(ArgumentError("write failed, IOStream is not writeable"))
return Int(ccall(:ios_write, Csize_t, (Ptr{Void}, Ptr{Void}, Csize_t), s.ios, p, nb))
end

Expand Down Expand Up @@ -237,14 +238,6 @@ end

## text I/O ##

function write(s::IOStream, c::Char)
if !iswritable(s)
throw(ArgumentError("write failed, IOStream is not writeable"))
end
Int(ccall(:ios_pututf8, Cint, (Ptr{Void}, UInt32), s.ios, c))
end
read(s::IOStream, ::Type{Char}) = Char(ccall(:jl_getutf8, UInt32, (Ptr{Void},), s.ios))

take!(s::IOStream) =
ccall(:jl_take_buffer, Vector{UInt8}, (Ptr{Void},), s.ios)

Expand Down
21 changes: 21 additions & 0 deletions test/char.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,24 @@ end

@test sprint(show, "text/plain", '$') == "'\$': ASCII/Unicode U+0024 (category Sc: Symbol, currency)"
@test repr('$') == "'\$'"

@testset "read incomplete character at end of stream / file" begin
local file = tempname()
local iob = IOBuffer([0xf0])
@test reinterpret(UInt32, read(iob, Char)) == 0xf0
@test eof(iob)
try
write(file, 0xf0)
open(file) do io
@test reinterpret(UInt32, read(io, Char)) == 0xf0
@test eof(io)
end
let io = Base.Filesystem.open(file, Base.Filesystem.JL_O_RDONLY)
@test reinterpret(UInt32, read(io, Char)) == 0xf0
@test eof(io)
close(io)
end
finally
rm(file, force=true)
end
end

0 comments on commit 15d5497

Please sign in to comment.