From ba64ff777080225a128796c1423ded4d76c11df5 Mon Sep 17 00:00:00 2001 From: Ben Baumgold <4933671+baumgold@users.noreply.github.com> Date: Tue, 11 Apr 2023 21:25:30 -0400 Subject: [PATCH 1/6] assert that input and output buffers passed to transcode! are independent --- src/transcode.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transcode.jl b/src/transcode.jl index b1b03876..fb8ccdb3 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -117,6 +117,7 @@ function transcode!( codec::Codec, input::Buffer, ) + @assert input.data !== output.data "input and outbut buffers must be independent" error = Error() code = startproc(codec, :write, error) if code === :error From 65e5f4d33072c4324fabcc0a7a6a82aba169e857 Mon Sep 17 00:00:00 2001 From: Ben Baumgold <4933671+baumgold@users.noreply.github.com> Date: Thu, 13 Apr 2023 18:12:46 -0400 Subject: [PATCH 2/6] Use Base.dataids Co-authored-by: Mark Kittisopikul --- src/transcode.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transcode.jl b/src/transcode.jl index fb8ccdb3..e91845e8 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -117,7 +117,7 @@ function transcode!( codec::Codec, input::Buffer, ) - @assert input.data !== output.data "input and outbut buffers must be independent" + @assert Base.dataids(input.data) !== Base.dataids(output.data) "input and outbut buffers must be independent" error = Error() code = startproc(codec, :write, error) if code === :error From 2d5e125c343450cf2731abeb83d9035016d4dd75 Mon Sep 17 00:00:00 2001 From: Ben Baumgold <4933671+baumgold@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:02:07 -0400 Subject: [PATCH 3/6] use Base.mightalias and add test --- src/noop.jl | 7 +++---- src/transcode.jl | 2 +- test/codecnoop.jl | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/noop.jl b/src/noop.jl index 2ebc44c2..a75b0f00 100644 --- a/src/noop.jl +++ b/src/noop.jl @@ -116,11 +116,10 @@ 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()) +function transcode!(output::Buffer, codec::Noop, input::Buffer) + @assert !Base.mightalias(input.data, output.data) "input and outbut buffers must be independent" copydata!(output, input) return output.data end diff --git a/src/transcode.jl b/src/transcode.jl index e91845e8..df6ca86d 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -117,7 +117,7 @@ function transcode!( codec::Codec, input::Buffer, ) - @assert Base.dataids(input.data) !== Base.dataids(output.data) "input and outbut buffers must be independent" + @assert !Base.mightalias(input.data, output.data) "input and outbut buffers must be independent" error = Error() code = startproc(codec, :write, error) if code === :error diff --git a/test/codecnoop.jl b/test/codecnoop.jl index 22e6e93c..a303bcad 100644 --- a/test/codecnoop.jl +++ b/test/codecnoop.jl @@ -189,6 +189,8 @@ @test transcode(Noop, data) == data @test transcode(Noop, data) !== data + data = Vector{UInt8}() + @test_throws AssertionError transcode(Noop(), data, data) data = b"" @test transcode(Noop(), data) == data @test transcode(Noop(), data) !== data From cecee5690d21ba66589133408b32fac6fa5e6a4b Mon Sep 17 00:00:00 2001 From: Ben Baumgold <4933671+baumgold@users.noreply.github.com> Date: Fri, 14 Apr 2023 15:24:23 -0400 Subject: [PATCH 4/6] fix noop codec implementation --- src/noop.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/noop.jl b/src/noop.jl index a75b0f00..30258dfc 100644 --- a/src/noop.jl +++ b/src/noop.jl @@ -118,13 +118,13 @@ end initial_output_size(codec::Noop, input::Memory) = length(input) -function transcode!(output::Buffer, codec::Noop, input::Buffer) - @assert !Base.mightalias(input.data, output.data) "input and outbut buffers must be independent" - 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 # ----- From 2eec7700136d18e3bf7378ba49f7c2a7c54a07ca Mon Sep 17 00:00:00 2001 From: Ben Baumgold <4933671+baumgold@users.noreply.github.com> Date: Tue, 18 Apr 2023 07:46:25 -0400 Subject: [PATCH 5/6] add unsafe_transcode --- src/transcode.jl | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/transcode.jl b/src/transcode.jl index df6ca86d..c9e65664 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -106,10 +106,10 @@ 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!( @@ -118,6 +118,23 @@ function transcode!( 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) if code === :error From bd5fe77f3f30d0a40ae07ad3f4caaf80212958a4 Mon Sep 17 00:00:00 2001 From: Ben Baumgold <4933671+baumgold@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:48:40 -0400 Subject: [PATCH 6/6] add test --- src/transcode.jl | 6 ++++++ test/codecnoop.jl | 1 + 2 files changed, 7 insertions(+) diff --git a/src/transcode.jl b/src/transcode.jl index c9e65664..461f95b9 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -183,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 a303bcad..d288f3c3 100644 --- a/test/codecnoop.jl +++ b/test/codecnoop.jl @@ -190,6 +190,7 @@ @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