@@ -77,11 +77,53 @@ julia> String(decompressed)
77
77
```
78
78
"""
79
79
function Base. transcode (codec:: Codec , data:: ByteData )
80
- # Add `minoutsize` because `transcode` will be called at least two times.
81
- buffer2 = Buffer (
82
- expectedsize (codec, Memory (data)) + minoutsize (codec, Memory (C_NULL , 0 )))
83
- mark! (buffer2)
84
- stream = TranscodingStream (codec, devnull , State (Buffer (data), buffer2); initialized= true )
85
- write (stream, TOKEN_END)
86
- return takemarked! (buffer2)
80
+ input = Buffer (data)
81
+ output = Buffer (initial_output_size (codec, buffermem (input)))
82
+ error = Error ()
83
+ code = startproc (codec, :write , error)
84
+ if code === :error
85
+ @goto error
86
+ end
87
+ n = minoutsize (codec, buffermem (input))
88
+ while code != = :end || buffersize (input) > 0
89
+ makemargin! (output, n)
90
+ Δin, Δout, code = process (codec, buffermem (input), marginmem (output), error)
91
+ @debug (
92
+ " called process()" ,
93
+ code = code,
94
+ input_size = buffersize (input),
95
+ output_size = marginsize (output),
96
+ input_delta = Δin,
97
+ output_delta = Δout,
98
+ )
99
+ consumed! (input, Δin)
100
+ supplied! (output, Δout)
101
+ if code === :error
102
+ @goto error
103
+ elseif code === :end && buffersize (input) > 0
104
+ if startproc (codec, :write , error) === :error
105
+ @goto error
106
+ end
107
+ end
108
+ n = max (Δout, minoutsize (codec, buffermem (input)))
109
+ end
110
+ if marginsize (output) == 0
111
+ return output. data
112
+ else
113
+ return output. data[1 : output. marginpos- 1 ]
114
+ end
115
+ @label error
116
+ if ! haserror (error)
117
+ set_default_error! (error)
118
+ end
119
+ throw (error[])
120
+ end
121
+
122
+ # Return the initial output buffer size.
123
+ function initial_output_size (codec:: Codec , input:: Memory )
124
+ return max (
125
+ minoutsize (codec, input),
126
+ expectedsize (codec, input),
127
+ 8 , # just in case where both minoutsize and expectedsize are foolish
128
+ )
87
129
end
0 commit comments