mirror of
https://github.com/ziglang/zig.git
synced 2025-12-22 06:03:16 +00:00
std: use LinearFifo to implement io.PeekStream
This commit is contained in:
parent
bdff2f43bd
commit
38ad7daebb
@ -196,7 +196,7 @@ test "io.BufferedInStream" {
|
|||||||
|
|
||||||
/// Creates a stream which supports 'un-reading' data, so that it can be read again.
|
/// Creates a stream which supports 'un-reading' data, so that it can be read again.
|
||||||
/// This makes look-ahead style parsing much easier.
|
/// This makes look-ahead style parsing much easier.
|
||||||
pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) type {
|
pub fn PeekStream(comptime buffer_type: usize, comptime InStreamError: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
pub const Error = InStreamError;
|
pub const Error = InStreamError;
|
||||||
@ -207,55 +207,35 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
|
|||||||
|
|
||||||
// Right now the look-ahead space is statically allocated, but a version with dynamic allocation
|
// Right now the look-ahead space is statically allocated, but a version with dynamic allocation
|
||||||
// is not too difficult to derive from this.
|
// is not too difficult to derive from this.
|
||||||
buffer: [buffer_size]u8,
|
const FifoType = std.fifo.LinearFifo(u8, .{ .Static = buffer_size });
|
||||||
index: usize,
|
fifo: FifoType,
|
||||||
at_end: bool,
|
|
||||||
|
|
||||||
pub fn init(base: *Stream) Self {
|
pub fn init(base: *Stream) Self {
|
||||||
return Self{
|
return .{
|
||||||
.base = base,
|
.base = base,
|
||||||
.buffer = undefined,
|
.fifo = FifoType.init(),
|
||||||
.index = 0,
|
|
||||||
.at_end = false,
|
|
||||||
.stream = Stream{ .readFn = readFn },
|
.stream = Stream{ .readFn = readFn },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn putBackByte(self: *Self, byte: u8) void {
|
pub fn putBackByte(self: *Self, byte: u8) !void {
|
||||||
self.buffer[self.index] = byte;
|
try self.putBack(@ptrCast([*]const u8, &byte)[0..1]);
|
||||||
self.index += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn putBack(self: *Self, bytes: []const u8) void {
|
pub fn putBack(self: *Self, bytes: []const u8) !void {
|
||||||
var pos = bytes.len;
|
try self.fifo.unget(bytes);
|
||||||
while (pos != 0) {
|
|
||||||
pos -= 1;
|
|
||||||
self.putBackByte(bytes[pos]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readFn(in_stream: *Stream, dest: []u8) Error!usize {
|
fn readFn(in_stream: *Stream, dest: []u8) Error!usize {
|
||||||
const self = @fieldParentPtr(Self, "stream", in_stream);
|
const self = @fieldParentPtr(Self, "stream", in_stream);
|
||||||
|
|
||||||
// copy over anything putBack()'d
|
// copy over anything putBack()'d
|
||||||
var pos: usize = 0;
|
var dest_index = self.fifo.read(dest);
|
||||||
while (pos < dest.len and self.index != 0) {
|
if (dest_index == dest.len) return dest_index;
|
||||||
dest[pos] = self.buffer[self.index - 1];
|
|
||||||
self.index -= 1;
|
|
||||||
pos += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos == dest.len or self.at_end) {
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ask the backing stream for more
|
// ask the backing stream for more
|
||||||
const left = dest.len - pos;
|
dest_index += try self.base.read(dest[dest_index..]);
|
||||||
const read = try self.base.read(dest[pos..]);
|
return dest_index;
|
||||||
assert(read <= left);
|
|
||||||
|
|
||||||
self.at_end = (read < left);
|
|
||||||
return pos + read;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,8 +97,8 @@ test "PeekStream" {
|
|||||||
|
|
||||||
var dest: [4]u8 = undefined;
|
var dest: [4]u8 = undefined;
|
||||||
|
|
||||||
ps.putBackByte(9);
|
try ps.putBackByte(9);
|
||||||
ps.putBackByte(10);
|
try ps.putBackByte(10);
|
||||||
|
|
||||||
var read = try ps.stream.read(dest[0..4]);
|
var read = try ps.stream.read(dest[0..4]);
|
||||||
expect(read == 4);
|
expect(read == 4);
|
||||||
@ -114,8 +114,8 @@ test "PeekStream" {
|
|||||||
expect(read == 2);
|
expect(read == 2);
|
||||||
expect(mem.eql(u8, dest[0..2], bytes[6..8]));
|
expect(mem.eql(u8, dest[0..2], bytes[6..8]));
|
||||||
|
|
||||||
ps.putBackByte(11);
|
try ps.putBackByte(11);
|
||||||
ps.putBackByte(12);
|
try ps.putBackByte(12);
|
||||||
|
|
||||||
read = try ps.stream.read(dest[0..4]);
|
read = try ps.stream.read(dest[0..4]);
|
||||||
expect(read == 2);
|
expect(read == 2);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user