Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assert that input and output buffers passed to transcode! are independent #140

Merged
merged 6 commits into from
Apr 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/noop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
# -----

Expand Down
32 changes: 28 additions & 4 deletions src/transcode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand Down
3 changes: 3 additions & 0 deletions test/codecnoop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down