| ... | ... | @@ -1,45 +0,0 @@ |
| 1 | | const std = @import("../std.zig"); |
| 2 | | const io = std.io; |
| 3 | | const assert = std.debug.assert; |
| 4 | | const testing = std.testing; |
| 5 | | |
| 6 | | pub fn LimitedReader(comptime ReaderType: type) type { |
| 7 | | return struct { |
| 8 | | inner_reader: ReaderType, |
| 9 | | bytes_left: u64, |
| 10 | | |
| 11 | | pub const Error = ReaderType.Error; |
| 12 | | pub const Reader = io.GenericReader(*Self, Error, read); |
| 13 | | |
| 14 | | const Self = @This(); |
| 15 | | |
| 16 | | pub fn read(self: *Self, dest: []u8) Error!usize { |
| 17 | | const max_read = @min(self.bytes_left, dest.len); |
| 18 | | const n = try self.inner_reader.read(dest[0..max_read]); |
| 19 | | self.bytes_left -= n; |
| 20 | | return n; |
| 21 | | } |
| 22 | | |
| 23 | | pub fn reader(self: *Self) Reader { |
| 24 | | return .{ .context = self }; |
| 25 | | } |
| 26 | | }; |
| 27 | | } |
| 28 | | |
| 29 | | /// Returns an initialised `LimitedReader`. |
| 30 | | /// `bytes_left` is a `u64` to be able to take 64 bit file offsets |
| 31 | | pub fn limitedReader(inner_reader: anytype, bytes_left: u64) LimitedReader(@TypeOf(inner_reader)) { |
| 32 | | return .{ .inner_reader = inner_reader, .bytes_left = bytes_left }; |
| 33 | | } |
| 34 | | |
| 35 | | test "basic usage" { |
| 36 | | const data = "hello world"; |
| 37 | | var fbs = std.io.fixedBufferStream(data); |
| 38 | | var early_stream = limitedReader(fbs.reader(), 3); |
| 39 | | |
| 40 | | var buf: [5]u8 = undefined; |
| 41 | | try testing.expectEqual(@as(usize, 3), try early_stream.reader().read(&buf)); |
| 42 | | try testing.expectEqualSlices(u8, data[0..3], buf[0..3]); |
| 43 | | try testing.expectEqual(@as(usize, 0), try early_stream.reader().read(&buf)); |
| 44 | | try testing.expectError(error.EndOfStream, early_stream.reader().skipBytes(10, .{})); |
| 45 | | } |