| ... | ... | @@ -1 +1,44 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | |
| 3 | pub fn Readable(T: type) type { |
| 4 | return struct { |
| 5 | const Error = T.ReadError; |
| 6 | |
| 7 | /// Returns the number of bytes read. It may be less than buffer.len. |
| 8 | /// If the number of bytes read is 0, it means end of stream. |
| 9 | /// End of stream is not an error condition. |
| 10 | // pub fn read(self: *T, buffer: []u8) Error!usize { |
| 11 | // } |
| 12 | |
| 13 | /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it |
| 14 | /// means the stream reached the end. Reaching the end of a stream is not an error |
| 15 | /// condition. |
| 16 | pub fn readAll(self: *T, buffer: []u8) Error!usize { |
| 17 | return self.readAtLeast(buffer, buffer.len); |
| 18 | } |
| 19 | |
| 20 | /// Returns the number of bytes read, calling the underlying read |
| 21 | /// function the minimal number of times until the buffer has at least |
| 22 | /// `len` bytes filled. If the number read is less than `len` it means |
| 23 | /// the stream reached the end. Reaching the end of the stream is not |
| 24 | /// an error condition. |
| 25 | pub fn readAtLeast(self: *T, buffer: []u8, len: usize) Error!usize { |
| 26 | std.debug.assert(len <= buffer.len); |
| 27 | var index: usize = 0; |
| 28 | while (index < len) { |
| 29 | const amt = try self.read(buffer[index..]); |
| 30 | if (amt == 0) break; |
| 31 | index += amt; |
| 32 | } |
| 33 | return index; |
| 34 | } |
| 35 | |
| 36 | /// If the number read would be smaller than `buf.len`, `error.EndOfStream` is returned instead. |
| 37 | pub fn readNoEof(self: *T, buf: []u8) (Error || error{EndOfStream})!void { |
| 38 | const amt_read = try self.readAll(buf); |
| 39 | if (amt_read < buf.len) return error.EndOfStream; |
| 40 | } |
| 41 | }; |
| 42 | } |
| 43 | |
| 44 | pub const AnyReadable = @import("./AnyReadable.zig"); |