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