From ee5af3c74c27ebf366ef51486119487650f80468 Mon Sep 17 00:00:00 2001 From: dweiller <4678790+dweiller@users.noreplay.github.com> Date: Fri, 10 Feb 2023 01:33:38 +1100 Subject: [PATCH] std.compress.zstandard: cleanup high-level api docs and error sets --- lib/std/compress/zstandard.zig | 40 +++-- lib/std/compress/zstandard/RingBuffer.zig | 9 +- lib/std/compress/zstandard/decode/block.zig | 6 +- lib/std/compress/zstandard/decompress.zig | 169 +++++++++++++++----- lib/std/compress/zstandard/types.zig | 18 ++- 5 files changed, 173 insertions(+), 69 deletions(-) diff --git a/lib/std/compress/zstandard.zig b/lib/std/compress/zstandard.zig index 72ed40e03d..afc542478b 100644 --- a/lib/std/compress/zstandard.zig +++ b/lib/std/compress/zstandard.zig @@ -7,7 +7,11 @@ const RingBuffer = @import("zstandard/RingBuffer.zig"); pub const decompress = @import("zstandard/decompress.zig"); pub usingnamespace @import("zstandard/types.zig"); -pub fn ZstandardStream(comptime ReaderType: type, comptime verify_checksum: bool, comptime window_size_max: usize) type { +pub fn ZstandardStream( + comptime ReaderType: type, + comptime verify_checksum: bool, + comptime window_size_max: usize, +) type { return struct { const Self = @This(); @@ -24,11 +28,16 @@ pub fn ZstandardStream(comptime ReaderType: type, comptime verify_checksum: bool sequence_buffer: []u8, checksum: if (verify_checksum) ?u32 else void, - pub const Error = ReaderType.Error || error{ ChecksumFailure, MalformedBlock, MalformedFrame, OutOfMemory }; + pub const Error = ReaderType.Error || error{ + ChecksumFailure, + MalformedBlock, + MalformedFrame, + OutOfMemory, + }; pub const Reader = std.io.Reader(*Self, Error, read); - pub fn init(allocator: Allocator, source: ReaderType) !Self { + pub fn init(allocator: Allocator, source: ReaderType) Self { return Self{ .allocator = allocator, .source = std.io.countingReader(source), @@ -146,7 +155,8 @@ pub fn ZstandardStream(comptime ReaderType: type, comptime verify_checksum: bool const source_reader = self.source.reader(); while (self.buffer.isEmpty() and self.state != .LastBlock) { - const header_bytes = source_reader.readBytesNoEof(3) catch return error.MalformedFrame; + const header_bytes = source_reader.readBytesNoEof(3) catch + return error.MalformedFrame; const block_header = decompress.block.decodeBlockHeader(&header_bytes); decompress.block.decodeBlockReader( @@ -171,10 +181,12 @@ pub fn ZstandardStream(comptime ReaderType: type, comptime verify_checksum: bool if (block_header.last_block) { self.state = .LastBlock; if (self.frame_context.has_checksum) { - const checksum = source_reader.readIntLittle(u32) catch return error.MalformedFrame; + const checksum = source_reader.readIntLittle(u32) catch + return error.MalformedFrame; if (comptime verify_checksum) { if (self.frame_context.hasher_opt) |*hasher| { - if (checksum != decompress.computeChecksum(hasher)) return error.ChecksumFailure; + if (checksum != decompress.computeChecksum(hasher)) + return error.ChecksumFailure; } } } @@ -182,9 +194,9 @@ pub fn ZstandardStream(comptime ReaderType: type, comptime verify_checksum: bool } const decoded_data_len = self.buffer.len(); - var written_count: usize = 0; - while (written_count < decoded_data_len and written_count < buffer.len) : (written_count += 1) { - buffer[written_count] = self.buffer.read().?; + var count: usize = 0; + while (count < decoded_data_len and count < buffer.len) : (count += 1) { + buffer[count] = self.buffer.read().?; } if (self.state == .LastBlock and self.buffer.len() == 0) { self.state = .NewFrame; @@ -195,18 +207,22 @@ pub fn ZstandardStream(comptime ReaderType: type, comptime verify_checksum: bool self.allocator.free(self.sequence_buffer); self.buffer.deinit(self.allocator); } - return written_count; + return count; } }; } -pub fn zstandardStream(allocator: Allocator, reader: anytype) !ZstandardStream(@TypeOf(reader), true, 8 * (1 << 20)) { +pub fn zstandardStream( + allocator: Allocator, + reader: anytype, + comptime window_size_max: usize, +) ZstandardStream(@TypeOf(reader), true, window_size_max) { return ZstandardStream(@TypeOf(reader), true, 8 * (1 << 20)).init(allocator, reader); } fn testDecompress(data: []const u8) ![]u8 { var in_stream = std.io.fixedBufferStream(data); - var stream = try zstandardStream(std.testing.allocator, in_stream.reader()); + var stream = zstandardStream(std.testing.allocator, in_stream.reader(), 1 << 23); defer stream.deinit(); const result = stream.reader().readAllAlloc(std.testing.allocator, std.math.maxInt(usize)); return result; diff --git a/lib/std/compress/zstandard/RingBuffer.zig b/lib/std/compress/zstandard/RingBuffer.zig index cf70c087b6..5bd7e5d1f9 100644 --- a/lib/std/compress/zstandard/RingBuffer.zig +++ b/lib/std/compress/zstandard/RingBuffer.zig @@ -13,6 +13,8 @@ data: []u8, read_index: usize, write_index: usize, +pub const Error = error{Full}; + /// Allocate a new `RingBuffer` pub fn init(allocator: Allocator, capacity: usize) Allocator.Error!RingBuffer { const bytes = try allocator.alloc(u8, capacity); @@ -41,7 +43,7 @@ pub fn mask2(self: RingBuffer, index: usize) usize { /// Write `byte` into the ring buffer. Returns `error.Full` if the ring /// buffer is full. -pub fn write(self: *RingBuffer, byte: u8) !void { +pub fn write(self: *RingBuffer, byte: u8) Error!void { if (self.isFull()) return error.Full; self.writeAssumeCapacity(byte); } @@ -55,7 +57,7 @@ pub fn writeAssumeCapacity(self: *RingBuffer, byte: u8) void { /// Write `bytes` into the ring bufffer. Returns `error.Full` if the ring /// buffer does not have enough space, without writing any data. -pub fn writeSlice(self: *RingBuffer, bytes: []const u8) !void { +pub fn writeSlice(self: *RingBuffer, bytes: []const u8) Error!void { if (self.len() + bytes.len > self.data.len) return error.Full; self.writeSliceAssumeCapacity(bytes); } @@ -87,7 +89,8 @@ pub fn isFull(self: RingBuffer) bool { /// Returns the length pub fn len(self: RingBuffer) usize { - const adjusted_write_index = self.write_index + @as(usize, @boolToInt(self.write_index < self.read_index)) * 2 * self.data.len; + const wrap_offset = 2 * self.data.len * @boolToInt(self.write_index < self.read_index); + const adjusted_write_index = self.write_index + wrap_offset; return adjusted_write_index - self.read_index; } diff --git a/lib/std/compress/zstandard/decode/block.zig b/lib/std/compress/zstandard/decode/block.zig index af87ec694f..7cf84d3034 100644 --- a/lib/std/compress/zstandard/decode/block.zig +++ b/lib/std/compress/zstandard/decode/block.zig @@ -413,7 +413,7 @@ pub const DecodeState = struct { const DecodeLiteralsError = error{ MalformedLiteralsLength, - PrefixNotFound, + NotFound, } || LiteralBitsError; /// Decode `len` bytes of literals into `dest`. @@ -422,8 +422,8 @@ pub const DecodeState = struct { /// - `error.MalformedLiteralsLength` if the number of literal bytes /// decoded by `self` plus `len` is greater than the regenerated size of /// `literals` - /// - `error.UnexpectedEndOfLiteralStream` and `error.PrefixNotFound` if - /// there are problems decoding Huffman compressed literals + /// - `error.UnexpectedEndOfLiteralStream` and `error.NotFound` if there + /// are problems decoding Huffman compressed literals pub fn decodeLiteralsSlice( self: *DecodeState, dest: []u8, diff --git a/lib/std/compress/zstandard/decompress.zig b/lib/std/compress/zstandard/decompress.zig index 68d43c8aeb..7bcfb0a936 100644 --- a/lib/std/compress/zstandard/decompress.zig +++ b/lib/std/compress/zstandard/decompress.zig @@ -6,6 +6,8 @@ const types = @import("types.zig"); const frame = types.frame; const LiteralsSection = types.compressed_block.LiteralsSection; const SequencesSection = types.compressed_block.SequencesSection; +const SkippableHeader = types.frame.Skippable.Header; +const ZstandardHeader = types.frame.Zstandard.Header; const Table = types.compressed_block.Table; pub const block = @import("decode/block.zig"); @@ -16,15 +18,13 @@ const readers = @import("readers.zig"); const readInt = std.mem.readIntLittle; const readIntSlice = std.mem.readIntSliceLittle; -fn readVarInt(comptime T: type, bytes: []const u8) T { - return std.mem.readVarInt(T, bytes, .Little); -} +/// Returns `true` is `magic` is a valid magic number for a skippable frame pub fn isSkippableMagic(magic: u32) bool { return frame.Skippable.magic_number_min <= magic and magic <= frame.Skippable.magic_number_max; } -/// Returns the kind of frame at the beginning of `src`. +/// Returns the kind of frame at the beginning of `source`. /// /// Errors returned: /// - `error.BadMagic` if `source` begins with bytes not equal to the @@ -50,11 +50,22 @@ pub fn frameType(magic: u32) error{BadMagic}!frame.Kind { } pub const FrameHeader = union(enum) { - zstandard: types.frame.Zstandard.Header, - skippable: types.frame.Skippable.Header, + zstandard: ZstandardHeader, + skippable: SkippableHeader, }; -pub fn decodeFrameHeader(source: anytype) error{ BadMagic, EndOfStream, ReservedBitSet }!FrameHeader { +pub const HeaderError = error{ BadMagic, EndOfStream, ReservedBitSet }; + +/// Returns the header of the frame at the beginning of `source`. +/// +/// Errors returned: +/// - `error.BadMagic` if `source` begins with bytes not equal to the +/// Zstandard frame magic number, or outside the range of magic numbers for +/// skippable frames. +/// - `error.EndOfStream` if `source` contains fewer than 4 bytes +/// - `error.ReservedBitSet` if the frame is a Zstandard frame and any of the +/// reserved bits are set +pub fn decodeFrameHeader(source: anytype) HeaderError!FrameHeader { const magic = try source.readIntLittle(u32); const frame_type = try frameType(magic); switch (frame_type) { @@ -68,41 +79,74 @@ pub fn decodeFrameHeader(source: anytype) error{ BadMagic, EndOfStream, Reserved } } -const ReadWriteCount = struct { +pub const ReadWriteCount = struct { read_count: usize, write_count: usize, }; -/// Decodes frames from `src` into `dest`; see `decodeFrame()`. -pub fn decode(dest: []u8, src: []const u8, verify_checksum: bool) !usize { +/// Decodes frames from `src` into `dest`; returns the length of the result. +/// The stream should not have extra trailing bytes - either all bytes in `src` +/// will be decoded, or an error will be returned. An error will be returned if +/// a Zstandard frame in `src` does not declare its content size. +/// +/// Errors returned: +/// - `error.DictionaryIdFlagUnsupported` if a `src` contains a frame that +/// uses a dictionary +/// - `error.MalformedFrame` if a frame in `src` is invalid +/// - `error.UnknownContentSizeUnsupported` if a frame in `src` does not +/// declare its content size +pub fn decode(dest: []u8, src: []const u8, verify_checksum: bool) error{ + MalformedFrame, + UnknownContentSizeUnsupported, + DictionaryIdFlagUnsupported, +}!usize { var write_count: usize = 0; var read_count: usize = 0; while (read_count < src.len) { - const counts = try decodeFrame(dest, src[read_count..], verify_checksum); + const counts = decodeFrame(dest, src[read_count..], verify_checksum) catch |err| { + switch (err) { + error.UnknownContentSizeUnsupported => return error.UnknownContentSizeUnsupported, + error.DictionaryIdFlagUnsupported => return error.DictionaryIdFlagUnsupported, + else => return error.MalformedFrame, + } + }; read_count += counts.read_count; write_count += counts.write_count; } return write_count; } +/// Decodes a stream of frames from `src`; returns the decoded bytes. The stream +/// should not have extra trailing bytes - either all bytes in `src` will be +/// decoded, or an error will be returned. +/// +/// Errors returned: +/// - `error.DictionaryIdFlagUnsupported` if a `src` contains a frame that +/// uses a dictionary +/// - `error.MalformedFrame` if a frame in `src` is invalid +/// - `error.OutOfMemory` if `allocator` cannot allocate enough memory pub fn decodeAlloc( allocator: Allocator, src: []const u8, verify_checksum: bool, window_size_max: usize, -) ![]u8 { +) error{ DictionaryIdFlagUnsupported, MalformedFrame, OutOfMemory }![]u8 { var result = std.ArrayList(u8).init(allocator); errdefer result.deinit(); var read_count: usize = 0; while (read_count < src.len) { - read_count += try decodeFrameArrayList( + read_count += decodeFrameArrayList( allocator, &result, src[read_count..], verify_checksum, window_size_max, - ); + ) catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.DictionaryIdFlagUnsupported => return error.DictionaryIdFlagUnsupported, + else => return error.MalformedFrame, + }; } return result.toOwnedSlice(); } @@ -112,18 +156,24 @@ pub fn decodeAlloc( /// frames that declare the decompressed content size. /// /// Errors returned: +/// - `error.BadMagic` if the first 4 bytes of `src` is not a valid magic +/// number for a Zstandard or skippable frame /// - `error.UnknownContentSizeUnsupported` if the frame does not declare the /// uncompressed content size +/// - `error.WindowSizeUnknown` if the frame does not have a valid window size /// - `error.ContentTooLarge` if `dest` is smaller than the uncompressed data /// size declared by the frame header -/// - `error.BadMagic` if the first 4 bytes of `src` is not a valid magic -/// number for a Zstandard or Skippable frame +/// - `error.ContentSizeTooLarge` if the frame header indicates a content size +/// that is larger than `std.math.maxInt(usize)` /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame /// contains a checksum that does not match the checksum of the decompressed /// data -/// - `error.ReservedBitSet` if the reserved bit of the frame header is set +/// - `error.ReservedBitSet` if any of the reserved bits of the frame header +/// are set /// - `error.EndOfStream` if `src` does not contain a complete frame +/// - `error.BadContentSize` if the content size declared by the frame does +/// not equal the actual size of decompressed data /// - an error in `block.Error` if there are errors decoding a block /// - `error.SkippableSizeTooLarge` if the frame is skippable and reports a /// size greater than `src.len` @@ -131,7 +181,15 @@ pub fn decodeFrame( dest: []u8, src: []const u8, verify_checksum: bool, -) !ReadWriteCount { +) (error{ + BadMagic, + UnknownContentSizeUnsupported, + ContentTooLarge, + ContentSizeTooLarge, + WindowSizeUnknown, + DictionaryIdFlagUnsupported, + SkippableSizeTooLarge, +} || FrameError)!ReadWriteCount { var fbs = std.io.fixedBufferStream(src); switch (try decodeFrameType(fbs.reader())) { .zstandard => return decodeZstandardFrame(dest, src, verify_checksum), @@ -153,16 +211,21 @@ pub fn decodeFrame( /// /// Errors returned: /// - `error.BadMagic` if the first 4 bytes of `src` is not a valid magic -/// number for a Zstandard or Skippable frame +/// number for a Zstandard or skippable frame /// - `error.WindowSizeUnknown` if the frame does not have a valid window size /// - `error.WindowTooLarge` if the window size is larger than /// `window_size_max` +/// - `error.ContentSizeTooLarge` if the frame header indicates a content size +/// that is larger than `std.math.maxInt(usize)` /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame /// contains a checksum that does not match the checksum of the decompressed /// data -/// - `error.ReservedBitSet` if the reserved bit of the frame header is set +/// - `error.ReservedBitSet` if any of the reserved bits of the frame header +/// are set /// - `error.EndOfStream` if `src` does not contain a complete frame +/// - `error.BadContentSize` if the content size declared by the frame does +/// not equal the actual size of decompressed data /// - `error.OutOfMemory` if `allocator` cannot allocate enough memory /// - an error in `block.Error` if there are errors decoding a block /// - `error.SkippableSizeTooLarge` if the frame is skippable and reports a @@ -173,12 +236,18 @@ pub fn decodeFrameArrayList( src: []const u8, verify_checksum: bool, window_size_max: usize, -) !usize { +) (error{ BadMagic, OutOfMemory, SkippableSizeTooLarge } || FrameContext.Error || FrameError)!usize { var fbs = std.io.fixedBufferStream(src); const reader = fbs.reader(); const magic = try reader.readIntLittle(u32); switch (try frameType(magic)) { - .zstandard => return decodeZstandardFrameArrayList(allocator, dest, src, verify_checksum, window_size_max), + .zstandard => return decodeZstandardFrameArrayList( + allocator, + dest, + src, + verify_checksum, + window_size_max, + ), .skippable => { const content_size = try fbs.reader().readIntLittle(u32); if (content_size > std.math.maxInt(usize) - 8) return error.SkippableSizeTooLarge; @@ -211,7 +280,10 @@ const FrameError = error{ /// uncompressed content size /// - `error.ContentTooLarge` if `dest` is smaller than the uncompressed data /// size declared by the frame header +/// - `error.WindowSizeUnknown` if the frame does not have a valid window size /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary +/// - `error.ContentSizeTooLarge` if the frame header indicates a content size +/// that is larger than `std.math.maxInt(usize)` /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame /// contains a checksum that does not match the checksum of the decompressed /// data @@ -239,7 +311,11 @@ pub fn decodeZstandardFrame( var source = fbs.reader(); const frame_header = try decodeZstandardHeader(source); consumed_count += fbs.pos; - break :context FrameContext.init(frame_header, std.math.maxInt(usize), verify_checksum) catch |err| switch (err) { + break :context FrameContext.init( + frame_header, + std.math.maxInt(usize), + verify_checksum, + ) catch |err| switch (err) { error.WindowTooLarge => unreachable, inline else => |e| return e, }; @@ -260,7 +336,8 @@ pub fn decodeZStandardFrameBlocks( src: []const u8, frame_context: *FrameContext, ) (error{ ContentTooLarge, UnknownContentSizeUnsupported } || FrameError)!ReadWriteCount { - const content_size = frame_context.content_size orelse return error.UnknownContentSizeUnsupported; + const content_size = frame_context.content_size orelse + return error.UnknownContentSizeUnsupported; if (dest.len < content_size) return error.ContentTooLarge; var consumed_count: usize = 0; @@ -304,14 +381,19 @@ pub const FrameContext = struct { /// /// Errors returned: /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary - /// - `error.WindowSizeUnknown` if the frame does not have a valid window size - /// - `error.WindowTooLarge` if the window size is larger than `window_size_max` + /// - `error.WindowSizeUnknown` if the frame does not have a valid window + /// size + /// - `error.WindowTooLarge` if the window size is larger than + /// `window_size_max` + /// - `error.ContentSizeTooLarge` if the frame header indicates a content + /// size larger than `std.math.maxInt(usize)` pub fn init( - frame_header: frame.Zstandard.Header, + frame_header: ZstandardHeader, window_size_max: usize, verify_checksum: bool, ) Error!FrameContext { - if (frame_header.descriptor.dictionary_id_flag != 0) return error.DictionaryIdFlagUnsupported; + if (frame_header.descriptor.dictionary_id_flag != 0) + return error.DictionaryIdFlagUnsupported; const window_size_raw = frameWindowSize(frame_header) orelse return error.WindowSizeUnknown; const window_size = if (window_size_raw > window_size_max) @@ -319,7 +401,8 @@ pub const FrameContext = struct { else @intCast(usize, window_size_raw); - const should_compute_checksum = frame_header.descriptor.content_checksum_flag and verify_checksum; + const should_compute_checksum = + frame_header.descriptor.content_checksum_flag and verify_checksum; const content_size = if (frame_header.content_size) |size| std.math.cast(usize, size) orelse return error.ContentSizeTooLarge @@ -345,6 +428,8 @@ pub const FrameContext = struct { /// - `error.WindowTooLarge` if the window size is larger than /// `window_size_max` /// - `error.DictionaryIdFlagUnsupported` if the frame uses a dictionary +/// - `error.ContentSizeTooLarge` if the frame header indicates a content size +/// that is larger than `std.math.maxInt(usize)` /// - `error.ChecksumFailure` if `verify_checksum` is true and the frame /// contains a checksum that does not match the checksum of the decompressed /// data @@ -441,8 +526,6 @@ pub fn decodeZstandardFrameBlocksArrayList( return consumed_count; } -/// Convenience wrapper for decoding all blocks in a frame; see -/// `decodeZStandardFrameBlocks()`. fn decodeFrameBlocksInner( dest: []u8, src: []const u8, @@ -459,7 +542,7 @@ fn decodeFrameBlocksInner( var bytes_read: usize = 3; defer consumed_count.* += bytes_read; var decode_state = block.DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data); - var written_count: usize = 0; + var count: usize = 0; while (true) : ({ block_header = try block.decodeBlockHeaderSlice(src[bytes_read..]); bytes_read += 3; @@ -471,18 +554,18 @@ fn decodeFrameBlocksInner( &decode_state, &bytes_read, block_size_max, - written_count, + count, ); - if (hash) |hash_state| hash_state.update(dest[written_count .. written_count + written_size]); - written_count += written_size; + if (hash) |hash_state| hash_state.update(dest[count .. count + written_size]); + count += written_size; if (block_header.last_block) break; } - return written_count; + return count; } /// Decode the header of a skippable frame. The first four bytes of `src` must -/// be a valid magic number for a Skippable frame. -pub fn decodeSkippableHeader(src: *const [8]u8) frame.Skippable.Header { +/// be a valid magic number for a skippable frame. +pub fn decodeSkippableHeader(src: *const [8]u8) SkippableHeader { const magic = readInt(u32, src[0..4]); assert(isSkippableMagic(magic)); const frame_size = readInt(u32, src[4..8]); @@ -494,7 +577,7 @@ pub fn decodeSkippableHeader(src: *const [8]u8) frame.Skippable.Header { /// Returns the window size required to decompress a frame, or `null` if it /// cannot be determined (which indicates a malformed frame header). -pub fn frameWindowSize(header: frame.Zstandard.Header) ?u64 { +pub fn frameWindowSize(header: ZstandardHeader) ?u64 { if (header.window_descriptor) |descriptor| { const exponent = (descriptor & 0b11111000) >> 3; const mantissa = descriptor & 0b00000111; @@ -508,10 +591,10 @@ pub fn frameWindowSize(header: frame.Zstandard.Header) ?u64 { /// Decode the header of a Zstandard frame. /// /// Errors returned: -/// - `error.ReservedBitSet` if the reserved bits of the header are set +/// - `error.ReservedBitSet` if any of the reserved bits of the header are set /// - `error.EndOfStream` if `source` does not contain a complete header -pub fn decodeZstandardHeader(source: anytype) error{ EndOfStream, ReservedBitSet }!frame.Zstandard.Header { - const descriptor = @bitCast(frame.Zstandard.Header.Descriptor, try source.readByte()); +pub fn decodeZstandardHeader(source: anytype) error{ EndOfStream, ReservedBitSet }!ZstandardHeader { + const descriptor = @bitCast(ZstandardHeader.Descriptor, try source.readByte()); if (descriptor.reserved) return error.ReservedBitSet; @@ -534,7 +617,7 @@ pub fn decodeZstandardHeader(source: anytype) error{ EndOfStream, ReservedBitSet if (field_size == 2) content_size.? += 256; } - const header = frame.Zstandard.Header{ + const header = ZstandardHeader{ .descriptor = descriptor, .window_descriptor = window_descriptor, .dictionary_id = dictionary_id, diff --git a/lib/std/compress/zstandard/types.zig b/lib/std/compress/zstandard/types.zig index 3f61b0bab4..db4fbdee2d 100644 --- a/lib/std/compress/zstandard/types.zig +++ b/lib/std/compress/zstandard/types.zig @@ -92,13 +92,13 @@ pub const compressed_block = struct { index: usize, }; - pub fn query(self: HuffmanTree, index: usize, prefix: u16) error{PrefixNotFound}!Result { + pub fn query(self: HuffmanTree, index: usize, prefix: u16) error{NotFound}!Result { var node = self.nodes[index]; const weight = node.weight; var i: usize = index; while (node.weight == weight) { if (node.prefix == prefix) return Result{ .symbol = node.symbol }; - if (i == 0) return error.PrefixNotFound; + if (i == 0) return error.NotFound; i -= 1; node = self.nodes[i]; } @@ -164,12 +164,14 @@ pub const compressed_block = struct { }; pub const match_length_code_table = [53]struct { u32, u5 }{ - .{ 3, 0 }, .{ 4, 0 }, .{ 5, 0 }, .{ 6, 0 }, .{ 7, 0 }, .{ 8, 0 }, .{ 9, 0 }, .{ 10, 0 }, - .{ 11, 0 }, .{ 12, 0 }, .{ 13, 0 }, .{ 14, 0 }, .{ 15, 0 }, .{ 16, 0 }, .{ 17, 0 }, .{ 18, 0 }, - .{ 19, 0 }, .{ 20, 0 }, .{ 21, 0 }, .{ 22, 0 }, .{ 23, 0 }, .{ 24, 0 }, .{ 25, 0 }, .{ 26, 0 }, - .{ 27, 0 }, .{ 28, 0 }, .{ 29, 0 }, .{ 30, 0 }, .{ 31, 0 }, .{ 32, 0 }, .{ 33, 0 }, .{ 34, 0 }, - .{ 35, 1 }, .{ 37, 1 }, .{ 39, 1 }, .{ 41, 1 }, .{ 43, 2 }, .{ 47, 2 }, .{ 51, 3 }, .{ 59, 3 }, - .{ 67, 4 }, .{ 83, 4 }, .{ 99, 5 }, .{ 131, 7 }, .{ 259, 8 }, .{ 515, 9 }, .{ 1027, 10 }, .{ 2051, 11 }, + .{ 3, 0 }, .{ 4, 0 }, .{ 5, 0 }, .{ 6, 0 }, .{ 7, 0 }, .{ 8, 0 }, + .{ 9, 0 }, .{ 10, 0 }, .{ 11, 0 }, .{ 12, 0 }, .{ 13, 0 }, .{ 14, 0 }, + .{ 15, 0 }, .{ 16, 0 }, .{ 17, 0 }, .{ 18, 0 }, .{ 19, 0 }, .{ 20, 0 }, + .{ 21, 0 }, .{ 22, 0 }, .{ 23, 0 }, .{ 24, 0 }, .{ 25, 0 }, .{ 26, 0 }, + .{ 27, 0 }, .{ 28, 0 }, .{ 29, 0 }, .{ 30, 0 }, .{ 31, 0 }, .{ 32, 0 }, + .{ 33, 0 }, .{ 34, 0 }, .{ 35, 1 }, .{ 37, 1 }, .{ 39, 1 }, .{ 41, 1 }, + .{ 43, 2 }, .{ 47, 2 }, .{ 51, 3 }, .{ 59, 3 }, .{ 67, 4 }, .{ 83, 4 }, + .{ 99, 5 }, .{ 131, 7 }, .{ 259, 8 }, .{ 515, 9 }, .{ 1027, 10 }, .{ 2051, 11 }, .{ 4099, 12 }, .{ 8195, 13 }, .{ 16387, 14 }, .{ 32771, 15 }, .{ 65539, 16 }, };