| ... | ... | @@ -70,13 +70,11 @@ pub fn DecompressStream( |
| 70 | 70 | self.state = .NewFrame; |
| 71 | 71 | }, |
| 72 | 72 | .zstandard => |header| { |
| 73 | | const frame_context = context: { |
| 74 | | break :context try decompress.FrameContext.init( |
| 75 | | header, |
| 76 | | options.window_size_max, |
| 77 | | options.verify_checksum, |
| 78 | | ); |
| 79 | | }; |
| 73 | const frame_context = try decompress.FrameContext.init( |
| 74 | header, |
| 75 | options.window_size_max, |
| 76 | options.verify_checksum, |
| 77 | ); |
| 80 | 78 | |
| 81 | 79 | const literal_fse_buffer = try self.allocator.alloc( |
| 82 | 80 | types.compressed_block.Table.Fse, |
| ... | ... | @@ -219,7 +217,9 @@ pub fn DecompressStream( |
| 219 | 217 | } |
| 220 | 218 | |
| 221 | 219 | const size = @min(self.buffer.len(), buffer.len); |
| 222 | | self.buffer.readFirstAssumeLength(buffer, size); |
| 220 | if (size > 0) { |
| 221 | self.buffer.readFirstAssumeLength(buffer, size); |
| 222 | } |
| 223 | 223 | if (self.state == .LastBlock and self.buffer.len() == 0) { |
| 224 | 224 | self.state = .NewFrame; |
| 225 | 225 | self.allocator.free(self.literal_fse_buffer); |
| ... | ... | @@ -282,3 +282,48 @@ test "zstandard decompression" { |
| 282 | 282 | try testReader(compressed3, uncompressed); |
| 283 | 283 | try testReader(compressed19, uncompressed); |
| 284 | 284 | } |
| 285 | |
| 286 | fn expectEqualDecoded(expected: []const u8, input: []const u8) !void { |
| 287 | const allocator = std.testing.allocator; |
| 288 | |
| 289 | { |
| 290 | const result = try decompress.decodeAlloc(allocator, input, false, 1 << 23); |
| 291 | defer allocator.free(result); |
| 292 | try std.testing.expectEqualStrings(expected, result); |
| 293 | } |
| 294 | |
| 295 | { |
| 296 | var buffer = try allocator.alloc(u8, 2 * expected.len); |
| 297 | defer allocator.free(buffer); |
| 298 | |
| 299 | const size = try decompress.decode(buffer, input, false); |
| 300 | try std.testing.expectEqualStrings(expected, buffer[0..size]); |
| 301 | } |
| 302 | |
| 303 | { |
| 304 | var in_stream = std.io.fixedBufferStream(input); |
| 305 | var stream = decompressStream(allocator, in_stream.reader()); |
| 306 | defer stream.deinit(); |
| 307 | |
| 308 | const result = try stream.reader().readAllAlloc(allocator, std.math.maxInt(usize)); |
| 309 | defer allocator.free(result); |
| 310 | |
| 311 | try std.testing.expectEqualStrings(expected, result); |
| 312 | } |
| 313 | } |
| 314 | |
| 315 | test "zero sized block" { |
| 316 | const input_raw = |
| 317 | "\x28\xb5\x2f\xfd" ++ // zstandard frame magic number |
| 318 | "\x20\x00" ++ // frame header: only single_segment_flag set, frame_content_size zero |
| 319 | "\x01\x00\x00"; // block header with: last_block set, block_type raw, block_size zero |
| 320 | |
| 321 | const input_rle = |
| 322 | "\x28\xb5\x2f\xfd" ++ // zstandard frame magic number |
| 323 | "\x20\x00" ++ // frame header: only single_segment_flag set, frame_content_size zero |
| 324 | "\x03\x00\x00" ++ // block header with: last_block set, block_type rle, block_size zero |
| 325 | "\xaa"; // block_content |
| 326 | |
| 327 | try expectEqualDecoded("", input_raw); |
| 328 | try expectEqualDecoded("", input_rle); |
| 329 | } |