| ... | ... | @@ -54,6 +54,40 @@ const ReadWriteCount = struct { |
| 54 | 54 | write_count: usize, |
| 55 | 55 | }; |
| 56 | 56 | |
| 57 | /// Decodes frames from `src` into `dest`; see `decodeFrame()`. |
| 58 | pub fn decode(dest: []u8, src: []const u8, verify_checksum: bool) !usize { |
| 59 | var write_count: usize = 0; |
| 60 | var read_count: usize = 0; |
| 61 | while (read_count < src.len) { |
| 62 | const counts = try decodeFrame(dest, src[read_count..], verify_checksum); |
| 63 | read_count += counts.read_count; |
| 64 | write_count += counts.write_count; |
| 65 | } |
| 66 | return write_count; |
| 67 | } |
| 68 | |
| 69 | pub fn decodeAlloc( |
| 70 | allocator: Allocator, |
| 71 | src: []const u8, |
| 72 | verify_checksum: bool, |
| 73 | window_size_max: usize, |
| 74 | ) ![]u8 { |
| 75 | var result = std.ArrayList(u8).init(allocator); |
| 76 | errdefer result.deinit(); |
| 77 | |
| 78 | var read_count: usize = 0; |
| 79 | while (read_count < src.len) { |
| 80 | read_count += try decodeZstandardFrameArrayList( |
| 81 | allocator, |
| 82 | &result, |
| 83 | src[read_count..], |
| 84 | verify_checksum, |
| 85 | window_size_max, |
| 86 | ); |
| 87 | } |
| 88 | return result.toOwnedSlice(); |
| 89 | } |
| 90 | |
| 57 | 91 | /// Decodes the frame at the start of `src` into `dest`. Returns the number of |
| 58 | 92 | /// bytes read from `src` and written to `dest`. This function can only decode |
| 59 | 93 | /// frames that declare the decompressed content size. |
| ... | ... | @@ -268,6 +302,24 @@ pub fn decodeZstandardFrameAlloc( |
| 268 | 302 | ) (error{OutOfMemory} || FrameContext.Error || FrameError)!DecodeResult { |
| 269 | 303 | var result = std.ArrayList(u8).init(allocator); |
| 270 | 304 | errdefer result.deinit(); |
| 305 | const read_count = try decodeZstandardFrameArrayList( |
| 306 | allocator, |
| 307 | &result, |
| 308 | src, |
| 309 | verify_checksum, |
| 310 | window_size_max, |
| 311 | ); |
| 312 | return DecodeResult{ .bytes = try result.toOwnedSlice(), .read_count = read_count }; |
| 313 | } |
| 314 | |
| 315 | /// Decode a ZStandard frame into `dest`; see `decodeZStandardFrameAlloc()`. |
| 316 | pub fn decodeZstandardFrameArrayList( |
| 317 | allocator: Allocator, |
| 318 | dest: *std.ArrayList(u8), |
| 319 | src: []const u8, |
| 320 | verify_checksum: bool, |
| 321 | window_size_max: usize, |
| 322 | ) (error{OutOfMemory} || FrameContext.Error || FrameError)!usize { |
| 271 | 323 | assert(readInt(u32, src[0..4]) == frame.Zstandard.magic_number); |
| 272 | 324 | var consumed_count: usize = 4; |
| 273 | 325 | |
| ... | ... | @@ -305,8 +357,8 @@ pub fn decodeZstandardFrameAlloc( |
| 305 | 357 | ); |
| 306 | 358 | if (written_size > 0) { |
| 307 | 359 | const written_slice = ring_buffer.sliceLast(written_size); |
| 308 | | try result.appendSlice(written_slice.first); |
| 309 | | try result.appendSlice(written_slice.second); |
| 360 | try dest.appendSlice(written_slice.first); |
| 361 | try dest.appendSlice(written_slice.second); |
| 310 | 362 | if (frame_context.hasher_opt) |*hasher| { |
| 311 | 363 | hasher.update(written_slice.first); |
| 312 | 364 | hasher.update(written_slice.second); |
| ... | ... | @@ -323,7 +375,7 @@ pub fn decodeZstandardFrameAlloc( |
| 323 | 375 | if (checksum != computeChecksum(hasher)) return error.ChecksumFailure; |
| 324 | 376 | } |
| 325 | 377 | } |
| 326 | | return DecodeResult{ .bytes = try result.toOwnedSlice(), .read_count = consumed_count }; |
| 378 | return consumed_count; |
| 327 | 379 | } |
| 328 | 380 | |
| 329 | 381 | /// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`. |