@@ -60,10 +60,8 @@ function decode(
6060 throw (DecodedSizeError (_clamp_max_size, try_find_decoded_size (d, src)))
6161 end
6262 @assert real_dst_size ∈ 0 : _clamp_max_size
63- if real_dst_size < _clamp_size_hint
64- resize! (dst, real_dst_size)
65- end
66- @assert real_dst_size == length (dst)
63+ @assert real_dst_size ≤ length (dst)
64+ resize! (dst, real_dst_size)
6765 dst
6866end
6967
@@ -206,55 +204,32 @@ Try to decode the input `src` into `dst` using decoder `d`.
206204
207205Return the size of the decoded output in `dst` if successful.
208206
209- If `dst` is too small, resize `dst` and try again.
210- If the `max_size` limit will be passed, return `nothing`.
211-
212- `dst` can be resized using the `resize!` function to any size between the original length of `dst` and `max_size`.
207+ `dst` can be grown using the `resize!` function to any size between one more than the original length of `dst` and `max_size`.
213208
214- Throw an `ArgumentError ` if `length( dst) ` is not in `0: max_size`.
209+ Return `nothing ` if the size of ` dst` is too small to contain the decoded output and cannot be grown due to the ` max_size` restriction .
215210
216211Precondition: `dst` and `src` do not overlap in memory.
217212
218213All of `dst` can be written to or used as scratch space by the decoder.
219214Only the initial returned number of bytes are valid output.
220-
221- If the size of `dst` is increased, its length will be equal to the returned number of bytes.
222215"""
223216function try_resize_decode! (d, dst:: AbstractVector{UInt8} , src:: AbstractVector{UInt8} , max_size:: Int64 ; kwargs... ):: Union{Nothing, Int64}
224- check_in_range (Int64 (0 ): max_size; dst_size= length (dst))
225- olb:: Int64 = length (dst)
226217 decoded_size = try_find_decoded_size (d, src):: Union{Nothing, Int64}
227218 if isnothing (decoded_size)
228219 while true
229220 ds = try_decode! (d, dst, src):: Union{Nothing, Int64}
230221 if isnothing (ds)
231- # grow dst
232- local cur_size:: Int64 = length (dst)
233- if cur_size == max_size
234- return
235- end
236- @assert cur_size < max_size
237- # This inequality prevents overflow
238- local next_size = if max_size - cur_size ≤ cur_size
239- max_size
240- else
241- max (2 * cur_size, Int64 (1 ))
242- end
243- resize! (dst, next_size)
222+ @something grow_dst! (dst, max_size) return nothing
244223 else
245224 @assert ds ∈ 0 : length (dst)
246- if length (dst) > olb && length (dst) != ds
247- @assert ds > olb
248- resize! (dst, ds) # shrink to just contain output if it was resized.
249- end
250225 return ds
251226 end
252227 end
253228 else
254- if decoded_size ∉ 0 : max_size
255- return
256- end
257- if decoded_size > olb
229+ if decoded_size > length (dst)
230+ if decoded_size > max_size
231+ return nothing
232+ end
258233 resize! (dst, decoded_size)
259234 end
260235 real_dst_size = something (try_decode! (d, dst, src))
@@ -300,3 +275,24 @@ function check_in_range(range; kwargs...)
300275 end
301276 end
302277end
278+
279+ """
280+ grow_dst!(dst::AbstractVector{UInt8}, max_size::Int64)::Union{Nothing, Int64}
281+
282+ Grow the destination vector `dst` to a size between its current size and `max_size`.
283+ Return the new size of `dst` if it was grown, or `nothing` if it could not be grown due to the `max_size` restriction.
284+ """
285+ function grow_dst! (dst:: AbstractVector{UInt8} , max_size:: Int64 ):: Union{Nothing, Int64}
286+ cur_size:: Int64 = length (dst)
287+ if cur_size ≥ max_size
288+ return
289+ end
290+ # This inequality prevents overflow
291+ next_size:: Int64 = if max_size - cur_size ≤ cur_size
292+ max_size
293+ else
294+ max (2 * cur_size, Int64 (1 ))
295+ end
296+ resize! (dst, next_size)
297+ return next_size
298+ end
0 commit comments