| author | |
| committer | |
| log | 646454beb5026ba50ae6bf4d75d018d1c67fe77a |
| tree | ac314609e1a7af58fe5ba2e7b2fe5224dfa5e404 |
| parent | faab6d5cbf18d25628793994e080f79d95adf4ea |
13 files changed, 123 insertions(+), 177 deletions(-)
lib/std/Uri.zig+28-29| ... | @@ -40,22 +40,17 @@ pub const Component = union(enum) { | ... | @@ -40,22 +40,17 @@ pub const Component = union(enum) { |
| 40 | }; | 40 | }; |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | pub fn format( | 43 | pub fn format(component: Component, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!usize { |
| 44 | component: Component, | 44 | var n: usize = 0; |
| 45 | comptime fmt: []const u8, | ||
| 46 | options: std.fmt.Options, | ||
| 47 | writer: *std.io.BufferedWriter, | ||
| 48 | ) anyerror!void { | ||
| 49 | _ = options; | ||
| 50 | if (fmt.len == 0) { | 45 | if (fmt.len == 0) { |
| 51 | try writer.print("std.Uri.Component{{ .{s} = \"{}\" }}", .{ | 46 | n += try bw.printCount("std.Uri.Component{{ .{s} = \"{}\" }}", .{ |
| 52 | @tagName(component), | 47 | @tagName(component), |
| 53 | std.zig.fmtEscapes(switch (component) { | 48 | std.zig.fmtEscapes(switch (component) { |
| 54 | .raw, .percent_encoded => |string| string, | 49 | .raw, .percent_encoded => |string| string, |
| 55 | }), | 50 | }), |
| 56 | }); | 51 | }); |
| 57 | } else if (comptime std.mem.eql(u8, fmt, "raw")) switch (component) { | 52 | } else if (comptime std.mem.eql(u8, fmt, "raw")) switch (component) { |
| 58 | .raw => |raw| try writer.writeAll(raw), | 53 | .raw => |raw| n += try bw.writeAllCount(raw), |
| 59 | .percent_encoded => |percent_encoded| { | 54 | .percent_encoded => |percent_encoded| { |
| 60 | var start: usize = 0; | 55 | var start: usize = 0; |
| 61 | var index: usize = 0; | 56 | var index: usize = 0; |
| ... | @@ -64,51 +59,55 @@ pub const Component = union(enum) { | ... | @@ -64,51 +59,55 @@ pub const Component = union(enum) { |
| 64 | if (percent_encoded.len - index < 2) continue; | 59 | if (percent_encoded.len - index < 2) continue; |
| 65 | const percent_encoded_char = | 60 | const percent_encoded_char = |
| 66 | std.fmt.parseInt(u8, percent_encoded[index..][0..2], 16) catch continue; | 61 | std.fmt.parseInt(u8, percent_encoded[index..][0..2], 16) catch continue; |
| 67 | try writer.print("{s}{c}", .{ | 62 | n += try bw.printCount("{s}{c}", .{ |
| 68 | percent_encoded[start..percent], | 63 | percent_encoded[start..percent], |
| 69 | percent_encoded_char, | 64 | percent_encoded_char, |
| 70 | }); | 65 | }); |
| 71 | start = percent + 3; | 66 | start = percent + 3; |
| 72 | index = percent + 3; | 67 | index = percent + 3; |
| 73 | } | 68 | } |
| 74 | try writer.writeAll(percent_encoded[start..]); | 69 | n += try bw.writeAllCount(percent_encoded[start..]); |
| 75 | }, | 70 | }, |
| 76 | } else if (comptime std.mem.eql(u8, fmt, "%")) switch (component) { | 71 | } else if (comptime std.mem.eql(u8, fmt, "%")) switch (component) { |
| 77 | .raw => |raw| try percentEncode(writer, raw, isUnreserved), | 72 | .raw => |raw| n += try percentEncode(bw, raw, isUnreserved), |
| 78 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 73 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 79 | } else if (comptime std.mem.eql(u8, fmt, "user")) switch (component) { | 74 | } else if (comptime std.mem.eql(u8, fmt, "user")) switch (component) { |
| 80 | .raw => |raw| try percentEncode(writer, raw, isUserChar), | 75 | .raw => |raw| n += try percentEncode(bw, raw, isUserChar), |
| 81 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 76 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 82 | } else if (comptime std.mem.eql(u8, fmt, "password")) switch (component) { | 77 | } else if (comptime std.mem.eql(u8, fmt, "password")) switch (component) { |
| 83 | .raw => |raw| try percentEncode(writer, raw, isPasswordChar), | 78 | .raw => |raw| n += try percentEncode(bw, raw, isPasswordChar), |
| 84 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 79 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 85 | } else if (comptime std.mem.eql(u8, fmt, "host")) switch (component) { | 80 | } else if (comptime std.mem.eql(u8, fmt, "host")) switch (component) { |
| 86 | .raw => |raw| try percentEncode(writer, raw, isHostChar), | 81 | .raw => |raw| n += try percentEncode(bw, raw, isHostChar), |
| 87 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 82 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 88 | } else if (comptime std.mem.eql(u8, fmt, "path")) switch (component) { | 83 | } else if (comptime std.mem.eql(u8, fmt, "path")) switch (component) { |
| 89 | .raw => |raw| try percentEncode(writer, raw, isPathChar), | 84 | .raw => |raw| n += try percentEncode(bw, raw, isPathChar), |
| 90 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 85 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 91 | } else if (comptime std.mem.eql(u8, fmt, "query")) switch (component) { | 86 | } else if (comptime std.mem.eql(u8, fmt, "query")) switch (component) { |
| 92 | .raw => |raw| try percentEncode(writer, raw, isQueryChar), | 87 | .raw => |raw| n += try percentEncode(bw, raw, isQueryChar), |
| 93 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 88 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 94 | } else if (comptime std.mem.eql(u8, fmt, "fragment")) switch (component) { | 89 | } else if (comptime std.mem.eql(u8, fmt, "fragment")) switch (component) { |
| 95 | .raw => |raw| try percentEncode(writer, raw, isFragmentChar), | 90 | .raw => |raw| n += try percentEncode(bw, raw, isFragmentChar), |
| 96 | .percent_encoded => |percent_encoded| try writer.writeAll(percent_encoded), | 91 | .percent_encoded => |percent_encoded| n += try bw.writeAllCount(percent_encoded), |
| 97 | } else @compileError("invalid format string '" ++ fmt ++ "'"); | 92 | } else @compileError("invalid format string '" ++ fmt ++ "'"); |
| 93 | |||
| 94 | return n; | ||
| 98 | } | 95 | } |
| 99 | 96 | ||
| 100 | pub fn percentEncode( | 97 | pub fn percentEncode( |
| 101 | writer: *std.io.BufferedWriter, | 98 | bw: *std.io.BufferedWriter, |
| 102 | raw: []const u8, | 99 | raw: []const u8, |
| 103 | comptime isValidChar: fn (u8) bool, | 100 | comptime isValidChar: fn (u8) bool, |
| 104 | ) anyerror!void { | 101 | ) anyerror!usize { |
| 102 | var n: usize = 0; | ||
| 105 | var start: usize = 0; | 103 | var start: usize = 0; |
| 106 | for (raw, 0..) |char, index| { | 104 | for (raw, 0..) |char, index| { |
| 107 | if (isValidChar(char)) continue; | 105 | if (isValidChar(char)) continue; |
| 108 | try writer.print("{s}%{X:0>2}", .{ raw[start..index], char }); | 106 | n += try bw.printCount("{s}%{X:0>2}", .{ raw[start..index], char }); |
| 109 | start = index + 1; | 107 | start = index + 1; |
| 110 | } | 108 | } |
| 111 | try writer.writeAll(raw[start..]); | 109 | n += try bw.writeAllCount(raw[start..]); |
| 110 | return n; | ||
| 112 | } | 111 | } |
| 113 | }; | 112 | }; |
| 114 | 113 |
lib/std/builtin.zig+12-14| ... | @@ -34,28 +34,26 @@ pub const StackTrace = struct { | ... | @@ -34,28 +34,26 @@ pub const StackTrace = struct { |
| 34 | index: usize, | 34 | index: usize, |
| 35 | instruction_addresses: []usize, | 35 | instruction_addresses: []usize, |
| 36 | 36 | ||
| 37 | pub fn format( | 37 | pub fn format(st: StackTrace, bw: *std.io.BufferedWriter, comptime fmt: []const u8) anyerror!usize { |
| 38 | self: StackTrace, | 38 | comptime std.debug.assert(fmt.len == 0); |
| 39 | comptime fmt: []const u8, | ||
| 40 | options: std.fmt.FormatOptions, | ||
| 41 | writer: anytype, | ||
| 42 | ) !void { | ||
| 43 | if (fmt.len != 0) std.fmt.invalidFmtError(fmt, self); | ||
| 44 | 39 | ||
| 45 | // TODO: re-evaluate whether to use format() methods at all. | 40 | // TODO: re-evaluate whether to use format() methods at all. |
| 46 | // Until then, avoid an error when using GeneralPurposeAllocator with WebAssembly | 41 | // Until then, avoid an error when using DebugAllocator with WebAssembly |
| 47 | // where it tries to call detectTTYConfig here. | 42 | // where it tries to call detectTTYConfig here. |
| 48 | if (builtin.os.tag == .freestanding) return; | 43 | if (builtin.os.tag == .freestanding) return 0; |
| 49 | 44 | ||
| 50 | _ = options; | ||
| 51 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { | 45 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { |
| 52 | return writer.print("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}); | 46 | return bw.printCount("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{ |
| 47 | @errorName(err), | ||
| 48 | }); | ||
| 53 | }; | 49 | }; |
| 54 | const tty_config = std.io.tty.detectConfig(.stderr()); | 50 | const tty_config = std.io.tty.detectConfig(.stderr()); |
| 55 | try writer.writeAll("\n"); | 51 | var n: usize = 0; |
| 56 | std.debug.writeStackTrace(self, writer, debug_info, tty_config) catch |err| { | 52 | n += try bw.writeAllCount("\n"); |
| 57 | try writer.print("Unable to print stack trace: {s}\n", .{@errorName(err)}); | 53 | n += std.debug.writeStackTrace(st, bw, debug_info, tty_config) catch |err| { |
| 54 | try bw.print("Unable to print stack trace: {s}\n", .{@errorName(err)}); | ||
| 58 | }; | 55 | }; |
| 56 | return n; | ||
| 59 | } | 57 | } |
| 60 | }; | 58 | }; |
| 61 | 59 |
lib/std/compress/gzip.zig+9-36| ... | @@ -1,66 +1,39 @@ | ... | @@ -1,66 +1,39 @@ |
| 1 | const std = @import("../std.zig"); | ||
| 1 | const deflate = @import("flate/deflate.zig"); | 2 | const deflate = @import("flate/deflate.zig"); |
| 2 | const inflate = @import("flate/inflate.zig"); | 3 | const inflate = @import("flate/inflate.zig"); |
| 3 | 4 | ||
| 4 | /// Decompress compressed data from reader and write plain data to the writer. | 5 | /// Decompress compressed data from reader and write plain data to the writer. |
| 5 | pub fn decompress(reader: anytype, writer: anytype) !void { | 6 | pub fn decompress(reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { |
| 6 | try inflate.decompress(.gzip, reader, writer); | 7 | try inflate.decompress(.gzip, reader, writer); |
| 7 | } | 8 | } |
| 8 | 9 | ||
| 9 | /// Decompressor type | 10 | pub const Decompressor = inflate.Decompressor(.gzip); |
| 10 | pub fn Decompressor(comptime ReaderType: type) type { | ||
| 11 | return inflate.Decompressor(.gzip, ReaderType); | ||
| 12 | } | ||
| 13 | |||
| 14 | /// Create Decompressor which will read compressed data from reader. | ||
| 15 | pub fn decompressor(reader: anytype) Decompressor(@TypeOf(reader)) { | ||
| 16 | return inflate.decompressor(.gzip, reader); | ||
| 17 | } | ||
| 18 | 11 | ||
| 19 | /// Compression level, trades between speed and compression size. | 12 | /// Compression level, trades between speed and compression size. |
| 20 | pub const Options = deflate.Options; | 13 | pub const Options = deflate.Options; |
| 21 | 14 | ||
| 22 | /// Compress plain data from reader and write compressed data to the writer. | 15 | /// Compress plain data from reader and write compressed data to the writer. |
| 23 | pub fn compress(reader: anytype, writer: anytype, options: Options) !void { | 16 | pub fn compress(reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter, options: Options) !void { |
| 24 | try deflate.compress(.gzip, reader, writer, options); | 17 | try deflate.compress(.gzip, reader, writer, options); |
| 25 | } | 18 | } |
| 26 | 19 | ||
| 27 | /// Compressor type | 20 | pub const Compressor = deflate.Compressor(.gzip); |
| 28 | pub fn Compressor(comptime WriterType: type) type { | ||
| 29 | return deflate.Compressor(.gzip, WriterType); | ||
| 30 | } | ||
| 31 | |||
| 32 | /// Create Compressor which outputs compressed data to the writer. | ||
| 33 | pub fn compressor(writer: anytype, options: Options) !Compressor(@TypeOf(writer)) { | ||
| 34 | return try deflate.compressor(.gzip, writer, options); | ||
| 35 | } | ||
| 36 | 21 | ||
| 37 | /// Huffman only compression. Without Lempel-Ziv match searching. Faster | 22 | /// Huffman only compression. Without Lempel-Ziv match searching. Faster |
| 38 | /// compression, less memory requirements but bigger compressed sizes. | 23 | /// compression, less memory requirements but bigger compressed sizes. |
| 39 | pub const huffman = struct { | 24 | pub const huffman = struct { |
| 40 | pub fn compress(reader: anytype, writer: anytype) !void { | 25 | pub fn compress(reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { |
| 41 | try deflate.huffman.compress(.gzip, reader, writer); | 26 | try deflate.huffman.compress(.gzip, reader, writer); |
| 42 | } | 27 | } |
| 43 | 28 | ||
| 44 | pub fn Compressor(comptime WriterType: type) type { | 29 | pub const Compressor = deflate.huffman.Compressor(.gzip); |
| 45 | return deflate.huffman.Compressor(.gzip, WriterType); | ||
| 46 | } | ||
| 47 | |||
| 48 | pub fn compressor(writer: anytype) !huffman.Compressor(@TypeOf(writer)) { | ||
| 49 | return deflate.huffman.compressor(.gzip, writer); | ||
| 50 | } | ||
| 51 | }; | 30 | }; |
| 52 | 31 | ||
| 53 | // No compression store only. Compressed size is slightly bigger than plain. | 32 | // No compression store only. Compressed size is slightly bigger than plain. |
| 54 | pub const store = struct { | 33 | pub const store = struct { |
| 55 | pub fn compress(reader: anytype, writer: anytype) !void { | 34 | pub fn compress(reader: *std.io.BufferedReader, writer: *std.io.BufferedWriter) !void { |
| 56 | try deflate.store.compress(.gzip, reader, writer); | 35 | try deflate.store.compress(.gzip, reader, writer); |
| 57 | } | 36 | } |
| 58 | 37 | ||
| 59 | pub fn Compressor(comptime WriterType: type) type { | 38 | pub const Compressor = deflate.store.Compressor(.gzip); |
| 60 | return deflate.store.Compressor(.gzip, WriterType); | ||
| 61 | } | ||
| 62 | |||
| 63 | pub fn compressor(writer: anytype) !store.Compressor(@TypeOf(writer)) { | ||
| 64 | return deflate.store.compressor(.gzip, writer); | ||
| 65 | } | ||
| 66 | }; | 39 | }; |
lib/std/compress/zstandard.zig+19-25| ... | @@ -7,21 +7,10 @@ pub const compressed_block = types.compressed_block; | ... | @@ -7,21 +7,10 @@ pub const compressed_block = types.compressed_block; |
| 7 | 7 | ||
| 8 | pub const decompress = @import("zstandard/decompress.zig"); | 8 | pub const decompress = @import("zstandard/decompress.zig"); |
| 9 | 9 | ||
| 10 | pub const DecompressorOptions = struct { | ||
| 11 | verify_checksum: bool = true, | ||
| 12 | window_buffer: []u8, | ||
| 13 | |||
| 14 | /// Recommended amount by the standard. Lower than this may result | ||
| 15 | /// in inability to decompress common streams. | ||
| 16 | pub const default_window_buffer_len = 8 * 1024 * 1024; | ||
| 17 | }; | ||
| 18 | |||
| 19 | pub const Decompressor = struct { | 10 | pub const Decompressor = struct { |
| 20 | const Self = @This(); | ||
| 21 | |||
| 22 | const table_size_max = types.compressed_block.table_size_max; | 11 | const table_size_max = types.compressed_block.table_size_max; |
| 23 | 12 | ||
| 24 | source: std.io.CountingReader, | 13 | source: *std.io.BufferedReader, |
| 25 | state: enum { NewFrame, InFrame, LastBlock }, | 14 | state: enum { NewFrame, InFrame, LastBlock }, |
| 26 | decode_state: decompress.block.DecodeState, | 15 | decode_state: decompress.block.DecodeState, |
| 27 | frame_context: decompress.FrameContext, | 16 | frame_context: decompress.FrameContext, |
| ... | @@ -35,6 +24,15 @@ pub const Decompressor = struct { | ... | @@ -35,6 +24,15 @@ pub const Decompressor = struct { |
| 35 | checksum: ?u32, | 24 | checksum: ?u32, |
| 36 | current_frame_decompressed_size: usize, | 25 | current_frame_decompressed_size: usize, |
| 37 | 26 | ||
| 27 | pub const Options = struct { | ||
| 28 | verify_checksum: bool = true, | ||
| 29 | window_buffer: []u8, | ||
| 30 | |||
| 31 | /// Recommended amount by the standard. Lower than this may result | ||
| 32 | /// in inability to decompress common streams. | ||
| 33 | pub const default_window_buffer_len = 8 * 1024 * 1024; | ||
| 34 | }; | ||
| 35 | |||
| 38 | const WindowBuffer = struct { | 36 | const WindowBuffer = struct { |
| 39 | data: []u8 = undefined, | 37 | data: []u8 = undefined, |
| 40 | read_index: usize = 0, | 38 | read_index: usize = 0, |
| ... | @@ -49,9 +47,9 @@ pub const Decompressor = struct { | ... | @@ -49,9 +47,9 @@ pub const Decompressor = struct { |
| 49 | OutOfMemory, | 47 | OutOfMemory, |
| 50 | }; | 48 | }; |
| 51 | 49 | ||
| 52 | pub fn init(source: *std.io.BufferedReader, options: DecompressorOptions) Self { | 50 | pub fn init(source: *std.io.BufferedReader, options: Options) Decompressor { |
| 53 | return .{ | 51 | return .{ |
| 54 | .source = std.io.countingReader(source), | 52 | .source = source, |
| 55 | .state = .NewFrame, | 53 | .state = .NewFrame, |
| 56 | .decode_state = undefined, | 54 | .decode_state = undefined, |
| 57 | .frame_context = undefined, | 55 | .frame_context = undefined, |
| ... | @@ -67,7 +65,7 @@ pub const Decompressor = struct { | ... | @@ -67,7 +65,7 @@ pub const Decompressor = struct { |
| 67 | }; | 65 | }; |
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | fn frameInit(self: *Self) !void { | 68 | fn frameInit(self: *Decompressor) !void { |
| 71 | const source_reader = self.source; | 69 | const source_reader = self.source; |
| 72 | switch (try decompress.decodeFrameHeader(source_reader)) { | 70 | switch (try decompress.decodeFrameHeader(source_reader)) { |
| 73 | .skippable => |header| { | 71 | .skippable => |header| { |
| ... | @@ -98,11 +96,11 @@ pub const Decompressor = struct { | ... | @@ -98,11 +96,11 @@ pub const Decompressor = struct { |
| 98 | } | 96 | } |
| 99 | } | 97 | } |
| 100 | 98 | ||
| 101 | pub fn reader(self: *Self) std.io.Reader { | 99 | pub fn reader(self: *Decompressor) std.io.Reader { |
| 102 | return .{ .context = self }; | 100 | return .{ .context = self }; |
| 103 | } | 101 | } |
| 104 | 102 | ||
| 105 | pub fn read(self: *Self, buffer: []u8) Error!usize { | 103 | pub fn read(self: *Decompressor, buffer: []u8) Error!usize { |
| 106 | if (buffer.len == 0) return 0; | 104 | if (buffer.len == 0) return 0; |
| 107 | 105 | ||
| 108 | var size: usize = 0; | 106 | var size: usize = 0; |
| ... | @@ -123,7 +121,7 @@ pub const Decompressor = struct { | ... | @@ -123,7 +121,7 @@ pub const Decompressor = struct { |
| 123 | return size; | 121 | return size; |
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | fn readInner(self: *Self, buffer: []u8) Error!usize { | 124 | fn readInner(self: *Decompressor, buffer: []u8) Error!usize { |
| 127 | std.debug.assert(self.state != .NewFrame); | 125 | std.debug.assert(self.state != .NewFrame); |
| 128 | 126 | ||
| 129 | var ring_buffer = RingBuffer{ | 127 | var ring_buffer = RingBuffer{ |
| ... | @@ -198,16 +196,12 @@ pub const Decompressor = struct { | ... | @@ -198,16 +196,12 @@ pub const Decompressor = struct { |
| 198 | } | 196 | } |
| 199 | }; | 197 | }; |
| 200 | 198 | ||
| 201 | pub fn decompressor(reader: anytype, options: DecompressorOptions) Decompressor(@TypeOf(reader)) { | ||
| 202 | return Decompressor(@TypeOf(reader)).init(reader, options); | ||
| 203 | } | ||
| 204 | |||
| 205 | fn testDecompress(data: []const u8) ![]u8 { | 199 | fn testDecompress(data: []const u8) ![]u8 { |
| 206 | const window_buffer = try std.testing.allocator.alloc(u8, 1 << 23); | 200 | const window_buffer = try std.testing.allocator.alloc(u8, 1 << 23); |
| 207 | defer std.testing.allocator.free(window_buffer); | 201 | defer std.testing.allocator.free(window_buffer); |
| 208 | 202 | ||
| 209 | var in_stream = std.io.fixedBufferStream(data); | 203 | var in_stream = std.io.fixedBufferStream(data); |
| 210 | var zstd_stream = decompressor(in_stream.reader(), .{ .window_buffer = window_buffer }); | 204 | var zstd_stream: Decompressor = .init(in_stream.reader(), .{ .window_buffer = window_buffer }); |
| 211 | const result = zstd_stream.reader().readAllAlloc(std.testing.allocator, std.math.maxInt(usize)); | 205 | const result = zstd_stream.reader().readAllAlloc(std.testing.allocator, std.math.maxInt(usize)); |
| 212 | return result; | 206 | return result; |
| 213 | } | 207 | } |
| ... | @@ -260,7 +254,7 @@ fn expectEqualDecodedStreaming(expected: []const u8, input: []const u8) !void { | ... | @@ -260,7 +254,7 @@ fn expectEqualDecodedStreaming(expected: []const u8, input: []const u8) !void { |
| 260 | defer std.testing.allocator.free(window_buffer); | 254 | defer std.testing.allocator.free(window_buffer); |
| 261 | 255 | ||
| 262 | var in_stream = std.io.fixedBufferStream(input); | 256 | var in_stream = std.io.fixedBufferStream(input); |
| 263 | var stream = decompressor(in_stream.reader(), .{ .window_buffer = window_buffer }); | 257 | var stream: Decompressor = .init(in_stream.reader(), .{ .window_buffer = window_buffer }); |
| 264 | 258 | ||
| 265 | const result = try stream.reader().readAllAlloc(std.testing.allocator, std.math.maxInt(usize)); | 259 | const result = try stream.reader().readAllAlloc(std.testing.allocator, std.math.maxInt(usize)); |
| 266 | defer std.testing.allocator.free(result); | 260 | defer std.testing.allocator.free(result); |
| ... | @@ -299,7 +293,7 @@ test "declared raw literals size too large" { | ... | @@ -299,7 +293,7 @@ test "declared raw literals size too large" { |
| 299 | 293 | ||
| 300 | var fbs = std.io.fixedBufferStream(input_raw); | 294 | var fbs = std.io.fixedBufferStream(input_raw); |
| 301 | var window: [1024]u8 = undefined; | 295 | var window: [1024]u8 = undefined; |
| 302 | var stream = decompressor(fbs.reader(), .{ .window_buffer = &window }); | 296 | var stream: Decompressor = .init(fbs.reader(), .{ .window_buffer = &window }); |
| 303 | 297 | ||
| 304 | var buf: [1024]u8 = undefined; | 298 | var buf: [1024]u8 = undefined; |
| 305 | try std.testing.expectError(error.MalformedBlock, stream.read(&buf)); | 299 | try std.testing.expectError(error.MalformedBlock, stream.read(&buf)); |
lib/std/compress/zstandard/decompress.zig+3-1| ... | @@ -629,5 +629,7 @@ pub fn decodeZstandardHeader( | ... | @@ -629,5 +629,7 @@ pub fn decodeZstandardHeader( |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | test { | 631 | test { |
| 632 | std.testing.refAllDecls(@This()); | 632 | _ = types; |
| 633 | _ = block; | ||
| 634 | _ = readers; | ||
| 633 | } | 635 | } |
lib/std/compress/zstandard/readers.zig+3-23| ... | @@ -31,11 +31,11 @@ pub const ReversedByteReader = struct { | ... | @@ -31,11 +31,11 @@ pub const ReversedByteReader = struct { |
| 31 | /// FSE compressed data. | 31 | /// FSE compressed data. |
| 32 | pub const ReverseBitReader = struct { | 32 | pub const ReverseBitReader = struct { |
| 33 | byte_reader: ReversedByteReader, | 33 | byte_reader: ReversedByteReader, |
| 34 | bit_reader: std.io.BitReader(.big, ReversedByteReader.Reader), | 34 | bit_reader: std.io.BitReader(.big), |
| 35 | 35 | ||
| 36 | pub fn init(self: *ReverseBitReader, bytes: []const u8) error{BitStreamHasNoStartBit}!void { | 36 | pub fn init(self: *ReverseBitReader, bytes: []const u8) error{BitStreamHasNoStartBit}!void { |
| 37 | self.byte_reader = ReversedByteReader.init(bytes); | 37 | self.byte_reader = ReversedByteReader.init(bytes); |
| 38 | self.bit_reader = std.io.bitReader(.big, self.byte_reader.reader()); | 38 | self.bit_reader = .init(self.byte_reader.reader()); |
| 39 | if (bytes.len == 0) return; | 39 | if (bytes.len == 0) return; |
| 40 | var i: usize = 0; | 40 | var i: usize = 0; |
| 41 | while (i < 8 and 0 == self.readBitsNoEof(u1, 1) catch unreachable) : (i += 1) {} | 41 | while (i < 8 and 0 == self.readBitsNoEof(u1, 1) catch unreachable) : (i += 1) {} |
| ... | @@ -59,24 +59,4 @@ pub const ReverseBitReader = struct { | ... | @@ -59,24 +59,4 @@ pub const ReverseBitReader = struct { |
| 59 | } | 59 | } |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | pub fn BitReader(comptime Reader: type) type { | 62 | pub const BitReader = std.io.BitReader(.little); |
| 63 | return struct { | ||
| 64 | underlying: std.io.BitReader(.little, Reader), | ||
| 65 | |||
| 66 | pub fn readBitsNoEof(self: *@This(), comptime U: type, num_bits: u16) !U { | ||
| 67 | return self.underlying.readBitsNoEof(U, num_bits); | ||
| 68 | } | ||
| 69 | |||
| 70 | pub fn readBits(self: *@This(), comptime U: type, num_bits: u16, out_bits: *u16) !U { | ||
| 71 | return self.underlying.readBits(U, num_bits, out_bits); | ||
| 72 | } | ||
| 73 | |||
| 74 | pub fn alignToByte(self: *@This()) void { | ||
| 75 | self.underlying.alignToByte(); | ||
| 76 | } | ||
| 77 | }; | ||
| 78 | } | ||
| 79 | |||
| 80 | pub fn bitReader(reader: anytype) BitReader(@TypeOf(reader)) { | ||
| 81 | return .{ .underlying = std.io.bitReader(.little, reader) }; | ||
| 82 | } |
lib/std/debug.zig+13-6| ... | @@ -733,26 +733,28 @@ pub fn writeStackTrace( | ... | @@ -733,26 +733,28 @@ pub fn writeStackTrace( |
| 733 | writer: *std.io.BufferedWriter, | 733 | writer: *std.io.BufferedWriter, |
| 734 | debug_info: *SelfInfo, | 734 | debug_info: *SelfInfo, |
| 735 | tty_config: io.tty.Config, | 735 | tty_config: io.tty.Config, |
| 736 | ) !void { | 736 | ) !usize { |
| 737 | if (builtin.strip_debug_info) return error.MissingDebugInfo; | 737 | if (builtin.strip_debug_info) return error.MissingDebugInfo; |
| 738 | var frame_index: usize = 0; | 738 | var frame_index: usize = 0; |
| 739 | var frames_left: usize = @min(stack_trace.index, stack_trace.instruction_addresses.len); | 739 | var frames_left: usize = @min(stack_trace.index, stack_trace.instruction_addresses.len); |
| 740 | var n: usize = 0; | ||
| 740 | 741 | ||
| 741 | while (frames_left != 0) : ({ | 742 | while (frames_left != 0) : ({ |
| 742 | frames_left -= 1; | 743 | frames_left -= 1; |
| 743 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; | 744 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; |
| 744 | }) { | 745 | }) { |
| 745 | const return_address = stack_trace.instruction_addresses[frame_index]; | 746 | const return_address = stack_trace.instruction_addresses[frame_index]; |
| 746 | try printSourceAtAddress(debug_info, writer, return_address - 1, tty_config); | 747 | n += try printSourceAtAddress(debug_info, writer, return_address - 1, tty_config); |
| 747 | } | 748 | } |
| 748 | 749 | ||
| 749 | if (stack_trace.index > stack_trace.instruction_addresses.len) { | 750 | if (stack_trace.index > stack_trace.instruction_addresses.len) { |
| 750 | const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len; | 751 | const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len; |
| 751 | 752 | ||
| 752 | tty_config.setColor(writer, .bold) catch {}; | 753 | n += tty_config.setColor(writer, .bold) catch {}; |
| 753 | try writer.print("({d} additional stack frames skipped...)\n", .{dropped_frames}); | 754 | n += try writer.printCount("({d} additional stack frames skipped...)\n", .{dropped_frames}); |
| 754 | tty_config.setColor(writer, .reset) catch {}; | 755 | n += tty_config.setColor(writer, .reset) catch {}; |
| 755 | } | 756 | } |
| 757 | return n; | ||
| 756 | } | 758 | } |
| 757 | 759 | ||
| 758 | pub const UnwindError = if (have_ucontext) | 760 | pub const UnwindError = if (have_ucontext) |
| ... | @@ -1100,7 +1102,12 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre | ... | @@ -1100,7 +1102,12 @@ fn printUnwindError(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, addre |
| 1100 | try tty_config.setColor(writer, .reset); | 1102 | try tty_config.setColor(writer, .reset); |
| 1101 | } | 1103 | } |
| 1102 | 1104 | ||
| 1103 | pub fn printSourceAtAddress(debug_info: *SelfInfo, writer: *std.io.BufferedWriter, address: usize, tty_config: io.tty.Config) !void { | 1105 | pub fn printSourceAtAddress( |
| 1106 | debug_info: *SelfInfo, | ||
| 1107 | writer: *std.io.BufferedWriter, | ||
| 1108 | address: usize, | ||
| 1109 | tty_config: io.tty.Config, | ||
| 1110 | ) !void { | ||
| 1104 | const module = debug_info.getModuleForAddress(address) catch |err| switch (err) { | 1111 | const module = debug_info.getModuleForAddress(address) catch |err| switch (err) { |
| 1105 | error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config), | 1112 | error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, writer, address, tty_config), |
| 1106 | else => return err, | 1113 | else => return err, |
lib/std/heap/debug_allocator.zig+9-9| ... | @@ -436,7 +436,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -436,7 +436,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 436 | const stack_trace = bucketStackTrace(bucket, slot_count, slot_index, .alloc); | 436 | const stack_trace = bucketStackTrace(bucket, slot_count, slot_index, .alloc); |
| 437 | const page_addr = @intFromPtr(bucket) & ~(page_size - 1); | 437 | const page_addr = @intFromPtr(bucket) & ~(page_size - 1); |
| 438 | const addr = page_addr + slot_index * size_class; | 438 | const addr = page_addr + slot_index * size_class; |
| 439 | log.err("memory address 0x{x} leaked: {}", .{ addr, stack_trace }); | 439 | log.err("memory address 0x{x} leaked: {f}", .{ addr, stack_trace }); |
| 440 | leaks = true; | 440 | leaks = true; |
| 441 | } | 441 | } |
| 442 | } | 442 | } |
| ... | @@ -463,7 +463,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -463,7 +463,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 463 | while (it.next()) |large_alloc| { | 463 | while (it.next()) |large_alloc| { |
| 464 | if (config.retain_metadata and large_alloc.freed) continue; | 464 | if (config.retain_metadata and large_alloc.freed) continue; |
| 465 | const stack_trace = large_alloc.getStackTrace(.alloc); | 465 | const stack_trace = large_alloc.getStackTrace(.alloc); |
| 466 | log.err("memory address 0x{x} leaked: {}", .{ | 466 | log.err("memory address 0x{x} leaked: {f}", .{ |
| 467 | @intFromPtr(large_alloc.bytes.ptr), stack_trace, | 467 | @intFromPtr(large_alloc.bytes.ptr), stack_trace, |
| 468 | }); | 468 | }); |
| 469 | leaks = true; | 469 | leaks = true; |
| ... | @@ -522,7 +522,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -522,7 +522,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 522 | .index = 0, | 522 | .index = 0, |
| 523 | }; | 523 | }; |
| 524 | std.debug.captureStackTrace(ret_addr, &second_free_stack_trace); | 524 | std.debug.captureStackTrace(ret_addr, &second_free_stack_trace); |
| 525 | log.err("Double free detected. Allocation: {} First free: {} Second free: {}", .{ | 525 | log.err("Double free detected. Allocation: {f} First free: {f} Second free: {f}", .{ |
| 526 | alloc_stack_trace, free_stack_trace, second_free_stack_trace, | 526 | alloc_stack_trace, free_stack_trace, second_free_stack_trace, |
| 527 | }); | 527 | }); |
| 528 | } | 528 | } |
| ... | @@ -568,7 +568,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -568,7 +568,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 568 | .index = 0, | 568 | .index = 0, |
| 569 | }; | 569 | }; |
| 570 | std.debug.captureStackTrace(ret_addr, &free_stack_trace); | 570 | std.debug.captureStackTrace(ret_addr, &free_stack_trace); |
| 571 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {} Free: {}", .{ | 571 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 572 | entry.value_ptr.bytes.len, | 572 | entry.value_ptr.bytes.len, |
| 573 | old_mem.len, | 573 | old_mem.len, |
| 574 | entry.value_ptr.getStackTrace(.alloc), | 574 | entry.value_ptr.getStackTrace(.alloc), |
| ... | @@ -678,7 +678,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -678,7 +678,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 678 | .index = 0, | 678 | .index = 0, |
| 679 | }; | 679 | }; |
| 680 | std.debug.captureStackTrace(ret_addr, &free_stack_trace); | 680 | std.debug.captureStackTrace(ret_addr, &free_stack_trace); |
| 681 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {} Free: {}", .{ | 681 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 682 | entry.value_ptr.bytes.len, | 682 | entry.value_ptr.bytes.len, |
| 683 | old_mem.len, | 683 | old_mem.len, |
| 684 | entry.value_ptr.getStackTrace(.alloc), | 684 | entry.value_ptr.getStackTrace(.alloc), |
| ... | @@ -907,7 +907,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -907,7 +907,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 907 | }; | 907 | }; |
| 908 | std.debug.captureStackTrace(return_address, &free_stack_trace); | 908 | std.debug.captureStackTrace(return_address, &free_stack_trace); |
| 909 | if (old_memory.len != requested_size) { | 909 | if (old_memory.len != requested_size) { |
| 910 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {} Free: {}", .{ | 910 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 911 | requested_size, | 911 | requested_size, |
| 912 | old_memory.len, | 912 | old_memory.len, |
| 913 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), | 913 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), |
| ... | @@ -915,7 +915,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -915,7 +915,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 915 | }); | 915 | }); |
| 916 | } | 916 | } |
| 917 | if (alignment != slot_alignment) { | 917 | if (alignment != slot_alignment) { |
| 918 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {} Free: {}", .{ | 918 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {f} Free: {f}", .{ |
| 919 | slot_alignment.toByteUnits(), | 919 | slot_alignment.toByteUnits(), |
| 920 | alignment.toByteUnits(), | 920 | alignment.toByteUnits(), |
| 921 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), | 921 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), |
| ... | @@ -1006,7 +1006,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -1006,7 +1006,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 1006 | }; | 1006 | }; |
| 1007 | std.debug.captureStackTrace(return_address, &free_stack_trace); | 1007 | std.debug.captureStackTrace(return_address, &free_stack_trace); |
| 1008 | if (memory.len != requested_size) { | 1008 | if (memory.len != requested_size) { |
| 1009 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {} Free: {}", .{ | 1009 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 1010 | requested_size, | 1010 | requested_size, |
| 1011 | memory.len, | 1011 | memory.len, |
| 1012 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), | 1012 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), |
| ... | @@ -1014,7 +1014,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -1014,7 +1014,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 1014 | }); | 1014 | }); |
| 1015 | } | 1015 | } |
| 1016 | if (alignment != slot_alignment) { | 1016 | if (alignment != slot_alignment) { |
| 1017 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {} Free: {}", .{ | 1017 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {f} Free: {f}", .{ |
| 1018 | slot_alignment.toByteUnits(), | 1018 | slot_alignment.toByteUnits(), |
| 1019 | alignment.toByteUnits(), | 1019 | alignment.toByteUnits(), |
| 1020 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), | 1020 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), |
lib/std/http/Server.zig+3-7| ... | @@ -130,13 +130,9 @@ pub const Request = struct { | ... | @@ -130,13 +130,9 @@ pub const Request = struct { |
| 130 | write_error: anyerror, | 130 | write_error: anyerror, |
| 131 | 131 | ||
| 132 | pub const Compression = union(enum) { | 132 | pub const Compression = union(enum) { |
| 133 | pub const DeflateDecompressor = std.compress.zlib.Decompressor(std.io.AnyReader); | 133 | deflate: std.compress.zlib.Decompressor, |
| 134 | pub const GzipDecompressor = std.compress.gzip.Decompressor(std.io.AnyReader); | 134 | gzip: std.compress.gzip.Decompressor, |
| 135 | pub const ZstdDecompressor = std.compress.zstd.Decompressor(std.io.AnyReader); | 135 | zstd: std.compress.zstd.Decompressor, |
| 136 | |||
| 137 | deflate: DeflateDecompressor, | ||
| 138 | gzip: GzipDecompressor, | ||
| 139 | zstd: ZstdDecompressor, | ||
| 140 | none: void, | 136 | none: void, |
| 141 | }; | 137 | }; |
| 142 | 138 |
lib/std/http/WebSocket.zig+1-1| ... | @@ -9,7 +9,7 @@ const native_endian = builtin.cpu.arch.endian(); | ... | @@ -9,7 +9,7 @@ const native_endian = builtin.cpu.arch.endian(); |
| 9 | key: []const u8, | 9 | key: []const u8, |
| 10 | request: *std.http.Server.Request, | 10 | request: *std.http.Server.Request, |
| 11 | recv_fifo: std.fifo.LinearFifo(u8, .Slice), | 11 | recv_fifo: std.fifo.LinearFifo(u8, .Slice), |
| 12 | reader: std.io.AnyReader, | 12 | reader: *std.io.BufferedReader, |
| 13 | response: std.http.Server.Response, | 13 | response: std.http.Server.Response, |
| 14 | /// Number of bytes that have been peeked but not discarded yet. | 14 | /// Number of bytes that have been peeked but not discarded yet. |
| 15 | outstanding_len: usize, | 15 | outstanding_len: usize, |
lib/std/io.zig+1-2| ... | @@ -30,8 +30,7 @@ pub const limitedReader = @import("io/limited_reader.zig").limitedReader; | ... | @@ -30,8 +30,7 @@ pub const limitedReader = @import("io/limited_reader.zig").limitedReader; |
| 30 | pub const MultiWriter = @import("io/multi_writer.zig").MultiWriter; | 30 | pub const MultiWriter = @import("io/multi_writer.zig").MultiWriter; |
| 31 | pub const multiWriter = @import("io/multi_writer.zig").multiWriter; | 31 | pub const multiWriter = @import("io/multi_writer.zig").multiWriter; |
| 32 | 32 | ||
| 33 | pub const BitReader = @import("io/bit_reader.zig").BitReader; | 33 | pub const BitReader = @import("io/bit_reader.zig").Type; |
| 34 | pub const bitReader = @import("io/bit_reader.zig").bitReader; | ||
| 35 | 34 | ||
| 36 | pub const BitWriter = @import("io/bit_writer.zig").BitWriter; | 35 | pub const BitWriter = @import("io/bit_writer.zig").BitWriter; |
| 37 | pub const bitWriter = @import("io/bit_writer.zig").bitWriter; | 36 | pub const bitWriter = @import("io/bit_writer.zig").bitWriter; |
lib/std/io/BufferedWriter.zig+9-9| ... | @@ -614,23 +614,23 @@ pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std. | ... | @@ -614,23 +614,23 @@ pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std. |
| 614 | return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill); | 614 | return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill); |
| 615 | } | 615 | } |
| 616 | 616 | ||
| 617 | pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void { | 617 | pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!usize { |
| 618 | const T = @TypeOf(value); | 618 | const T = @TypeOf(value); |
| 619 | 619 | var n: usize = 0; | |
| 620 | switch (@typeInfo(T)) { | 620 | switch (@typeInfo(T)) { |
| 621 | .pointer => |info| { | 621 | .pointer => |info| { |
| 622 | try bw.writeAll(@typeName(info.child) ++ "@"); | 622 | n += try bw.writeAllCount(@typeName(info.child) ++ "@"); |
| 623 | if (info.size == .slice) | 623 | if (info.size == .slice) |
| 624 | try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{}) | 624 | n += try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{}) |
| 625 | else | 625 | else |
| 626 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); | 626 | n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); |
| 627 | return; | 627 | return n; |
| 628 | }, | 628 | }, |
| 629 | .optional => |info| { | 629 | .optional => |info| { |
| 630 | if (@typeInfo(info.child) == .pointer) { | 630 | if (@typeInfo(info.child) == .pointer) { |
| 631 | try bw.writeAll(@typeName(info.child) ++ "@"); | 631 | n += try bw.writeAll(@typeName(info.child) ++ "@"); |
| 632 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); | 632 | n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); |
| 633 | return; | 633 | return n; |
| 634 | } | 634 | } |
| 635 | }, | 635 | }, |
| 636 | else => {}, | 636 | else => {}, |
lib/std/io/bit_reader.zig+13-15| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("../std.zig"); | 1 | const std = @import("../std.zig"); |
| 2 | const bit_reader = @This(); | ||
| 2 | 3 | ||
| 3 | //General note on endianess: | 4 | //General note on endianess: |
| 4 | //Big endian is packed starting in the most significant part of the byte and subsequent | 5 | //Big endian is packed starting in the most significant part of the byte and subsequent |
| ... | @@ -13,11 +14,11 @@ const std = @import("../std.zig"); | ... | @@ -13,11 +14,11 @@ const std = @import("../std.zig"); |
| 13 | // of the byte. | 14 | // of the byte. |
| 14 | 15 | ||
| 15 | /// Creates a bit reader which allows for reading bits from an underlying standard reader | 16 | /// Creates a bit reader which allows for reading bits from an underlying standard reader |
| 16 | pub fn BitReader(comptime endian: std.builtin.Endian) type { | 17 | pub fn Type(comptime endian: std.builtin.Endian) type { |
| 17 | return struct { | 18 | return struct { |
| 18 | reader: *std.io.BufferedReader, | 19 | reader: *std.io.BufferedReader, |
| 19 | bits: u8 = 0, | 20 | bits: u8, |
| 20 | count: u4 = 0, | 21 | count: u4, |
| 21 | 22 | ||
| 22 | const low_bit_mask = [9]u8{ | 23 | const low_bit_mask = [9]u8{ |
| 23 | 0b00000000, | 24 | 0b00000000, |
| ... | @@ -31,11 +32,12 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { | ... | @@ -31,11 +32,12 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { |
| 31 | 0b11111111, | 32 | 0b11111111, |
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 35 | pub fn init(reader: *std.io.BufferedReader) @This() { | ||
| 36 | return .{ .reader = reader, .bits = 0, .count = 0 }; | ||
| 37 | } | ||
| 38 | |||
| 34 | fn Bits(comptime T: type) type { | 39 | fn Bits(comptime T: type) type { |
| 35 | return struct { | 40 | return struct { T, u16 }; |
| 36 | T, | ||
| 37 | u16, | ||
| 38 | }; | ||
| 39 | } | 41 | } |
| 40 | 42 | ||
| 41 | fn initBits(comptime T: type, out: anytype, num: u16) Bits(T) { | 43 | fn initBits(comptime T: type, out: anytype, num: u16) Bits(T) { |
| ... | @@ -82,7 +84,7 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { | ... | @@ -82,7 +84,7 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { |
| 82 | const full_bytes_left = (num - out_count) / 8; | 84 | const full_bytes_left = (num - out_count) / 8; |
| 83 | 85 | ||
| 84 | for (0..full_bytes_left) |_| { | 86 | for (0..full_bytes_left) |_| { |
| 85 | const byte = self.reader.readByte() catch |err| switch (err) { | 87 | const byte = self.reader.takeByte() catch |err| switch (err) { |
| 86 | error.EndOfStream => return initBits(T, out, out_count), | 88 | error.EndOfStream => return initBits(T, out, out_count), |
| 87 | else => |e| return e, | 89 | else => |e| return e, |
| 88 | }; | 90 | }; |
| ... | @@ -105,7 +107,7 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { | ... | @@ -105,7 +107,7 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { |
| 105 | 107 | ||
| 106 | if (bits_left == 0) return initBits(T, out, out_count); | 108 | if (bits_left == 0) return initBits(T, out, out_count); |
| 107 | 109 | ||
| 108 | const final_byte = self.reader.readByte() catch |err| switch (err) { | 110 | const final_byte = self.reader.takeByte() catch |err| switch (err) { |
| 109 | error.EndOfStream => return initBits(T, out, out_count), | 111 | error.EndOfStream => return initBits(T, out, out_count), |
| 110 | else => |e| return e, | 112 | else => |e| return e, |
| 111 | }; | 113 | }; |
| ... | @@ -157,10 +159,6 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { | ... | @@ -157,10 +159,6 @@ pub fn BitReader(comptime endian: std.builtin.Endian) type { |
| 157 | }; | 159 | }; |
| 158 | } | 160 | } |
| 159 | 161 | ||
| 160 | pub fn bitReader(comptime endian: std.builtin.Endian, reader: *std.io.BufferedReader) BitReader(endian) { | ||
| 161 | return .{ .reader = reader }; | ||
| 162 | } | ||
| 163 | |||
| 164 | /////////////////////////////// | 162 | /////////////////////////////// |
| 165 | 163 | ||
| 166 | test "api coverage" { | 164 | test "api coverage" { |
| ... | @@ -168,7 +166,7 @@ test "api coverage" { | ... | @@ -168,7 +166,7 @@ test "api coverage" { |
| 168 | const mem_le = [_]u8{ 0b00011101, 0b10010101 }; | 166 | const mem_le = [_]u8{ 0b00011101, 0b10010101 }; |
| 169 | 167 | ||
| 170 | var mem_in_be = std.io.fixedBufferStream(&mem_be); | 168 | var mem_in_be = std.io.fixedBufferStream(&mem_be); |
| 171 | var bit_stream_be = bitReader(.big, mem_in_be.reader()); | 169 | var bit_stream_be: bit_reader.Type(.big) = .init(mem_in_be.reader()); |
| 172 | 170 | ||
| 173 | var out_bits: u16 = undefined; | 171 | var out_bits: u16 = undefined; |
| 174 | 172 | ||
| ... | @@ -205,7 +203,7 @@ test "api coverage" { | ... | @@ -205,7 +203,7 @@ test "api coverage" { |
| 205 | try expectError(error.EndOfStream, bit_stream_be.readBitsNoEof(u1, 1)); | 203 | try expectError(error.EndOfStream, bit_stream_be.readBitsNoEof(u1, 1)); |
| 206 | 204 | ||
| 207 | var mem_in_le = std.io.fixedBufferStream(&mem_le); | 205 | var mem_in_le = std.io.fixedBufferStream(&mem_le); |
| 208 | var bit_stream_le = bitReader(.little, mem_in_le.reader()); | 206 | var bit_stream_le: bit_reader.Type(.little) = .init(mem_in_le.reader()); |
| 209 | 207 | ||
| 210 | try expect(1 == try bit_stream_le.readBits(u2, 1, &out_bits)); | 208 | try expect(1 == try bit_stream_le.readBits(u2, 1, &out_bits)); |
| 211 | try expect(out_bits == 1); | 209 | try expect(out_bits == 1); |