Commit ee5af3c74c

dweiller <4678790+dweiller@users.noreplay.github.com>
2023-02-09 15:33:38
std.compress.zstandard: cleanup high-level api docs and error sets
1 parent 31cc460
Changed files (5)
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,
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,
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;
 }
 
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 },
     };
 
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;