1const std = @import("std");
2const builtin = @import("builtin");
3const extras = @import("extras");
4const nio = @import("./nio.zig");
5
6const sys = switch (builtin.target.os.tag) {
7 .linux => @import("sys-linux"),
8 .macos => @import("sys-darwin"),
9 else => unreachable,
10};
11
12pub fn LimitedReader(ReaderType: type) type {
13 return struct {
14 backing_reader: ReaderType,
15 bytes_left: u64,
16
17 const Self = @This();
18
19 pub fn init(backing_reader: ReaderType, bytes_left: u64) Self {
20 return .{
21 .backing_reader = backing_reader,
22 .bytes_left = bytes_left,
23 };
24 }
25
26 pub fn from(backing_reader: anytype, bytes_left: u64) LimitedReader(@TypeOf(backing_reader)) {
27 return .init(backing_reader, bytes_left);
28 }
29
30 const R = nio.Readable(@This(), ._var);
31 pub const readAll = R.readAll;
32 pub const readAtLeast = R.readAtLeast;
33 pub const readNoEof = R.readNoEof;
34 pub const readAllAlloc = R.readAllAlloc;
35 pub const readArray = R.readArray;
36 pub const readByte = R.readByte;
37 pub const readUntilDelimiterArrayList = R.readUntilDelimiterArrayList;
38 pub const readUntilDelimiterAlloc = R.readUntilDelimiterAlloc;
39 pub const readUntilDelimiterOrEofAlloc = R.readUntilDelimiterOrEofAlloc;
40 pub const readUntilDelimitersBuf = R.readUntilDelimitersBuf;
41 pub const readUntilDelimitersArrayList = R.readUntilDelimitersArrayList;
42 pub const readAlloc = R.readAlloc;
43 pub const readInt = R.readInt;
44 pub const readUntilDelimitersAlloc = R.readUntilDelimitersAlloc;
45 pub const readUntilDelimiter = R.readUntilDelimiter;
46 pub const readUntilDelimiterOrEof = R.readUntilDelimiterOrEof;
47 pub const readExpected = R.readExpected;
48 pub const readType = R.readType;
49 pub const skipBytes = R.skipBytes;
50 pub const skipUntilDelimiterOrEof = R.skipUntilDelimiterOrEof;
51 pub const pipeTo = R.pipeTo;
52
53 pub const ReadError = extras.Pointee(ReaderType).ReadError;
54
55 pub fn read(self: *Self, bytes: []u8) ReadError!usize {
56 const max_read = @min(self.bytes_left, bytes.len);
57 const n = try self.backing_reader.read(bytes[0..max_read]);
58 self.bytes_left -= n;
59 return n;
60 }
61 // pub fn readv(self: *Self, iovec: []sys.struct_iovec) ReadError!usize {
62 // const len = try self.backing_reader.readv(iovec);
63 // self.bytes_read += len;
64 // return len;
65 // }
66
67 pub fn anyReadable(self: *Self) nio.AnyReadable {
68 const S = struct {
69 fn read(s: *allowzero anyopaque, buffer: []u8) anyerror!usize {
70 const fbs: *Self = @ptrCast(@alignCast(s));
71 return fbs.read(buffer);
72 }
73 };
74 return .{
75 .vtable = &.{ .read = S.read },
76 .state = @ptrCast(self),
77 };
78 }
79 };
80}