From 35aa1c690f338f1c76c237437334882c4b407010 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Mon, 8 Jun 2026 13:14:52 -0700 Subject: [PATCH] move these over here from zig-extras zig-extras/db70f7e35558c0df34cce0497ec0eea8e984d30d --- AnyReadable.zig | 1 + buffered_reader.zig | 1 + counting_reader.zig | 1 + fixed_buffer_stream.zig | 1 + limited_reader.zig | 1 + nio.zig | 57 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 62 insertions(+) diff --git a/AnyReadable.zig b/AnyReadable.zig index 855c06cd945af1dbef2179d8f7866ab82e264aa3..59292f79b8774894af9843498c59e2c2f8e8536c 100644 --- a/AnyReadable.zig +++ b/AnyReadable.zig @@ -26,6 +26,7 @@ pub const readUntilDelimitersAlloc = R.readUntilDelimitersAlloc; pub const readUntilDelimiter = R.readUntilDelimiter; pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; pub const readExpected = R.readExpected; +pub const readType = R.readType; pub const skipBytes = R.skipBytes; pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; diff --git a/buffered_reader.zig b/buffered_reader.zig index 190d43b55ae5601a44fd1fa30cc04c9e214e9753..8e09f7371edad597a02b9c41f70add6421675a99 100644 --- a/buffered_reader.zig +++ b/buffered_reader.zig @@ -38,6 +38,7 @@ pub fn BufferedReader(comptime buffer_size: usize, comptime ReaderType: type) ty pub const readUntilDelimiter = R.readUntilDelimiter; pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; pub const readExpected = R.readExpected; + pub const readType = R.readType; pub const skipBytes = R.skipBytes; pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; diff --git a/counting_reader.zig b/counting_reader.zig index 7e5542ea6f68dba079ba9f8700b9765ccebe5a4e..25be23d90c42736d01bebc5d69a08f277ae5151a 100644 --- a/counting_reader.zig +++ b/counting_reader.zig @@ -41,6 +41,7 @@ pub fn CountingReader(ReaderType: type) type { pub const readUntilDelimiter = R.readUntilDelimiter; pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; pub const readExpected = R.readExpected; + pub const readType = R.readType; pub const skipBytes = R.skipBytes; pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; diff --git a/fixed_buffer_stream.zig b/fixed_buffer_stream.zig index 9e373b4ce7d43a05f0249b5726186704d964368e..b6189287a6b1a852b898d4142d6eee234924f8a5 100644 --- a/fixed_buffer_stream.zig +++ b/fixed_buffer_stream.zig @@ -46,6 +46,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type { pub const readUntilDelimiter = R.readUntilDelimiter; pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; pub const readExpected = R.readExpected; + pub const readType = R.readType; pub const skipBytes = R.skipBytes; pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; diff --git a/limited_reader.zig b/limited_reader.zig index dfaa16ca4b564451d9cd3ab31debfac6c0063a11..829b683af5083f168a7c9ea59566c296d36e4b90 100644 --- a/limited_reader.zig +++ b/limited_reader.zig @@ -41,6 +41,7 @@ pub fn LimitedReader(ReaderType: type) type { pub const readUntilDelimiter = R.readUntilDelimiter; pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; pub const readExpected = R.readExpected; + pub const readType = R.readType; pub const skipBytes = R.skipBytes; pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; diff --git a/nio.zig b/nio.zig index f5d72420cf6994553945cf4211e0a954fbbc57e4..37bde83834280cb003fbfbf43b55e725aeb29204 100644 --- a/nio.zig +++ b/nio.zig @@ -214,6 +214,34 @@ pub fn Readable(T: type, this_kind: enum { _var, _const, _bare }) type { return true; } + pub fn readType(self: Self, comptime C: type, endian: std.builtin.Endian) !C { + if (C == u8) return readByte(self); // single bytes dont have an endianness + return switch (@typeInfo(C)) { + .@"struct" => |t| { + switch (t.layout) { + .auto, .@"extern" => { + var s: C = undefined; + inline for (std.meta.fields(C)) |field| { + @field(s, field.name) = try readType(self, field.type, endian); + } + return s; + }, + .@"packed" => return @bitCast(try readType(self, t.backing_integer.?, endian)), + } + }, + .array => |t| { + var s: C = undefined; + for (0..t.len) |i| { + s[i] = try readType(self, t.child, endian); + } + return s; + }, + .int => try self.readInt(C, endian), + .@"enum" => |t| @enumFromInt(try readType(self, t.tag_type, endian)), + else => unreachable, + }; + } + pub fn skipBytes(self: Self, num_bytes: u64, comptime options: struct { buf_size: usize = 512 }) anyerror!void { var buf: [options.buf_size]u8 = undefined; var remaining = num_bytes; @@ -420,3 +448,32 @@ pub fn randomBytes(comptime len: usize) [len]u8 { crypto_random.bytes(&bytes); return bytes; } + +pub fn indexBufferT(bytes: [*]const u8, comptime T: type, endian: std.builtin.Endian, idx: usize, max_len: usize) T { + std.debug.assert(idx < max_len); + var fbs: FixedBufferStream([]const u8) = .init((bytes + (idx * @sizeOf(T)))[0..@sizeOf(T)]); + return fbs.readType(T, endian) catch |err| switch (err) { + error.EndOfStream => unreachable, // assert above has been violated + }; +} + +pub fn BufIndexer(comptime T: type, comptime endian: std.builtin.Endian) type { + return struct { + bytes: [*]const u8, + max_len: usize, + + const Self = @This(); + + pub fn init(bytes: [*]const u8, max_len: usize) Self { + return .{ + .bytes = bytes, + .max_len = max_len, + }; + } + + /// asserts 'idx' to be in bounds + pub fn at(self: *const Self, idx: usize) T { + return indexBufferT(self.bytes, T, endian, idx, self.max_len); + } + }; +} -- 2.54.0