diff --git a/base/strings/string.jl b/base/strings/string.jl index c2aa95690e99d..a57e87ba1c01c 100644 --- a/base/strings/string.jl +++ b/base/strings/string.jl @@ -77,6 +77,16 @@ function String(v::Vector{UInt8}) setfield!(v, :ref, memoryref(Memory{UInt8}())) return str end +function String(v::ReinterpretArray{UInt8, 1, S, Vector{S}, IsReshaped}) where {S, IsReshaped} + len = length(v) + len == 0 && return "" + return ccall(:jl_pchar_to_string, Ref{String}, (Ptr{S}, Int), v.parent.ref, len) +end +function String(v::ReinterpretArray{UInt8, 1, S, Memory{S}, IsReshaped}) where {S, IsReshaped} + len = length(v) + len == 0 && return "" + return ccall(:jl_pchar_to_string, Ref{String}, (Ptr{S}, Int), v.parent.ptr, len) +end "Create a string re-using the memory, if possible. Mutating or reading the memory after calling this function is undefined behaviour." diff --git a/test/strings/basic.jl b/test/strings/basic.jl index c3e0bcc501070..7276e8183b51c 100644 --- a/test/strings/basic.jl +++ b/test/strings/basic.jl @@ -8,6 +8,14 @@ using Random @test String("abc!") == "abc!" @test String(0x61:0x63) == "abc" + v = [0x61,0x62,0x63,0x21] + v32 = copy(reinterpret(UInt32, v)) + @test String(reinterpret(UInt8, v32)) == "abc!" && !isempty(v32) + @test 1 == @allocations String(reinterpret(UInt8, v32)) + m32 = v32.ref.mem + @test String(reinterpret(UInt8, m32)) == "abc!" && !isempty(m32) + @test 1 == @allocations String(reinterpret(UInt8, m32)) + # Check that resizing empty source vector does not corrupt string b = IOBuffer() @inferred write(b, "ab")