diff --git a/src/noop.jl b/src/noop.jl index 2ebc44c2..30258dfc 100644 --- a/src/noop.jl +++ b/src/noop.jl @@ -116,16 +116,15 @@ function Base.unsafe_write(stream::NoopStream, input::Ptr{UInt8}, nbytes::UInt) end end -function Base.transcode(::Type{Noop}, data::ByteData) - return transcode(Noop(), data) -end +initial_output_size(codec::Noop, input::Memory) = length(input) -function Base.transcode(codec::Noop, input::Buffer, output::Buffer = Buffer()) - copydata!(output, input) - return output.data +function process(codec::Noop, input::Memory, output::Memory, error::Error) + iszero(length(input)) && return (0, 0, :end) + n = min(length(input), length(output)) + unsafe_copyto!(output.ptr, input.ptr, n) + (n, n, :ok) end - # Stats # ----- diff --git a/src/transcode.jl b/src/transcode.jl index b1b03876..461f95b9 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -106,16 +106,34 @@ end """ transcode!(output::Buffer, codec::Codec, input::Buffer) -Transcode `input` by applying `codec` and storing the results in `output`. -Note that this method does not initialize or finalize `codec`. This is -efficient when you transcode a number of pieces of data, but you need to call -[`TranscodingStreams.initialize`](@ref) and +Transcode `input` by applying `codec` and storing the results in `output` +with validation of input and output. Note that this method does not initialize +or finalize `codec`. This is efficient when you transcode a number of +pieces of data, but you need to call [`TranscodingStreams.initialize`](@ref) and [`TranscodingStreams.finalize`](@ref) explicitly. """ function transcode!( output::Buffer, codec::Codec, input::Buffer, +) + @assert !Base.mightalias(input.data, output.data) "input and outbut buffers must be independent" + unsafe_transcode!(output, codec, input) +end + +""" + unsafe_transcode!(output::Buffer, codec::Codec, input::Buffer) + +Transcode `input` by applying `codec` and storing the results in `output` +without validation of input or output. Note that this method does not initialize +or finalize `codec`. This is efficient when you transcode a number of +pieces of data, but you need to call [`TranscodingStreams.initialize`](@ref) and +[`TranscodingStreams.finalize`](@ref) explicitly. +""" +function unsafe_transcode!( + output::Buffer, + codec::Codec, + input::Buffer, ) error = Error() code = startproc(codec, :write, error) @@ -165,6 +183,12 @@ Base.transcode(codec::Codec, data::Buffer, output::ByteData) = Base.transcode(codec::Codec, data::ByteData, args...) = transcode(codec, Buffer(data), args...) +unsafe_transcode!(codec::Codec, data::Buffer, output::ByteData) = + unsafe_transcode!(Buffer(output), codec, data) + +unsafe_transcode!(codec::Codec, data::ByteData, args...) = + unsafe_transcode!(codec, Buffer(data), args...) + # Return the initial output buffer size. function initial_output_size(codec::Codec, input::Memory) return max( diff --git a/test/codecnoop.jl b/test/codecnoop.jl index 22e6e93c..d288f3c3 100644 --- a/test/codecnoop.jl +++ b/test/codecnoop.jl @@ -189,6 +189,9 @@ @test transcode(Noop, data) == data @test transcode(Noop, data) !== data + data = Vector{UInt8}() + @test TranscodingStreams.unsafe_transcode!(Noop(), data, data) == data + @test_throws AssertionError transcode(Noop(), data, data) data = b"" @test transcode(Noop(), data) == data @test transcode(Noop(), data) !== data