Skip to content

Commit 8423b71

Browse files
baumgoldmkitti
andauthored
assert that input and output buffers passed to transcode! are independent (#140)
* assert that input and output buffers passed to transcode! are independent * Use Base.dataids Co-authored-by: Mark Kittisopikul <[email protected]> * use Base.mightalias and add test * fix noop codec implementation * add unsafe_transcode * add test --------- Co-authored-by: Mark Kittisopikul <[email protected]>
1 parent eda3444 commit 8423b71

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

src/noop.jl

+6-7
Original file line numberDiff line numberDiff line change
@@ -116,16 +116,15 @@ function Base.unsafe_write(stream::NoopStream, input::Ptr{UInt8}, nbytes::UInt)
116116
end
117117
end
118118

119-
function Base.transcode(::Type{Noop}, data::ByteData)
120-
return transcode(Noop(), data)
121-
end
119+
initial_output_size(codec::Noop, input::Memory) = length(input)
122120

123-
function Base.transcode(codec::Noop, input::Buffer, output::Buffer = Buffer())
124-
copydata!(output, input)
125-
return output.data
121+
function process(codec::Noop, input::Memory, output::Memory, error::Error)
122+
iszero(length(input)) && return (0, 0, :end)
123+
n = min(length(input), length(output))
124+
unsafe_copyto!(output.ptr, input.ptr, n)
125+
(n, n, :ok)
126126
end
127127

128-
129128
# Stats
130129
# -----
131130

src/transcode.jl

+28-4
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,34 @@ end
112112
"""
113113
transcode!(output::Buffer, codec::Codec, input::Buffer)
114114
115-
Transcode `input` by applying `codec` and storing the results in `output`.
116-
Note that this method does not initialize or finalize `codec`. This is
117-
efficient when you transcode a number of pieces of data, but you need to call
118-
[`TranscodingStreams.initialize`](@ref) and
115+
Transcode `input` by applying `codec` and storing the results in `output`
116+
with validation of input and output. Note that this method does not initialize
117+
or finalize `codec`. This is efficient when you transcode a number of
118+
pieces of data, but you need to call [`TranscodingStreams.initialize`](@ref) and
119119
[`TranscodingStreams.finalize`](@ref) explicitly.
120120
"""
121121
function transcode!(
122122
output::Buffer,
123123
codec::Codec,
124124
input::Buffer,
125+
)
126+
@assert !Base.mightalias(input.data, output.data) "input and outbut buffers must be independent"
127+
unsafe_transcode!(output, codec, input)
128+
end
129+
130+
"""
131+
unsafe_transcode!(output::Buffer, codec::Codec, input::Buffer)
132+
133+
Transcode `input` by applying `codec` and storing the results in `output`
134+
without validation of input or output. Note that this method does not initialize
135+
or finalize `codec`. This is efficient when you transcode a number of
136+
pieces of data, but you need to call [`TranscodingStreams.initialize`](@ref) and
137+
[`TranscodingStreams.finalize`](@ref) explicitly.
138+
"""
139+
function unsafe_transcode!(
140+
output::Buffer,
141+
codec::Codec,
142+
input::Buffer,
125143
)
126144
error = Error()
127145
code = startproc(codec, :write, error)
@@ -171,6 +189,12 @@ Base.transcode(codec::Codec, data::Buffer, output::ByteData) =
171189
Base.transcode(codec::Codec, data::ByteData, args...) =
172190
transcode(codec, Buffer(data), args...)
173191

192+
unsafe_transcode!(codec::Codec, data::Buffer, output::ByteData) =
193+
unsafe_transcode!(Buffer(output), codec, data)
194+
195+
unsafe_transcode!(codec::Codec, data::ByteData, args...) =
196+
unsafe_transcode!(codec, Buffer(data), args...)
197+
174198
# Return the initial output buffer size.
175199
function initial_output_size(codec::Codec, input::Memory)
176200
return max(

test/codecnoop.jl

+3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@
189189
@test transcode(Noop, data) == data
190190
@test transcode(Noop, data) !== data
191191

192+
data = Vector{UInt8}()
193+
@test TranscodingStreams.unsafe_transcode!(Noop(), data, data) == data
194+
@test_throws AssertionError transcode(Noop(), data, data)
192195
data = b""
193196
@test transcode(Noop(), data) == data
194197
@test transcode(Noop(), data) !== data

0 commit comments

Comments
 (0)