| ... | @@ -54,6 +54,40 @@ const ReadWriteCount = struct { | ... | @@ -54,6 +54,40 @@ const ReadWriteCount = struct { |
| 54 | write_count: usize, | 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 | /// Decodes the frame at the start of `src` into `dest`. Returns the number of | 91 | /// Decodes the frame at the start of `src` into `dest`. Returns the number of |
| 58 | /// bytes read from `src` and written to `dest`. This function can only decode | 92 | /// bytes read from `src` and written to `dest`. This function can only decode |
| 59 | /// frames that declare the decompressed content size. | 93 | /// frames that declare the decompressed content size. |
| ... | @@ -268,6 +302,24 @@ pub fn decodeZstandardFrameAlloc( | ... | @@ -268,6 +302,24 @@ pub fn decodeZstandardFrameAlloc( |
| 268 | ) (error{OutOfMemory} || FrameContext.Error || FrameError)!DecodeResult { | 302 | ) (error{OutOfMemory} || FrameContext.Error || FrameError)!DecodeResult { |
| 269 | var result = std.ArrayList(u8).init(allocator); | 303 | var result = std.ArrayList(u8).init(allocator); |
| 270 | errdefer result.deinit(); | 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 | assert(readInt(u32, src[0..4]) == frame.Zstandard.magic_number); | 323 | assert(readInt(u32, src[0..4]) == frame.Zstandard.magic_number); |
| 272 | var consumed_count: usize = 4; | 324 | var consumed_count: usize = 4; |
| 273 | | 325 | |
| ... | @@ -305,8 +357,8 @@ pub fn decodeZstandardFrameAlloc( | ... | @@ -305,8 +357,8 @@ pub fn decodeZstandardFrameAlloc( |
| 305 | ); | 357 | ); |
| 306 | if (written_size > 0) { | 358 | if (written_size > 0) { |
| 307 | const written_slice = ring_buffer.sliceLast(written_size); | 359 | const written_slice = ring_buffer.sliceLast(written_size); |
| 308 | try result.appendSlice(written_slice.first); | 360 | try dest.appendSlice(written_slice.first); |
| 309 | try result.appendSlice(written_slice.second); | 361 | try dest.appendSlice(written_slice.second); |
| 310 | if (frame_context.hasher_opt) |*hasher| { | 362 | if (frame_context.hasher_opt) |*hasher| { |
| 311 | hasher.update(written_slice.first); | 363 | hasher.update(written_slice.first); |
| 312 | hasher.update(written_slice.second); | 364 | hasher.update(written_slice.second); |
| ... | @@ -323,7 +375,7 @@ pub fn decodeZstandardFrameAlloc( | ... | @@ -323,7 +375,7 @@ pub fn decodeZstandardFrameAlloc( |
| 323 | if (checksum != computeChecksum(hasher)) return error.ChecksumFailure; | 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 | /// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`. | 381 | /// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`. |