From 154bac77f093606c551a512fb7877c0243bee4a2 Mon Sep 17 00:00:00 2001 From: Sam O'Connor Date: Thu, 21 Jan 2016 21:51:18 +1100 Subject: [PATCH 1/3] rename: readbytes -> read, readall -> readstring --- README.md | 2 ++ src/Compat.jl | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/README.md b/README.md index 1f6572b7f..ce18dbc06 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,8 @@ Currently, the `@compat` macro supports the following syntaxes: * `super` is now `supertype` [#14338](https://github.com/JuliaLang/julia/pull/14338) +* `readall` and `readbytes` are now `readstring` and `read` [#14660](https://github.com/JuliaLang/julia/pull/14660) + ## New macros * `@inline` and `@noinline` have been added. On 0.3, these are "no-ops," meaning they don't actually do anything. diff --git a/src/Compat.jl b/src/Compat.jl index b9a8bbd77..2699cd97d 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -750,4 +750,26 @@ if VERSION < v"0.5.0-dev+1946" export supertype end + +if VERSION < v"0.5.0-dev+2228" + const readstring = readall + export readstring + + read(s::IO, nb::Integer=typemax(Int)) = readbytes(s, nb) + + write(filename::AbstractString, args...) = open(io->write(io, args...), filename, "w") + + read(filename::AbstractString, args...) = open(io->read(io, args...), filename) + read!(filename::AbstractString, a) = open(io->read!(io, a), filename) + readuntil(filename::AbstractString, args...) = open(io->readuntil(io, args...), filename) + readline(filename::AbstractString) = open(readline, filename) + readlines(filename::AbstractString) = open(readlines, filename) + + function write(to::IO, from::IO) + while !eof(from) + write(to, readavailable(from)) + end + end +end + end # module From 3407e5074dd5e7b409e177749ebc97c41e6e1e56 Mon Sep 17 00:00:00 2001 From: Sam O'Connor Date: Fri, 29 Jan 2016 10:11:06 +1100 Subject: [PATCH 2/3] tests for read --- src/Compat.jl | 25 ++++-- test/runtests.jl | 196 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 213 insertions(+), 8 deletions(-) diff --git a/src/Compat.jl b/src/Compat.jl index 2699cd97d..f66f24d01 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -755,21 +755,30 @@ if VERSION < v"0.5.0-dev+2228" const readstring = readall export readstring - read(s::IO, nb::Integer=typemax(Int)) = readbytes(s, nb) + Base.read(s::IO) = readbytes(s) + Base.read(s::IO, nb) = readbytes(s, nb) - write(filename::AbstractString, args...) = open(io->write(io, args...), filename, "w") + Base.write(filename::AbstractString, args...) = open(io->write(io, args...), filename, "w") - read(filename::AbstractString, args...) = open(io->read(io, args...), filename) - read!(filename::AbstractString, a) = open(io->read!(io, a), filename) - readuntil(filename::AbstractString, args...) = open(io->readuntil(io, args...), filename) - readline(filename::AbstractString) = open(readline, filename) - readlines(filename::AbstractString) = open(readlines, filename) + Base.read(filename::AbstractString, args...) = open(io->read(io, args...), filename) + Base.read!(filename::AbstractString, a) = open(io->read!(io, a), filename) + Base.readuntil(filename::AbstractString, args...) = open(io->readuntil(io, args...), filename) + Base.readline(filename::AbstractString) = open(readline, filename) + Base.readlines(filename::AbstractString) = open(readlines, filename) + Base.readavailable(s::IOStream) = read!(s, Vector{UInt8}(nb_available(s))) + Base.readavailable(s::IOBuffer) = read(s) - function write(to::IO, from::IO) + function Base.write(to::IO, from::IO) while !eof(from) write(to, readavailable(from)) end end + + function Base.eachline(filename::AbstractString) + s = open(filename) + EachLine(s, ()->close(s)) + end + end end # module diff --git a/test/runtests.jl b/test/runtests.jl index 37e536a0d..e7eedd5a1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -560,3 +560,199 @@ Base.remote_do(() -> true, 1) # Doesn't return anything so cannot be `@test`ed b @test "1234" == @compat withenv("_TESTVAR" => 1234) do return ENV["_TESTVAR"] end + +# https://github.com/JuliaLang/julia/pull/14660 +mktempdir() do dir + + verbose = false + + # Create test file... + filename = joinpath(dir, "file.txt") + text = "C1,C2\n1,2\na,b\n" + + # List of IO producers... + l = [ + ("IOStream", (text) -> begin + write(filename, text) + open(filename) + end), + ("IOBuffer", (text)->IOBuffer(text)) + ] + + open_streams = [] + function cleanup() + for s in open_streams + try close(s) end + end + end + + for (name, f) in l + + io = ()->(s=f(text); push!(open_streams, s); s) + + write(filename, text) + + verbose && println("$name read...") + @test read(io(), UInt8) == read(IOBuffer(text), UInt8) + @test read(io(), UInt8) == read(filename, UInt8) + @test read(io(), Int) == read(IOBuffer(text), Int) + @test read(io(), Int) == read(filename,Int) + s1 = io() + s2 = IOBuffer(text) + @test read(s1, UInt32, 2) == read(s2, UInt32, 2) + @test !eof(s1) + @test read(s1, UInt8, 5) == read(s2, UInt8, 5) + @test !eof(s1) + @test read(s1, UInt8, 1) == read(s2, UInt8, 1) + @test eof(s1) + @test_throws EOFError read(s1, UInt8) + @test eof(s1) + close(s1) + close(s2) + + verbose && println("$name eof...") + n = length(text) - 1 + @test read!(io(), Vector{UInt8}(n)) == + read!(IOBuffer(text), Vector{UInt8}(n)) + @test (s = io(); read!(s, Vector{UInt8}(n)); !eof(s)) + n = length(text) + @test read!(io(), Vector{UInt8}(n)) == + read!(IOBuffer(text), Vector{UInt8}(n)) + @test (s = io(); read!(s, Vector{UInt8}(n)); eof(s)) + n = length(text) + 1 + @test_throws EOFError read!(io(), Vector{UInt8}(n)) + @test_throws EOFError read!(io(), Vector{UInt8}(n)) + + old_text = text + cleanup() + + for text in [ + old_text, + UTF8String(['A' + i % 52 for i in 1:(div(Base.SZ_UNBUFFERED_IO,2))]), + UTF8String(['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO -1)]), + UTF8String(['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO )]), + UTF8String(['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO +1)]) + ] + + write(filename, text) + + verbose && println("$name readstring...") + @test readstring(io()) == text + + @test readstring(io()) == readstring(filename) + + + verbose && println("$name read...") + @test read(io()) == Vector{UInt8}(text) + + @test read(io()) == read(filename) + + cleanup() + + + verbose && println("$name readbytes!...") + l = length(text) + for n = [1, 2, l-2, l-1, l, l+1, l+2] + a1 = Vector{UInt8}(n); + a2 = Vector{UInt8}(n) + s1 = io() + s2 = IOBuffer(text) + n1 = readbytes!(s1, a1) + n2 = readbytes!(s2, a2) + @test n1 == n2 + @test length(a1) == length(a2) + @test a1[1:n1] == a2[1:n2] + @test n <= length(text) || eof(s1) + @test n <= length(text) || eof(s2) + + cleanup() + end + + verbose && println("$name read!...") + l = length(text) + for n = [1, 2, l-2, l-1, l] + @test read!(io(), Vector{UInt8}(n)) == + read!(IOBuffer(text), Vector{UInt8}(n)) + @test read!(io(), Vector{UInt8}(n)) == + read!(filename, Vector{UInt8}(n)) + + cleanup() + end + @test_throws EOFError read!(io(), Vector{UInt8}(length(text)+1)) + + + verbose && println("$name readuntil...") + @test readuntil(io(), '\n') == readuntil(IOBuffer(text),'\n') + @test readuntil(io(), '\n') == readuntil(filename,'\n') + @test readuntil(io(), "\n") == readuntil(IOBuffer(text),"\n") + @test readuntil(io(), "\n") == readuntil(filename,"\n") + @test readuntil(io(), ',') == readuntil(IOBuffer(text),',') + @test readuntil(io(), ',') == readuntil(filename,',') + + cleanup() + + verbose && println("$name readline...") + @test readline(io()) == readline(IOBuffer(text)) + @test readline(io()) == readline(filename) + + verbose && println("$name readlines...") + @test readlines(io()) == readlines(IOBuffer(text)) + @test readlines(io()) == readlines(filename) + @test collect(eachline(io())) == collect(eachline(IOBuffer(text))) + @test collect(eachline(io())) == collect(eachline(filename)) + + cleanup() + + verbose && println("$name countlines...") + @test countlines(io()) == countlines(IOBuffer(text)) + + verbose && println("$name readcsv...") + @test readcsv(io()) == readcsv(IOBuffer(text)) + @test readcsv(io()) == readcsv(filename) + + cleanup() + end + + text = old_text + write(filename, text) + + if !(typeof(io()) in [Base.PipeEndpoint, Pipe, TCPSocket]) + + verbose && println("$name position...") + @test (s = io(); read!(s, Vector{UInt8}(4)); position(s)) == 4 + + verbose && println("$name seek...") + for n = 0:length(text)-1 + @test readlines(seek(io(), n)) == readlines(seek(IOBuffer(text), n)) + cleanup() + end + verbose && println("$name skip...") + for n = 0:length(text)-1 + @test readlines(seek(io(), n)) == readlines(seek(IOBuffer(text), n)) + @test readlines(skip(io(), n)) == readlines(skip(IOBuffer(text), n)) + cleanup() + end + verbose && println("$name seekend...") + @test readstring(seekend(io())) == "" + end + + + verbose && println("$name write(::IOStream, ...)") + to = open("$filename.to", "w") + write(to, io()) + close(to) + @test readstring("$filename.to") == text + + verbose && println("$name write(filename, ...)") + write("$filename.to", io()) + @test readstring("$filename.to") == text + + verbose && println("$name write(::IOBuffer, ...)") + to = IOBuffer(Vector{UInt8}(copy(text)), false, true) + write(to, io()) + @test takebuf_string(to) == text + + cleanup() + end + +end From 3504a9fbf709085881dbddd7b941e595416afde4 Mon Sep 17 00:00:00 2001 From: Sam O'Connor Date: Tue, 2 Feb 2016 09:28:20 +1100 Subject: [PATCH 3/3] Type inference work around per https://github.com/JuliaLang/julia/commit/639621859863609c5f3abbc2ed75c675695b3693#commitcomment-15805537 --- test/runtests.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index e7eedd5a1..a2e69f1e6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -162,7 +162,7 @@ end extrapath = @windows? joinpath(JULIA_HOME,"..","Git","usr","bin")*";" : "" @compat withenv("PATH" => extrapath * ENV["PATH"]) do - @test readall(pipeline(`echo hello`, `sort`)) == "hello\n" + @test readstring(pipeline(`echo hello`, `sort`)) == "hello\n" @test success(pipeline(`true`, `true`)) end @@ -628,10 +628,10 @@ mktempdir() do dir for text in [ old_text, - UTF8String(['A' + i % 52 for i in 1:(div(Base.SZ_UNBUFFERED_IO,2))]), - UTF8String(['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO -1)]), - UTF8String(['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO )]), - UTF8String(['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO +1)]) + UTF8String(Char['A' + i % 52 for i in 1:(div(Base.SZ_UNBUFFERED_IO,2))]), + UTF8String(Char['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO -1)]), + UTF8String(Char['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO )]), + UTF8String(Char['A' + i % 52 for i in 1:( Base.SZ_UNBUFFERED_IO +1)]) ] write(filename, text)