authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2019-11-11 03:07:57+11:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 16:47:03-05:00
log38ad7daebb42d562946c092a59cfbbf94e75870a
tree7edcc066089eb6e06ba6d74ca06968f2fd470294
parentbdff2f43bdc112cb02e36678d079e82fd5a96605
signature Commit is signed but in an unrecognized format.

std: use LinearFifo to implement io.PeekStream


2 files changed, 17 insertions(+), 37 deletions(-)

lib/std/io.zig+13-33
...@@ -196,7 +196,7 @@ test "io.BufferedInStream" {...@@ -196,7 +196,7 @@ test "io.BufferedInStream" {
196196
197/// Creates a stream which supports 'un-reading' data, so that it can be read again.197/// Creates a stream which supports 'un-reading' data, so that it can be read again.
198/// This makes look-ahead style parsing much easier.198/// This makes look-ahead style parsing much easier.
199pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) type {199pub fn PeekStream(comptime buffer_type: usize, comptime InStreamError: type) type {
200 return struct {200 return struct {
201 const Self = @This();201 const Self = @This();
202 pub const Error = InStreamError;202 pub const Error = InStreamError;
...@@ -207,55 +207,35 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ...@@ -207,55 +207,35 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
207207
208 // Right now the look-ahead space is statically allocated, but a version with dynamic allocation208 // Right now the look-ahead space is statically allocated, but a version with dynamic allocation
209 // is not too difficult to derive from this.209 // is not too difficult to derive from this.
210 buffer: [buffer_size]u8,210 const FifoType = std.fifo.LinearFifo(u8, .{ .Static = buffer_size });
211 index: usize,211 fifo: FifoType,
212 at_end: bool,
213212
214 pub fn init(base: *Stream) Self {213 pub fn init(base: *Stream) Self {
215 return Self{214 return .{
216 .base = base,215 .base = base,
217 .buffer = undefined,216 .fifo = FifoType.init(),
218 .index = 0,
219 .at_end = false,
220 .stream = Stream{ .readFn = readFn },217 .stream = Stream{ .readFn = readFn },
221 };218 };
222 }219 }
223220
224 pub fn putBackByte(self: *Self, byte: u8) void {221 pub fn putBackByte(self: *Self, byte: u8) !void {
225 self.buffer[self.index] = byte;222 try self.putBack(@ptrCast([*]const u8, &byte)[0..1]);
226 self.index += 1;
227 }223 }
228224
229 pub fn putBack(self: *Self, bytes: []const u8) void {225 pub fn putBack(self: *Self, bytes: []const u8) !void {
230 var pos = bytes.len;226 try self.fifo.unget(bytes);
231 while (pos != 0) {
232 pos -= 1;
233 self.putBackByte(bytes[pos]);
234 }
235 }227 }
236228
237 fn readFn(in_stream: *Stream, dest: []u8) Error!usize {229 fn readFn(in_stream: *Stream, dest: []u8) Error!usize {
238 const self = @fieldParentPtr(Self, "stream", in_stream);230 const self = @fieldParentPtr(Self, "stream", in_stream);
239231
240 // copy over anything putBack()'d232 // copy over anything putBack()'d
241 var pos: usize = 0;233 var dest_index = self.fifo.read(dest);
242 while (pos < dest.len and self.index != 0) {234 if (dest_index == dest.len) return dest_index;
243 dest[pos] = self.buffer[self.index - 1];
244 self.index -= 1;
245 pos += 1;
246 }
247
248 if (pos == dest.len or self.at_end) {
249 return pos;
250 }
251235
252 // ask the backing stream for more236 // ask the backing stream for more
253 const left = dest.len - pos;237 dest_index += try self.base.read(dest[dest_index..]);
254 const read = try self.base.read(dest[pos..]);238 return dest_index;
255 assert(read <= left);
256
257 self.at_end = (read < left);
258 return pos + read;
259 }239 }
260 };240 };
261}241}
lib/std/io/test.zig+4-4
...@@ -97,8 +97,8 @@ test "PeekStream" {...@@ -97,8 +97,8 @@ test "PeekStream" {
9797
98 var dest: [4]u8 = undefined;98 var dest: [4]u8 = undefined;
9999
100 ps.putBackByte(9);100 try ps.putBackByte(9);
101 ps.putBackByte(10);101 try ps.putBackByte(10);
102102
103 var read = try ps.stream.read(dest[0..4]);103 var read = try ps.stream.read(dest[0..4]);
104 expect(read == 4);104 expect(read == 4);
...@@ -114,8 +114,8 @@ test "PeekStream" {...@@ -114,8 +114,8 @@ test "PeekStream" {
114 expect(read == 2);114 expect(read == 2);
115 expect(mem.eql(u8, dest[0..2], bytes[6..8]));115 expect(mem.eql(u8, dest[0..2], bytes[6..8]));
116116
117 ps.putBackByte(11);117 try ps.putBackByte(11);
118 ps.putBackByte(12);118 try ps.putBackByte(12);
119119
120 read = try ps.stream.read(dest[0..4]);120 read = try ps.stream.read(dest[0..4]);
121 expect(read == 2);121 expect(read == 2);