@@ -10,6 +10,7 @@ const fs = std.fs;
1010const mem = std .mem ;
1111const meta = std .meta ;
1212const File = std .fs .File ;
13+ const Allocator = std .mem .Allocator ;
1314
1415pub const Mode = enum {
1516 /// I/O operates normally, waiting for the operating system syscalls to complete.
@@ -105,7 +106,255 @@ pub fn getStdIn() File {
105106 };
106107}
107108
108- pub const Reader = @import ("io/reader.zig" ).Reader ;
109+ pub fn GenericReader (
110+ comptime Context : type ,
111+ comptime ReadError : type ,
112+ /// Returns the number of bytes read. It may be less than buffer.len.
113+ /// If the number of bytes read is 0, it means end of stream.
114+ /// End of stream is not an error condition.
115+ comptime readFn : fn (context : Context , buffer : []u8 ) ReadError ! usize ,
116+ ) type {
117+ return struct {
118+ context : Context ,
119+
120+ pub const Error = ReadError ;
121+ pub const NoEofError = ReadError || error {
122+ EndOfStream ,
123+ };
124+
125+ pub inline fn read (self : Self , buffer : []u8 ) Error ! usize {
126+ return readFn (self .context , buffer );
127+ }
128+
129+ pub inline fn readAll (self : Self , buffer : []u8 ) Error ! usize {
130+ return @errorCast (self .any ().readAll (buffer ));
131+ }
132+
133+ pub inline fn readAtLeast (self : Self , buffer : []u8 , len : usize ) Error ! usize {
134+ return @errorCast (self .any ().readAtLeast (buffer , len ));
135+ }
136+
137+ pub inline fn readNoEof (self : Self , buf : []u8 ) NoEofError ! void {
138+ return @errorCast (self .any ().readNoEof (buf ));
139+ }
140+
141+ pub inline fn readAllArrayList (
142+ self : Self ,
143+ array_list : * std .ArrayList (u8 ),
144+ max_append_size : usize ,
145+ ) (error {StreamTooLong } || Error )! void {
146+ return @errorCast (self .any ().readAllArrayList (array_list , max_append_size ));
147+ }
148+
149+ pub inline fn readAllArrayListAligned (
150+ self : Self ,
151+ comptime alignment : ? u29 ,
152+ array_list : * std .ArrayListAligned (u8 , alignment ),
153+ max_append_size : usize ,
154+ ) (error {StreamTooLong } || Error )! void {
155+ return @errorCast (self .any ().readAllArrayListAligned (
156+ alignment ,
157+ array_list ,
158+ max_append_size ,
159+ ));
160+ }
161+
162+ pub inline fn readAllAlloc (
163+ self : Self ,
164+ allocator : Allocator ,
165+ max_size : usize ,
166+ ) (Error || error {StreamTooLong })! []u8 {
167+ return @errorCast (self .any ().readAllAlloc (allocator , max_size ));
168+ }
169+
170+ pub inline fn readUntilDelimiterArrayList (
171+ self : Self ,
172+ array_list : * std .ArrayList (u8 ),
173+ delimiter : u8 ,
174+ max_size : usize ,
175+ ) (NoEofError || error {StreamTooLong })! void {
176+ return @errorCast (self .any ().readUntilDelimiterArrayList (
177+ array_list ,
178+ delimiter ,
179+ max_size ,
180+ ));
181+ }
182+
183+ pub inline fn readUntilDelimiterAlloc (
184+ self : Self ,
185+ allocator : Allocator ,
186+ delimiter : u8 ,
187+ max_size : usize ,
188+ ) (NoEofError || error {StreamTooLong })! []u8 {
189+ return @errorCast (self .any ().readUntilDelimiterAlloc (
190+ allocator ,
191+ delimiter ,
192+ max_size ,
193+ ));
194+ }
195+
196+ pub inline fn readUntilDelimiter (
197+ self : Self ,
198+ buf : []u8 ,
199+ delimiter : u8 ,
200+ ) (NoEofError || error {StreamTooLong })! []u8 {
201+ return @errorCast (self .any ().readUntilDelimiter (buf , delimiter ));
202+ }
203+
204+ pub inline fn readUntilDelimiterOrEofAlloc (
205+ self : Self ,
206+ allocator : Allocator ,
207+ delimiter : u8 ,
208+ max_size : usize ,
209+ ) (Error || error {StreamTooLong })! ? []u8 {
210+ return @errorCast (self .any ().readUntilDelimiterOrEofAlloc (
211+ allocator ,
212+ delimiter ,
213+ max_size ,
214+ ));
215+ }
216+
217+ pub inline fn readUntilDelimiterOrEof (
218+ self : Self ,
219+ buf : []u8 ,
220+ delimiter : u8 ,
221+ ) (Error || error {StreamTooLong })! ? []u8 {
222+ return @errorCast (self .any ().readUntilDelimiterOrEof (buf , delimiter ));
223+ }
224+
225+ pub inline fn streamUntilDelimiter (
226+ self : Self ,
227+ writer : anytype ,
228+ delimiter : u8 ,
229+ optional_max_size : ? usize ,
230+ ) (NoEofError || error {StreamTooLong } || @TypeOf (writer ).Error )! void {
231+ return @errorCast (self .any ().streamUntilDelimiter (
232+ writer ,
233+ delimiter ,
234+ optional_max_size ,
235+ ));
236+ }
237+
238+ pub inline fn skipUntilDelimiterOrEof (self : Self , delimiter : u8 ) Error ! void {
239+ return @errorCast (self .any ().skipUntilDelimiterOrEof (delimiter ));
240+ }
241+
242+ pub inline fn readByte (self : Self ) NoEofError ! u8 {
243+ return @errorCast (self .any ().readByte ());
244+ }
245+
246+ pub inline fn readByteSigned (self : Self ) NoEofError ! i8 {
247+ return @errorCast (self .any ().readByteSigned ());
248+ }
249+
250+ pub inline fn readBytesNoEof (
251+ self : Self ,
252+ comptime num_bytes : usize ,
253+ ) NoEofError ! [num_bytes ]u8 {
254+ return @errorCast (self .any ().readBytesNoEof (num_bytes ));
255+ }
256+
257+ pub inline fn readIntoBoundedBytes (
258+ self : Self ,
259+ comptime num_bytes : usize ,
260+ bounded : * std .BoundedArray (u8 , num_bytes ),
261+ ) Error ! void {
262+ return @errorCast (self .any ().readIntoBoundedBytes (num_bytes , bounded ));
263+ }
264+
265+ pub inline fn readBoundedBytes (
266+ self : Self ,
267+ comptime num_bytes : usize ,
268+ ) Error ! std. BoundedArray (u8 , num_bytes ) {
269+ return @errorCast (self .any ().readBoundedBytes (num_bytes ));
270+ }
271+
272+ pub inline fn readIntNative (self : Self , comptime T : type ) NoEofError ! T {
273+ return @errorCast (self .any ().readIntNative (T ));
274+ }
275+
276+ pub inline fn readIntForeign (self : Self , comptime T : type ) NoEofError ! T {
277+ return @errorCast (self .any ().readIntForeign (T ));
278+ }
279+
280+ pub inline fn readIntLittle (self : Self , comptime T : type ) NoEofError ! T {
281+ return @errorCast (self .any ().readIntLittle (T ));
282+ }
283+
284+ pub inline fn readIntBig (self : Self , comptime T : type ) NoEofError ! T {
285+ return @errorCast (self .any ().readIntBig (T ));
286+ }
287+
288+ pub inline fn readInt (self : Self , comptime T : type , endian : std.builtin.Endian ) NoEofError ! T {
289+ return @errorCast (self .any ().readInt (T , endian ));
290+ }
291+
292+ pub inline fn readVarInt (
293+ self : Self ,
294+ comptime ReturnType : type ,
295+ endian : std.builtin.Endian ,
296+ size : usize ,
297+ ) NoEofError ! ReturnType {
298+ return @errorCast (self .any ().readVarInt (ReturnType , endian , size ));
299+ }
300+
301+ pub const SkipBytesOptions = AnyReader .SkipBytesOptions ;
302+
303+ pub inline fn skipBytes (
304+ self : Self ,
305+ num_bytes : u64 ,
306+ comptime options : SkipBytesOptions ,
307+ ) NoEofError ! void {
308+ return @errorCast (self .any ().skipBytes (num_bytes , options ));
309+ }
310+
311+ pub inline fn isBytes (self : Self , slice : []const u8 ) Error ! bool {
312+ return @errorCast (self .any ().isBytes (slice ));
313+ }
314+
315+ pub inline fn readStruct (self : Self , comptime T : type ) NoEofError ! T {
316+ return @errorCast (self .any ().readStruct (T ));
317+ }
318+
319+ pub inline fn readStructBig (self : Self , comptime T : type ) NoEofError ! T {
320+ return @errorCast (self .any ().readStructBig (T ));
321+ }
322+
323+ pub const ReadEnumError = Error || error {
324+ /// An integer was read, but it did not match any of the tags in the supplied enum.
325+ InvalidValue ,
326+ };
327+
328+ pub inline fn readEnum (
329+ self : Self ,
330+ comptime Enum : type ,
331+ endian : std.builtin.Endian ,
332+ ) ReadEnumError ! Enum {
333+ return @errorCast (self .any ().readEnum (Enum , endian ));
334+ }
335+
336+ pub inline fn any (self : * const Self ) AnyReader {
337+ return .{
338+ .context = @ptrCast (& self .context ),
339+ .readFn = typeErasedReadFn ,
340+ };
341+ }
342+
343+ const Self = @This ();
344+
345+ fn typeErasedReadFn (context : * const anyopaque , buffer : []u8 ) anyerror ! usize {
346+ const ptr : * const Context = @alignCast (@ptrCast (context ));
347+ return readFn (ptr .* , buffer );
348+ }
349+ };
350+ }
351+
352+ /// Deprecated; consider switching to `AnyReader` or use `GenericReader`
353+ /// to use previous API.
354+ pub const Reader = GenericReader ;
355+
356+ pub const AnyReader = @import ("io/Reader.zig" );
357+
109358pub const Writer = @import ("io/writer.zig" ).Writer ;
110359pub const SeekableStream = @import ("io/seekable_stream.zig" ).SeekableStream ;
111360
@@ -168,7 +417,7 @@ test "null_writer" {
168417}
169418
170419pub fn poll (
171- allocator : std.mem. Allocator ,
420+ allocator : Allocator ,
172421 comptime StreamEnum : type ,
173422 files : PollFiles (StreamEnum ),
174423) Poller (StreamEnum ) {
@@ -418,6 +667,7 @@ pub fn PollFiles(comptime StreamEnum: type) type {
418667}
419668
420669test {
670+ _ = AnyReader ;
421671 _ = @import ("io/bit_reader.zig" );
422672 _ = @import ("io/bit_writer.zig" );
423673 _ = @import ("io/buffered_atomic_file.zig" );
@@ -427,7 +677,6 @@ test {
427677 _ = @import ("io/counting_writer.zig" );
428678 _ = @import ("io/counting_reader.zig" );
429679 _ = @import ("io/fixed_buffer_stream.zig" );
430- _ = @import ("io/reader.zig" );
431680 _ = @import ("io/writer.zig" );
432681 _ = @import ("io/peek_stream.zig" );
433682 _ = @import ("io/seekable_stream.zig" );
0 commit comments