diff --git a/AnyReadable.zig b/AnyReadable.zig new file mode 100644 index 0000000000000000000000000000000000000000..4725feb166fd9dfd4971af668a6bc05b1dc641ae --- /dev/null +++ b/AnyReadable.zig @@ -0,0 +1,14 @@ +const std = @import("std"); + +const nio = @import("./nio.zig"); +const AnyReadable = @This(); + +readFn: *const fn (*anyopaque, []u8) anyerror!usize, +state: *anyopaque, + +pub fn read(r: *AnyReadable, buffer: []u8) !usize { + return r.readFn(r.state, buffer); +} + +pub const ReadError = anyerror; +pub usingnamespace nio.Readable(@This()); diff --git a/README.md b/README.md index 43a986f254e5616445af61df8d42bfff36df8de7..671cdeb284062ea878cf540d1be6e41dd2e287ff 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,5 @@ [![Zigmod](https://img.shields.io/badge/Zigmod-latest-f7a41d)](https://github.com/nektro/zigmod) Nektro's IO, an alternative to `std.io`. + +Some code ported from Zig 0.14.1, via MIT Copyright (c) Zig contributors. New code MPL-2.0. diff --git a/nio.zig b/nio.zig index 95a0b682a71942e4010a9c8ee96461fb9a3b53a3..a560f861114f36ca6194d843d198241206ef5401 100644 --- a/nio.zig +++ b/nio.zig @@ -1 +1,44 @@ const std = @import("std"); + +pub fn Readable(T: type) type { + return struct { + const Error = T.ReadError; + + /// Returns the number of bytes read. It may be less than buffer.len. + /// If the number of bytes read is 0, it means end of stream. + /// End of stream is not an error condition. + // pub fn read(self: *T, buffer: []u8) Error!usize { + // } + + /// Returns the number of bytes read. If the number read is smaller than `buffer.len`, it + /// means the stream reached the end. Reaching the end of a stream is not an error + /// condition. + pub fn readAll(self: *T, buffer: []u8) Error!usize { + return self.readAtLeast(buffer, buffer.len); + } + + /// Returns the number of bytes read, calling the underlying read + /// function the minimal number of times until the buffer has at least + /// `len` bytes filled. If the number read is less than `len` it means + /// the stream reached the end. Reaching the end of the stream is not + /// an error condition. + pub fn readAtLeast(self: *T, buffer: []u8, len: usize) Error!usize { + std.debug.assert(len <= buffer.len); + var index: usize = 0; + while (index < len) { + const amt = try self.read(buffer[index..]); + if (amt == 0) break; + index += amt; + } + return index; + } + + /// If the number read would be smaller than `buf.len`, `error.EndOfStream` is returned instead. + pub fn readNoEof(self: *T, buf: []u8) (Error || error{EndOfStream})!void { + const amt_read = try self.readAll(buf); + if (amt_read < buf.len) return error.EndOfStream; + } + }; +} + +pub const AnyReadable = @import("./AnyReadable.zig");