authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-06-08 13:14:52 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-06-08 13:14:52 -07:00
log35aa1c690f338f1c76c237437334882c4b407010
tree1270a5508494cbc1396b13ba6a5e3053e81a2bfa
parent777e31f720d2e64bcdb17ba36880c5bc85f959ee
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

move these over here from zig-extras

zig-extras/db70f7e35558c0df34cce0497ec0eea8e984d30d

6 files changed, 62 insertions(+), 0 deletions(-)

AnyReadable.zig+1
......@@ -26,6 +26,7 @@ pub const readUntilDelimitersAlloc = R.readUntilDelimitersAlloc;
2626pub const readUntilDelimiter = R.readUntilDelimiter;
2727pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof;
2828pub const readExpected = R.readExpected;
29pub const readType = R.readType;
2930pub const skipBytes = R.skipBytes;
3031pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof;
3132
buffered_reader.zig+1
......@@ -38,6 +38,7 @@ pub fn BufferedReader(comptime buffer_size: usize, comptime ReaderType: type) ty
3838 pub const readUntilDelimiter = R.readUntilDelimiter;
3939 pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof;
4040 pub const readExpected = R.readExpected;
41 pub const readType = R.readType;
4142 pub const skipBytes = R.skipBytes;
4243 pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof;
4344
counting_reader.zig+1
......@@ -41,6 +41,7 @@ pub fn CountingReader(ReaderType: type) type {
4141 pub const readUntilDelimiter = R.readUntilDelimiter;
4242 pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof;
4343 pub const readExpected = R.readExpected;
44 pub const readType = R.readType;
4445 pub const skipBytes = R.skipBytes;
4546 pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof;
4647
fixed_buffer_stream.zig+1
......@@ -46,6 +46,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type {
4646 pub const readUntilDelimiter = R.readUntilDelimiter;
4747 pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof;
4848 pub const readExpected = R.readExpected;
49 pub const readType = R.readType;
4950 pub const skipBytes = R.skipBytes;
5051 pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof;
5152
limited_reader.zig+1
......@@ -41,6 +41,7 @@ pub fn LimitedReader(ReaderType: type) type {
4141 pub const readUntilDelimiter = R.readUntilDelimiter;
4242 pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof;
4343 pub const readExpected = R.readExpected;
44 pub const readType = R.readType;
4445 pub const skipBytes = R.skipBytes;
4546 pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof;
4647
nio.zig+57
......@@ -214,6 +214,34 @@ pub fn Readable(T: type, this_kind: enum { _var, _const, _bare }) type {
214214 return true;
215215 }
216216
217 pub fn readType(self: Self, comptime C: type, endian: std.builtin.Endian) !C {
218 if (C == u8) return readByte(self); // single bytes dont have an endianness
219 return switch (@typeInfo(C)) {
220 .@"struct" => |t| {
221 switch (t.layout) {
222 .auto, .@"extern" => {
223 var s: C = undefined;
224 inline for (std.meta.fields(C)) |field| {
225 @field(s, field.name) = try readType(self, field.type, endian);
226 }
227 return s;
228 },
229 .@"packed" => return @bitCast(try readType(self, t.backing_integer.?, endian)),
230 }
231 },
232 .array => |t| {
233 var s: C = undefined;
234 for (0..t.len) |i| {
235 s[i] = try readType(self, t.child, endian);
236 }
237 return s;
238 },
239 .int => try self.readInt(C, endian),
240 .@"enum" => |t| @enumFromInt(try readType(self, t.tag_type, endian)),
241 else => unreachable,
242 };
243 }
244
217245 pub fn skipBytes(self: Self, num_bytes: u64, comptime options: struct { buf_size: usize = 512 }) anyerror!void {
218246 var buf: [options.buf_size]u8 = undefined;
219247 var remaining = num_bytes;
......@@ -420,3 +448,32 @@ pub fn randomBytes(comptime len: usize) [len]u8 {
420448 crypto_random.bytes(&bytes);
421449 return bytes;
422450}
451
452pub fn indexBufferT(bytes: [*]const u8, comptime T: type, endian: std.builtin.Endian, idx: usize, max_len: usize) T {
453 std.debug.assert(idx < max_len);
454 var fbs: FixedBufferStream([]const u8) = .init((bytes + (idx * @sizeOf(T)))[0..@sizeOf(T)]);
455 return fbs.readType(T, endian) catch |err| switch (err) {
456 error.EndOfStream => unreachable, // assert above has been violated
457 };
458}
459
460pub fn BufIndexer(comptime T: type, comptime endian: std.builtin.Endian) type {
461 return struct {
462 bytes: [*]const u8,
463 max_len: usize,
464
465 const Self = @This();
466
467 pub fn init(bytes: [*]const u8, max_len: usize) Self {
468 return .{
469 .bytes = bytes,
470 .max_len = max_len,
471 };
472 }
473
474 /// asserts 'idx' to be in bounds
475 pub fn at(self: *const Self, idx: usize) T {
476 return indexBufferT(self.bytes, T, endian, idx, self.max_len);
477 }
478 };
479}