@@ -10,6 +10,7 @@ const fs = std.fs;
10
10
const mem = std .mem ;
11
11
const meta = std .meta ;
12
12
const File = std .fs .File ;
13
+ const Allocator = std .mem .Allocator ;
13
14
14
15
pub const Mode = enum {
15
16
/// I/O operates normally, waiting for the operating system syscalls to complete.
@@ -105,7 +106,243 @@ pub fn getStdIn() File {
105
106
};
106
107
}
107
108
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 .typeErased ().readAll (buffer ));
131
+ }
132
+
133
+ pub inline fn readAtLeast (self : Self , buffer : []u8 , len : usize ) Error ! usize {
134
+ return @errorCast (self .typeErased ().readAtLeast (buffer , len ));
135
+ }
136
+
137
+ pub inline fn readNoEof (self : Self , buf : []u8 ) NoEofError ! void {
138
+ return @errorCast (self .typeErased ().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 .typeErased ().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 .typeErased ().readAllArrayListAligned (
156
+ alignment ,
157
+ array_list ,
158
+ max_append_size ,
159
+ ));
160
+ }
161
+
162
+ pub inline fn readAllAlloc (self : Self , allocator : Allocator , max_size : usize ) Error ! []u8 {
163
+ return @errorCast (self .typeErased ().readAllAlloc (allocator , max_size ));
164
+ }
165
+
166
+ pub inline fn readUntilDelimiterArrayList (
167
+ self : Self ,
168
+ array_list : * std .ArrayList (u8 ),
169
+ delimiter : u8 ,
170
+ max_size : usize ,
171
+ ) Error ! void {
172
+ return @errorCast (self .typeErased ().readUntilDelimiterArrayList (
173
+ array_list ,
174
+ delimiter ,
175
+ max_size ,
176
+ ));
177
+ }
178
+
179
+ pub inline fn readUntilDelimiterAlloc (
180
+ self : Self ,
181
+ allocator : Allocator ,
182
+ delimiter : u8 ,
183
+ max_size : usize ,
184
+ ) Error ! []u8 {
185
+ return @errorCast (self .typeErased ().readUntilDelimiterAlloc (
186
+ allocator ,
187
+ delimiter ,
188
+ max_size ,
189
+ ));
190
+ }
191
+
192
+ pub inline fn readUntilDelimiter (self : Self , buf : []u8 , delimiter : u8 ) Error ! []u8 {
193
+ return @errorCast (self .typeErased ().readUntilDelimiter (buf , delimiter ));
194
+ }
195
+
196
+ pub inline fn readUntilDelimiterOrEofAlloc (
197
+ self : Self ,
198
+ allocator : Allocator ,
199
+ delimiter : u8 ,
200
+ max_size : usize ,
201
+ ) Error ! ? []u8 {
202
+ return @errorCast (self .typeErased ().readUntilDelimiterOrEofAlloc (
203
+ allocator ,
204
+ delimiter ,
205
+ max_size ,
206
+ ));
207
+ }
208
+
209
+ pub inline fn readUntilDelimiterOrEof (self : Self , buf : []u8 , delimiter : u8 ) Error ! ? []u8 {
210
+ return @errorCast (self .typeErased ().readUntilDelimiterOrEof (buf , delimiter ));
211
+ }
212
+
213
+ pub inline fn streamUntilDelimiter (
214
+ self : Self ,
215
+ writer : anytype ,
216
+ delimiter : u8 ,
217
+ optional_max_size : ? usize ,
218
+ ) (NoEofError || error {StreamTooLong } || @TypeOf (writer ).Error )! void {
219
+ return @errorCast (self .typeErased ().streamUntilDelimiter (
220
+ writer .typeErased (),
221
+ delimiter ,
222
+ optional_max_size ,
223
+ ));
224
+ }
225
+
226
+ pub inline fn skipUntilDelimiterOrEof (self : Self , delimiter : u8 ) Error ! void {
227
+ return @errorCast (self .typeErased ().skipUntilDelimiterOrEof (delimiter ));
228
+ }
229
+
230
+ pub inline fn readByte (self : Self ) NoEofError ! u8 {
231
+ return @errorCast (self .typeErased ().readByte ());
232
+ }
233
+
234
+ pub inline fn readByteSigned (self : Self ) NoEofError ! i8 {
235
+ return @errorCast (self .typeErased ().readByteSigned ());
236
+ }
237
+
238
+ pub inline fn readBytesNoEof (
239
+ self : Self ,
240
+ comptime num_bytes : usize ,
241
+ ) NoEofError ! [num_bytes ]u8 {
242
+ return @errorCast (self .typeErased ().readBytesNoEof (num_bytes ));
243
+ }
244
+
245
+ pub inline fn readIntoBoundedBytes (
246
+ self : Self ,
247
+ comptime num_bytes : usize ,
248
+ bounded : * std .BoundedArray (u8 , num_bytes ),
249
+ ) Error ! void {
250
+ return @errorCast (self .typeErased ().readIntoBoundedBytes (num_bytes , bounded ));
251
+ }
252
+
253
+ pub inline fn readBoundedBytes (
254
+ self : Self ,
255
+ comptime num_bytes : usize ,
256
+ ) Error ! std. BoundedArray (u8 , num_bytes ) {
257
+ return @errorCast (self .typeErased ().readBoundedBytes (num_bytes ));
258
+ }
259
+
260
+ pub inline fn readIntNative (self : Self , comptime T : type ) NoEofError ! T {
261
+ return @errorCast (self .typeErased ().readIntNative (T ));
262
+ }
263
+
264
+ pub inline fn readIntForeign (self : Self , comptime T : type ) NoEofError ! T {
265
+ return @errorCast (self .typeErased ().readIntForeign (T ));
266
+ }
267
+
268
+ pub inline fn readIntLittle (self : Self , comptime T : type ) NoEofError ! T {
269
+ return @errorCast (self .typeErased ().readIntLittle (T ));
270
+ }
271
+
272
+ pub inline fn readIntBig (self : Self , comptime T : type ) NoEofError ! T {
273
+ return @errorCast (self .typeErased ().readIntBig (T ));
274
+ }
275
+
276
+ pub inline fn readInt (self : Self , comptime T : type , endian : std.builtin.Endian ) NoEofError ! T {
277
+ return @errorCast (self .typeErased ().readInt (T , endian ));
278
+ }
279
+
280
+ pub inline fn readVarInt (
281
+ self : Self ,
282
+ comptime ReturnType : type ,
283
+ endian : std.builtin.Endian ,
284
+ size : usize ,
285
+ ) NoEofError ! ReturnType {
286
+ return @errorCast (self .typeErased ().readVarInt (ReturnType , endian , size ));
287
+ }
288
+
289
+ pub const SkipBytesOptions = TypeErasedReader .SkipBytesOptions ;
290
+
291
+ pub inline fn skipBytes (
292
+ self : Self ,
293
+ num_bytes : u64 ,
294
+ comptime options : SkipBytesOptions ,
295
+ ) Error ! void {
296
+ return @errorCast (self .typeErased ().skipBytes (num_bytes , options ));
297
+ }
298
+
299
+ pub inline fn isBytes (self : Self , slice : []const u8 ) Error ! bool {
300
+ return @errorCast (self .typeErased ().isBytes (slice ));
301
+ }
302
+
303
+ pub fn readStruct (self : Self , comptime T : type ) Error ! T {
304
+ return @errorCast (self .typeErased ().readStruct (T ));
305
+ }
306
+
307
+ pub inline fn readStructBig (self : Self , comptime T : type ) Error ! T {
308
+ return @errorCast (self .typeErased ().readStructBig (T ));
309
+ }
310
+
311
+ pub const ReadEnumError = Error || error {
312
+ /// An integer was read, but it did not match any of the tags in the supplied enum.
313
+ InvalidValue ,
314
+ };
315
+
316
+ pub inline fn readEnum (
317
+ self : Self ,
318
+ comptime Enum : type ,
319
+ endian : std.builtin.Endian ,
320
+ ) ReadEnumError ! Enum {
321
+ return @errorCast (self .typeErased ().readEnum (Enum , endian ));
322
+ }
323
+
324
+ pub inline fn typeErased (self : * const Self ) TypeErasedReader {
325
+ return .{
326
+ .context = @ptrCast (& self .context ),
327
+ .readFn = typeErasedReadFn ,
328
+ };
329
+ }
330
+
331
+ const Self = @This ();
332
+
333
+ fn typeErasedReadFn (context : * const anyopaque , buffer : []u8 ) anyerror ! usize {
334
+ const ptr : * const Context = @alignCast (@ptrCast (context ));
335
+ return readFn (ptr .* , buffer );
336
+ }
337
+ };
338
+ }
339
+
340
+ /// Deprecated; consider switching to `TypeErasedReader` or use `GenericReader`
341
+ /// to use previous API.
342
+ pub const Reader = GenericReader ;
343
+
344
+ pub const TypeErasedReader = @import ("io/Reader.zig" );
345
+
109
346
pub const Writer = @import ("io/writer.zig" ).Writer ;
110
347
pub const SeekableStream = @import ("io/seekable_stream.zig" ).SeekableStream ;
111
348
@@ -168,7 +405,7 @@ test "null_writer" {
168
405
}
169
406
170
407
pub fn poll (
171
- allocator : std.mem. Allocator ,
408
+ allocator : Allocator ,
172
409
comptime StreamEnum : type ,
173
410
files : PollFiles (StreamEnum ),
174
411
) Poller (StreamEnum ) {
@@ -418,6 +655,7 @@ pub fn PollFiles(comptime StreamEnum: type) type {
418
655
}
419
656
420
657
test {
658
+ _ = TypeErasedReader ;
421
659
_ = @import ("io/bit_reader.zig" );
422
660
_ = @import ("io/bit_writer.zig" );
423
661
_ = @import ("io/buffered_atomic_file.zig" );
@@ -427,7 +665,6 @@ test {
427
665
_ = @import ("io/counting_writer.zig" );
428
666
_ = @import ("io/counting_reader.zig" );
429
667
_ = @import ("io/fixed_buffer_stream.zig" );
430
- _ = @import ("io/reader.zig" );
431
668
_ = @import ("io/writer.zig" );
432
669
_ = @import ("io/peek_stream.zig" );
433
670
_ = @import ("io/seekable_stream.zig" );
0 commit comments