From 3906356d7d591237b2a4490fc2d2cf8469b4271a Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Sun, 4 Feb 2018 09:11:14 +0900 Subject: [PATCH 1/5] add keyword arguments to IOBuffer's constructors --- base/iobuffer.jl | 90 +++++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index a41bb4fe74590..526c060594f2b 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -32,15 +32,27 @@ StringVector(n::Integer) = unsafe_wrap(Vector{UInt8}, _string_n(n)) # IOBuffers behave like Files. They are typically readable and writable. They are seekable. (They can be appendable). """ - IOBuffer([data, ][readable::Bool=true, writable::Bool=false[, maxsize::Int=typemax(Int)]]) + IOBuffer([data::AbstractVector{UInt8}]; keywords...) -> IOBuffer -Create an `IOBuffer`, which may optionally operate on a pre-existing array. If the -readable/writable arguments are given, they restrict whether or not the buffer may be read -from or written to respectively. The last argument optionally specifies a size beyond which -the buffer may not be grown. +Create an in-memory I/O stream, which may optionally operate on a pre-existing array. + +It may take optional keyword arguments: +- `read`, `write`, `append`: restricts operations to the buffer; see `open` for details. +- `truncate`: truncates the buffer size to zero length. +- `maxsize`: specifies a size beyond which the buffer may not be grown. + +When `data` is given, the buffer will be both readable and writable by default. # Examples ```jldoctest +julia> io = IOBuffer(); + +julia> write(io, "JuliaLang is a GitHub organization.", " It has many members.") +56 + +julia> String(take!(io)) +"JuliaLang is a GitHub organization. It has many members." + julia> io = IOBuffer("JuliaLang is a GitHub organization.") IOBuffer(data=UInt8[...], readable=true, writable=false, seekable=true, append=false, size=35, maxsize=Inf, ptr=1, mark=-1) @@ -50,7 +62,7 @@ julia> read(io, String) julia> write(io, "This isn't writable.") ERROR: ArgumentError: ensureroom failed, IOBuffer is not writeable -julia> io = IOBuffer(UInt8[], true, true, 34) +julia> io = IOBuffer(UInt8[], read=true, write=true, maxsize=34) IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=34, ptr=1, mark=-1) julia> write(io, "JuliaLang is a GitHub organization.") @@ -60,33 +72,49 @@ julia> String(take!(io)) "JuliaLang is a GitHub organization" ``` """ -IOBuffer(data::AbstractVector{UInt8}, readable::Bool=true, writable::Bool=false, maxsize::Integer=typemax(Int)) = - GenericIOBuffer(data, readable, writable, true, false, maxsize) -function IOBuffer(readable::Bool, writable::Bool) - b = IOBuffer(StringVector(32), readable, writable) - b.data[:] = 0 - b.size = 0 - return b +function IOBuffer( + data::AbstractVector{UInt8}; + read::Union{Bool,Nothing}=nothing, + write::Union{Bool,Nothing}=nothing, + append::Union{Bool,Nothing}=nothing, + truncate::Union{Bool,Nothing}=nothing, + maxsize::Integer=typemax(Int)) + if maxsize < 0 + throw(ArgumentError("negative maxsize: $(maxsize)")) + end + flags = open_flags(read=read, write=write, append=append, truncate=truncate) + buf = GenericIOBuffer(data, flags.read, flags.write, true, flags.append, Int(maxsize)) + if flags.truncate + buf.size = 0 + end + return buf end -""" - IOBuffer() -> IOBuffer - -Create an in-memory I/O stream, which is both readable and writable. - -# Examples -```jldoctest -julia> io = IOBuffer(); - -julia> write(io, "JuliaLang is a GitHub organization.", " It has many members.") -56 - -julia> String(take!(io)) -"JuliaLang is a GitHub organization. It has many members." -``` -""" -IOBuffer() = IOBuffer(true, true) +function IOBuffer(; + read::Union{Bool,Nothing}=true, + write::Union{Bool,Nothing}=true, + append::Union{Bool,Nothing}=nothing, + truncate::Union{Bool,Nothing}=true, + maxsize::Integer=typemax(Int)) + size = maxsize == typemax(Int) ? 32 : Int(maxsize) + flags = open_flags(read=read, write=write, append=append, truncate=truncate) + buf = IOBuffer( + StringVector(size), + read=flags.read, + write=flags.write, + append=flags.append, + truncate=flags.truncate, + maxsize=maxsize) + buf.data[:] = 0 # TODO: Is this really needed? + if flags.truncate + buf.size = 0 + end + return buf +end +# TODO: deprecate these methods? +IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer=typemax(Int)) = IOBuffer(data, read=read, write=write, maxsize=maxsize) +IOBuffer(read::Bool, write::Bool) = IOBuffer(read=read, write=write) """ IOBuffer(size::Integer) @@ -110,7 +138,7 @@ julia> String(take!(io)) "Hello world " ``` """ -IOBuffer(maxsize::Integer) = (x=IOBuffer(StringVector(maxsize), true, true, maxsize); x.size=0; x) +IOBuffer(maxsize::Integer) = IOBuffer(maxsize=maxsize) # PipeBuffers behave like Unix Pipes. They are typically readable and writable, they act appendable, and are not seekable. From 1499957a5f3d428c3e9f9ad94821375e8e8c8b36 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Sun, 4 Feb 2018 23:26:33 +0900 Subject: [PATCH 2/5] deprecate --- base/deprecated.jl | 5 +++++ base/function | 0 base/int.jl | 2 +- base/iobuffer.jl | 28 ---------------------------- base/printf.jl | 2 +- base/strings/basic.jl | 4 ++-- base/strings/io.jl | 6 +++--- base/strings/util.jl | 2 +- 8 files changed, 13 insertions(+), 36 deletions(-) create mode 100644 base/function diff --git a/base/deprecated.jl b/base/deprecated.jl index 8b584d8507abf..2137d46e62558 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1415,6 +1415,11 @@ end @deprecate which(s::Symbol) which(Main, s) +@deprecate IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer=typemax(Int)) IOBuffer(data, read=read, write=write, maxsize=maxsize) +@deprecate IOBuffer(read::Bool, write::Bool) IOBuffer(read=read, write=write) +@deprecate IOBuffer(maxsize::Integer) IOBuffer(maxsize=maxsize) + + # END 0.7 deprecations # BEGIN 1.0 deprecations diff --git a/base/function b/base/function new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/base/int.jl b/base/int.jl index 6e655b06ac929..d5556bf048379 100644 --- a/base/int.jl +++ b/base/int.jl @@ -539,7 +539,7 @@ end macro big_str(s) if '_' in s # remove _ in s[2:end-1] - bf = IOBuffer(lastindex(s)) + bf = IOBuffer(maxsize=lastindex(s)) print(bf, s[1]) for c in SubString(s, 2, lastindex(s)-1) c != '_' && print(bf, c) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index 526c060594f2b..141f586d3c8a9 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -112,34 +112,6 @@ function IOBuffer(; return buf end -# TODO: deprecate these methods? -IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer=typemax(Int)) = IOBuffer(data, read=read, write=write, maxsize=maxsize) -IOBuffer(read::Bool, write::Bool) = IOBuffer(read=read, write=write) -""" - IOBuffer(size::Integer) - -Create a fixed size IOBuffer. The buffer will not grow dynamically. - -# Examples -```jldoctest -julia> io = IOBuffer(12) -IOBuffer(data=UInt8[...], readable=true, writable=true, seekable=true, append=false, size=0, maxsize=12, ptr=1, mark=-1) - -julia> write(io, "Hello world.") -12 - -julia> String(take!(io)) -"Hello world." - -julia> write(io, "Hello world again.") -12 - -julia> String(take!(io)) -"Hello world " -``` -""" -IOBuffer(maxsize::Integer) = IOBuffer(maxsize=maxsize) - # PipeBuffers behave like Unix Pipes. They are typically readable and writable, they act appendable, and are not seekable. """ diff --git a/base/printf.jl b/base/printf.jl index 5816d7b8ba560..8bfefc8e77c11 100644 --- a/base/printf.jl +++ b/base/printf.jl @@ -1114,7 +1114,7 @@ function bigfloat_printf(out, d::BigFloat, flags::String, width::Int, precision: if precision >= 0 fmt_len += ndigits(precision)+1 end - fmt = IOBuffer(fmt_len) + fmt = IOBuffer(maxsize=fmt_len) write(fmt, '%') write(fmt, flags) if width > 0 diff --git a/base/strings/basic.jl b/base/strings/basic.jl index 6889c744be068..a747ac39e5b8e 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -512,7 +512,7 @@ isascii(s::AbstractString) = all(isascii, s) ## string map, filter, has ## function map(f, s::AbstractString) - out = IOBuffer(StringVector(sizeof(s)), true, true) + out = IOBuffer(StringVector(sizeof(s)), read=true, write=true) truncate(out, 0) for c in s c′ = f(c) @@ -525,7 +525,7 @@ function map(f, s::AbstractString) end function filter(f, s::AbstractString) - out = IOBuffer(StringVector(sizeof(s)), true, true) + out = IOBuffer(StringVector(sizeof(s)), read=true, write=true) truncate(out, 0) for c in s f(c) && write(out, c) diff --git a/base/strings/io.jl b/base/strings/io.jl index e2944ed953b4d..97dbf4eed89e6 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -81,7 +81,7 @@ julia> sprint(showcompact, 66.66666) ``` """ function sprint(f::Function, args...; context=nothing, sizehint::Integer=0) - s = IOBuffer(StringVector(sizehint), true, true) + s = IOBuffer(StringVector(sizehint), read=true, write=true) # specialized version of truncate(s,0) s.size = 0 s.ptr = 1 @@ -100,7 +100,7 @@ tostr_sizehint(x::Float32) = 12 function print_to_string(xs...; env=nothing) # specialized for performance reasons - s = IOBuffer(StringVector(tostr_sizehint(xs[1])), true, true) + s = IOBuffer(StringVector(tostr_sizehint(xs[1])), read=true, write=true) # specialized version of truncate(s,0) s.size = 0 s.ptr = 1 @@ -436,7 +436,7 @@ Returns: function unindent(str::AbstractString, indent::Int; tabwidth=8) indent == 0 && return str # Note: this loses the type of the original string - buf = IOBuffer(StringVector(sizeof(str)), true, true) + buf = IOBuffer(StringVector(sizeof(str)), read=true, write=true) truncate(buf,0) cutting = true col = 0 # current column (0 based) diff --git a/base/strings/util.jl b/base/strings/util.jl index c90d6302d86ad..9fe05fe6edcf5 100644 --- a/base/strings/util.jl +++ b/base/strings/util.jl @@ -383,7 +383,7 @@ function replace(str::String, pat_repl::Pair; count::Integer=typemax(Int)) i = a = firstindex(str) r = coalesce(findnext(pattern,str,i), 0) j, k = first(r), last(r) - out = IOBuffer(StringVector(floor(Int, 1.2sizeof(str))), true, true) + out = IOBuffer(StringVector(floor(Int, 1.2sizeof(str))), read=true, write=true) out.size = 0 out.ptr = 1 while j != 0 From a55638696810ee0b1166a61e574334b726c9d2a5 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Mon, 5 Feb 2018 00:09:01 +0900 Subject: [PATCH 3/5] fix tests --- base/deprecated.jl | 4 ++-- base/iobuffer.jl | 2 +- stdlib/Dates/src/io.jl | 2 +- test/functional.jl | 4 ++-- test/iobuffer.jl | 10 +++++----- test/read.jl | 2 +- test/show.jl | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/base/deprecated.jl b/base/deprecated.jl index 2137d46e62558..bb08a70bbcb78 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1415,9 +1415,9 @@ end @deprecate which(s::Symbol) which(Main, s) -@deprecate IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool, maxsize::Integer=typemax(Int)) IOBuffer(data, read=read, write=write, maxsize=maxsize) +@deprecate IOBuffer(data::AbstractVector{UInt8}, read::Bool, write::Bool=false, maxsize::Integer=typemax(Int)) IOBuffer(data, read=read, write=write, maxsize=maxsize) @deprecate IOBuffer(read::Bool, write::Bool) IOBuffer(read=read, write=write) -@deprecate IOBuffer(maxsize::Integer) IOBuffer(maxsize=maxsize) +@deprecate IOBuffer(maxsize::Integer) IOBuffer(read=true, write=true, maxsize=maxsize) # END 0.7 deprecations diff --git a/base/iobuffer.jl b/base/iobuffer.jl index 141f586d3c8a9..804fe26530334 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -105,7 +105,7 @@ function IOBuffer(; append=flags.append, truncate=flags.truncate, maxsize=maxsize) - buf.data[:] = 0 # TODO: Is this really needed? + buf.data[:] = 0 if flags.truncate buf.size = 0 end diff --git a/stdlib/Dates/src/io.jl b/stdlib/Dates/src/io.jl index e3657d3e45665..538ffdcff2909 100644 --- a/stdlib/Dates/src/io.jl +++ b/stdlib/Dates/src/io.jl @@ -481,7 +481,7 @@ end function format(dt::TimeType, fmt::DateFormat, bufsize=12) # preallocate to reduce resizing - io = IOBuffer(Vector{UInt8}(uninitialized, bufsize), true, true) + io = IOBuffer(Vector{UInt8}(uninitialized, bufsize), read=true, write=true) format(io, dt, fmt) String(io.data[1:io.ptr - 1]) end diff --git a/test/functional.jl b/test/functional.jl index a42d001f72e6f..0b40087416e45 100644 --- a/test/functional.jl +++ b/test/functional.jl @@ -14,7 +14,7 @@ end @test isequal(map(sqrt, 2:6), [sqrt(i) for i in 2:6]) # map on ranges should evaluate first value only once (#4453) -let io=IOBuffer(3) +let io=IOBuffer(maxsize=3) map(x->print(io,x), 1:2) @test String(take!(io))=="12" end @@ -176,4 +176,4 @@ end @test res isa Vector{Union{Bool, T}} res = map(f, y) @test res isa Vector{Union{Bool, T}} -end \ No newline at end of file +end diff --git a/test/iobuffer.jl b/test/iobuffer.jl index 39d11a8b36bde..fa8284f4e593e 100644 --- a/test/iobuffer.jl +++ b/test/iobuffer.jl @@ -195,7 +195,7 @@ end @testset "pr #11554" begin io = IOBuffer(SubString("***αhelloworldω***", 4, 16)) - io2 = IOBuffer(Vector{UInt8}(b"goodnightmoon"), true, true) + io2 = IOBuffer(Vector{UInt8}(b"goodnightmoon"), read=true, write=true) @test read(io, Char) == 'α' @test_throws ArgumentError write(io,"!") @@ -227,7 +227,7 @@ end # issue #11917 # (previous tests triggered this sometimes, but this should trigger nearly all the time) -let io = IOBuffer(0) +let io = IOBuffer(maxsize=0) write(io, fill(0x01, 1048577)) end @@ -289,11 +289,11 @@ end end @testset "Test constructor with a generic type argument." begin - io = IOBuffer(Int16(10)) + io = IOBuffer(maxsize=Int16(10)) @test io isa IOBuffer - io = IOBuffer(Int32(10)) + io = IOBuffer(maxsize=Int32(10)) @test io isa IOBuffer - io = IOBuffer(Int64(10)) + io = IOBuffer(maxsize=Int64(10)) @test io isa IOBuffer end diff --git a/test/read.jl b/test/read.jl index 632af6e0e683f..07bad4f50607b 100644 --- a/test/read.jl +++ b/test/read.jl @@ -343,7 +343,7 @@ for (name, f) in l @test read("$filename.to", String) == text verbose && println("$name write(::IOBuffer, ...)") - to = IOBuffer(Vector{UInt8}(codeunits(text)), false, true) + to = IOBuffer(Vector{UInt8}(codeunits(text)), read=false, write=true) write(to, io()) @test String(take!(to)) == text diff --git a/test/show.jl b/test/show.jl index 1759c3ce5b1c1..0614388310e2d 100644 --- a/test/show.jl +++ b/test/show.jl @@ -755,7 +755,7 @@ end # PR 17117 # test print_array -let s = IOBuffer(Vector{UInt8}(), true, true) +let s = IOBuffer(Vector{UInt8}(), read=true, write=true) Base.print_array(s, [1, 2, 3]) @test String(resize!(s.data, s.size)) == " 1\n 2\n 3" end From cbf3f71aae07e5b6eeb4846a9587fe9738a443f7 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Mon, 5 Feb 2018 09:17:00 +0900 Subject: [PATCH 4/5] remove a junk file [ci skip] --- base/function | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 base/function diff --git a/base/function b/base/function deleted file mode 100644 index e69de29bb2d1d..0000000000000 From 9341456efa88803847058beb571cf9255013e9c6 Mon Sep 17 00:00:00 2001 From: Kenta Sato Date: Tue, 6 Feb 2018 13:37:30 +0900 Subject: [PATCH 5/5] fix docs [ci skip] --- base/iobuffer.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index 804fe26530334..30a54d595b703 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -41,7 +41,7 @@ It may take optional keyword arguments: - `truncate`: truncates the buffer size to zero length. - `maxsize`: specifies a size beyond which the buffer may not be grown. -When `data` is given, the buffer will be both readable and writable by default. +When `data` is not given, the buffer will be both readable and writable by default. # Examples ```jldoctest