From 93e7414f96aa2b27f3f0bf72f27967c83e6396ef Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Sun, 31 May 2026 14:45:21 -0700 Subject: [PATCH] add LimitedReader --- limited_reader.zig | 73 ++++++++++++++++++++++++++++++++++++++++++++++ nio.zig | 2 ++ 2 files changed, 75 insertions(+) create mode 100644 limited_reader.zig diff --git a/limited_reader.zig b/limited_reader.zig new file mode 100644 index 0000000000000000000000000000000000000000..af8059c194c2277a03ba2fcd2b58699c4cf9df30 --- /dev/null +++ b/limited_reader.zig @@ -0,0 +1,73 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const extras = @import("extras"); +const nio = @import("./nio.zig"); + +const sys = switch (builtin.target.os.tag) { + .linux => @import("sys-linux"), + .macos => @import("sys-darwin"), + else => unreachable, +}; + +pub fn LimitedReader(ReaderType: type) type { + return struct { + backing_reader: ReaderType, + bytes_left: u64, + + const Self = @This(); + + pub fn init(backing_reader: ReaderType, bytes_left: u64) Self { + return .{ + .backing_reader = backing_reader, + .bytes_left = bytes_left, + }; + } + + const R = nio.Readable(@This(), ._var); + pub const readAll = R.readAll; + pub const readAtLeast = R.readAtLeast; + pub const readNoEof = R.readNoEof; + pub const readAllAlloc = R.readAllAlloc; + pub const readArray = R.readArray; + pub const readByte = R.readByte; + pub const readUntilDelimiterArrayList = R.readUntilDelimiterArrayList; + pub const readUntilDelimiterAlloc = R.readUntilDelimiterAlloc; + pub const readUntilDelimiterOrEofAlloc = R.readUntilDelimiterOrEofAlloc; + pub const readUntilDelimitersBuf = R.readUntilDelimitersBuf; + pub const readUntilDelimitersArrayList = R.readUntilDelimitersArrayList; + pub const readAlloc = R.readAlloc; + pub const readInt = R.readInt; + pub const readUntilDelimitersAlloc = R.readUntilDelimitersAlloc; + pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof; + pub const readExpected = R.readExpected; + pub const skipBytes = R.skipBytes; + pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof; + + pub const ReadError = extras.Pointee(ReaderType).ReadError; + + pub fn read(self: *Self, bytes: []u8) ReadError!usize { + const max_read = @min(self.bytes_left, bytes.len); + const n = try self.backing_reader.read(bytes[0..max_read]); + self.bytes_left -= n; + return n; + } + // pub fn readv(self: *Self, iovec: []sys.struct_iovec) ReadError!usize { + // const len = try self.backing_reader.readv(iovec); + // self.bytes_read += len; + // return len; + // } + + pub fn anyReadable(self: *Self) nio.AnyReadable { + const S = struct { + fn read(s: *allowzero anyopaque, buffer: []u8) anyerror!usize { + const fbs: *Self = @ptrCast(@alignCast(s)); + return fbs.read(buffer); + } + }; + return .{ + .vtable = &.{ .read = S.read }, + .state = @ptrCast(self), + }; + } + }; +} diff --git a/nio.zig b/nio.zig index bdc922099b4aff719fd68c4a0807f091af4ee913..b764a0c7291c8b5f9223340151b73921778119b0 100644 --- a/nio.zig +++ b/nio.zig @@ -395,3 +395,5 @@ pub const NullWriter = @import("./null_writer.zig").NullWriter; pub const AllocatingWriter = @import("./allocating_writer.zig").AllocatingWriter; pub const CountingReader = @import("./counting_reader.zig").CountingReader; + +pub const LimitedReader = @import("./limited_reader.zig").LimitedReader; -- 2.54.0