Skip to content

Commit 9fca391

Browse files
committed
UnpackReader.skip: fix end of stream
1 parent 60e8bbe commit 9fca391

File tree

1 file changed

+54
-10
lines changed

1 file changed

+54
-10
lines changed

src/io.zig

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -286,23 +286,63 @@ pub const UnpackReader = struct {
286286
/// - from the reader's error
287287
pub fn skip(self: *UnpackReader, reader: anytype, header: fmt.Header) !void {
288288
switch (header.type) {
289-
.array => {
289+
.array, .fixarray => {
290290
var r = try self.array(header);
291-
_ = try r.skipAll(reader);
291+
292+
while (r.next(reader) catch |err| switch (err) {
293+
error.EndOfStream => null,
294+
else => return err,
295+
}) |head| {
296+
try self.skip(reader, head);
297+
}
292298
},
293-
.map => {
299+
.map, .fixmap => {
294300
var r = try self.map(header);
295-
_ = try r.skipAll(reader);
301+
302+
while (r.next(reader) catch |err| switch (err) {
303+
error.EndOfStream => null,
304+
else => return err,
305+
}) |head| {
306+
try self.skip(reader, head);
307+
}
296308
},
297309
else => {
298-
var r = try self.rawReader(reader, header);
299-
r.reader().skipBytes(std.math.maxInt(u64), .{}) catch |err| switch (err) {
300-
error.EndOfStream => {}, // This value is ended
301-
else => return err,
302-
};
310+
var r = self.rawReader(reader, header) catch unreachable;
311+
try r.reader().skipBytes(header.size, .{});
303312
},
304313
}
305314
}
315+
316+
test skip {
317+
const t = std.testing;
318+
319+
var content: std.BoundedArray(u8, fmt.PREFIX_BUFSIZE * 1 + "Hello".len) = .{};
320+
_ = try writeString(content.writer(), "Hello");
321+
var stream = std.io.fixedBufferStream(content.constSlice());
322+
323+
var buf: [256]u8 = undefined;
324+
var unpacker = UnpackReader.init(&buf);
325+
const head = try unpacker.next(stream.reader());
326+
const value = try unpacker.rawDupe(stream.reader(), t.allocator, head, 256);
327+
defer t.allocator.free(value);
328+
try t.expectEqualStrings("Hello", value);
329+
}
330+
331+
test "skip returns error.EndOfStream if the stream is ended early" {
332+
const t = std.testing;
333+
334+
var content: std.BoundedArray(u8, fmt.PREFIX_BUFSIZE * 1 + "Hello".len) = .{};
335+
_ = try writeString(content.writer(), "Hello");
336+
var stream = std.io.fixedBufferStream(content.constSlice()[0 .. content.len - 1]);
337+
338+
var buf: [256]u8 = undefined;
339+
var unpacker = UnpackReader.init(&buf);
340+
const head = try unpacker.next(stream.reader());
341+
try t.expectError(
342+
error.EndOfStream,
343+
unpacker.skip(stream.reader(), head),
344+
);
345+
}
306346
};
307347

308348
/// The reader reads a raw value.
@@ -332,7 +372,7 @@ pub fn RawReader(Reader: type) type {
332372
return readsize0;
333373
}
334374

335-
pub const ReaderPtr = std.io.GenericReader(*@This(), LitmitedReader.Error | BufferReader.ReadError, read);
375+
pub const ReaderPtr = std.io.GenericReader(*@This(), LitmitedReader.Error || BufferReader.ReadError, read);
336376

337377
pub fn reader(self: *@This()) ReaderPtr {
338378
return ReaderPtr{ .context = self };
@@ -471,3 +511,7 @@ pub const MapReader = struct {
471511
return self.current - c0;
472512
}
473513
};
514+
515+
test {
516+
_ = UnpackReader;
517+
}

0 commit comments

Comments
 (0)