| author | |
| committer | |
| log | 35aa1c690f338f1c76c237437334882c4b407010 |
| tree | 1270a5508494cbc1396b13ba6a5e3053e81a2bfa |
| parent | 777e31f720d2e64bcdb17ba36880c5bc85f959ee |
| signature |
zig-extras/db70f7e35558c0df34cce0497ec0eea8e984d30d6 files changed, 62 insertions(+), 0 deletions(-)
AnyReadable.zig+1| ... | ... | @@ -26,6 +26,7 @@ pub const readUntilDelimitersAlloc = R.readUntilDelimitersAlloc; |
| 26 | 26 | pub const readUntilDelimiter = R.readUntilDelimiter; |
| 27 | 27 | pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; |
| 28 | 28 | pub const readExpected = R.readExpected; |
| 29 | pub const readType = R.readType; | |
| 29 | 30 | pub const skipBytes = R.skipBytes; |
| 30 | 31 | pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; |
| 31 | 32 |
buffered_reader.zig+1| ... | ... | @@ -38,6 +38,7 @@ pub fn BufferedReader(comptime buffer_size: usize, comptime ReaderType: type) ty |
| 38 | 38 | pub const readUntilDelimiter = R.readUntilDelimiter; |
| 39 | 39 | pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; |
| 40 | 40 | pub const readExpected = R.readExpected; |
| 41 | pub const readType = R.readType; | |
| 41 | 42 | pub const skipBytes = R.skipBytes; |
| 42 | 43 | pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; |
| 43 | 44 |
counting_reader.zig+1| ... | ... | @@ -41,6 +41,7 @@ pub fn CountingReader(ReaderType: type) type { |
| 41 | 41 | pub const readUntilDelimiter = R.readUntilDelimiter; |
| 42 | 42 | pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; |
| 43 | 43 | pub const readExpected = R.readExpected; |
| 44 | pub const readType = R.readType; | |
| 44 | 45 | pub const skipBytes = R.skipBytes; |
| 45 | 46 | pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; |
| 46 | 47 |
fixed_buffer_stream.zig+1| ... | ... | @@ -46,6 +46,7 @@ pub fn FixedBufferStream(comptime Buffer: type) type { |
| 46 | 46 | pub const readUntilDelimiter = R.readUntilDelimiter; |
| 47 | 47 | pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; |
| 48 | 48 | pub const readExpected = R.readExpected; |
| 49 | pub const readType = R.readType; | |
| 49 | 50 | pub const skipBytes = R.skipBytes; |
| 50 | 51 | pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; |
| 51 | 52 |
limited_reader.zig+1| ... | ... | @@ -41,6 +41,7 @@ pub fn LimitedReader(ReaderType: type) type { |
| 41 | 41 | pub const readUntilDelimiter = R.readUntilDelimiter; |
| 42 | 42 | pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; |
| 43 | 43 | pub const readExpected = R.readExpected; |
| 44 | pub const readType = R.readType; | |
| 44 | 45 | pub const skipBytes = R.skipBytes; |
| 45 | 46 | pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; |
| 46 | 47 |
nio.zig+57| ... | ... | @@ -214,6 +214,34 @@ pub fn Readable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 214 | 214 | return true; |
| 215 | 215 | } |
| 216 | 216 | |
| 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 | ||
| 217 | 245 | pub fn skipBytes(self: Self, num_bytes: u64, comptime options: struct { buf_size: usize = 512 }) anyerror!void { |
| 218 | 246 | var buf: [options.buf_size]u8 = undefined; |
| 219 | 247 | var remaining = num_bytes; |
| ... | ... | @@ -420,3 +448,32 @@ pub fn randomBytes(comptime len: usize) [len]u8 { |
| 420 | 448 | crypto_random.bytes(&bytes); |
| 421 | 449 | return bytes; |
| 422 | 450 | } |
| 451 | ||
| 452 | pub 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 | ||
| 460 | pub 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 | } |