Skip to content

Commit 1e76822

Browse files
committed
add transcode
1 parent 7ea7558 commit 1e76822

File tree

5 files changed

+47
-1
lines changed

5 files changed

+47
-1
lines changed

src/buffer.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ mutable struct Buffer
2323
marginpos::Int
2424

2525
function Buffer(size::Integer)
26-
@assert size > 0
2726
return new(Vector{UInt8}(size), 0, 1, 1)
2827
end
28+
29+
function Buffer(data::Vector{UInt8})
30+
return new(data, 0, 1, length(data)+1)
31+
end
2932
end
3033

3134
function Base.length(buf::Buffer)
@@ -167,6 +170,12 @@ function initbuffer!(buf::Buffer)
167170
return buf
168171
end
169172

173+
# Copy marked data.
174+
function copymarked(buf::Buffer)
175+
@assert buf.markpos > 0
176+
return buf.data[buf.markpos:buf.marginpos-1]
177+
end
178+
170179
# Read as much data as possbile from `input` to the margin of `output`.
171180
# This function will not block if `input` has buffered data.
172181
function readdata!(input::IO, output::Buffer)

src/state.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ mutable struct State
2323
function State(size::Integer)
2424
return new(:idle, :ok, Buffer(size), Buffer(size))
2525
end
26+
27+
function State(buffer1::Buffer, buffer2::Buffer)
28+
return new(:idle, :ok, buffer1, buffer2)
29+
end
2630
end

src/stream.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ function TranscodingStream(codec::Codec, stream::IO; bufsize::Integer=DEFAULT_BU
4545
return TranscodingStream{typeof(codec),typeof(stream)}(codec, stream, State(bufsize))
4646
end
4747

48+
function TranscodingStream(codec::Codec, stream::IO, state::State)
49+
return TranscodingStream{typeof(codec),typeof(stream)}(codec, stream, state)
50+
end
51+
4852
function Base.show(io::IO, stream::TranscodingStream)
4953
print(io, summary(stream), "(<state=$(stream.state.state)>)")
5054
end
@@ -267,6 +271,22 @@ function Base.write(stream::TranscodingStream, ::EndToken)
267271
end
268272

269273

274+
# Transcode
275+
# ---------
276+
277+
"""
278+
transcode(codec::Codec, data::Vector{UInt8})::Vector{UInt8}
279+
280+
Transcode `data` by applying `codec`.
281+
"""
282+
function Base.transcode(codec::Codec, data::Vector{UInt8})
283+
buffer2 = Buffer(length(data))
284+
mark!(buffer2)
285+
write(TranscodingStream(codec, DevNull, State(Buffer(data), buffer2)), TOKEN_END)
286+
return copymarked(buffer2)
287+
end
288+
289+
270290
# Buffering
271291
# ---------
272292

src/testtools.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,11 @@ function test_roundtrip_write(encoder, decoder)
2323
close(stream)
2424
end
2525
end
26+
27+
function test_roundtrip_transcode(encode, decode)
28+
srand(12345)
29+
for n in vcat(0:30, sort!(rand(500:100_000, 30))), alpha in (0x00:0xff, 0x00:0x0f)
30+
data = rand(alpha, n)
31+
Base.Test.@test hash(transcode(decode(), transcode(encode(), data))) == hash(data)
32+
end
33+
end

test/runtests.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ using Base.Test
7979
mark(stream)
8080
@test hash(read(stream)) == hash(data)
8181
@test hash(stream.state.buffer1.data[1:length(data)]) == hash(data)
82+
83+
# transcode
84+
@test transcode(Identity(), b"") == b""
85+
@test transcode(Identity(), b"foo") == b"foo"
86+
TranscodingStreams.test_roundtrip_transcode(Identity, Identity)
8287
end
8388

8489
Pkg.test("CodecZlib")

0 commit comments

Comments
 (0)