diff --git a/src/DataStrings.jl b/src/DataStrings.jl index dc1360c..ac0bf64 100644 --- a/src/DataStrings.jl +++ b/src/DataStrings.jl @@ -522,11 +522,14 @@ Base.Symbol(s::DataString) = Symbol(String(s)) Base.promote_rule(::Type{DataString}, ::Type{String}) = String function Base.write(io::IO, s::DataString) - n = 0 - @inbounds for i = 1:ncodeunits(s) - n += write(io, codeunit(s, i)) + n = ncodeunits(s) + # a view's content is one contiguous run of its retained buffer + n > INLINE_MAX && return GC.@preserve s unsafe_write(io, pointer(s.data, payloadpos(s.p)), n) + m = 0 + @inbounds for i = 1:n + m += write(io, codeunit(s, i)) end - return n + return m end Base.print(io::IO, s::DataString) = (write(io, s); nothing) diff --git a/test/construct.jl b/test/construct.jl index c8d4ab1..e2c83e1 100644 --- a/test/construct.jl +++ b/test/construct.jl @@ -71,6 +71,12 @@ end @test read(io,String) == "αβ" end @test DataString["a","b"] == ["a","b"] + longs = StringVector(["first long string value", "second long string value"]) + for s in (DataString(""), DataString("αβ"), DataString("twelve bytes"), longs[1], longs[2]) + io = IOBuffer() + @test write(io, s) == ncodeunits(s) + @test String(take!(io)) == String(s) + end values = Union{String,Missing}["a", "a long value retained by a view", missing] col = StringVector(values) retained = col[2]