zig
zig copied to clipboard
add equivilant functionality from std.mem.indexOf{Any,None} to reader.*Delim*
There are some use cases in which you may want to read until a whitespace or discard all whitespaces.
It is also possible to make it ~generic :
// this code is taken from zig 0.15.0 stdlib => peekDelimiterInclusive
// with std.mem.indexOfScalar replaced with indexOfPos_func
fn peekUntilInclusiveGeneric(reader: *std.io.Reader, indexOfPos_func: fn (buf:[]u8, pos:usize) ?usize) ![]u8 {
const buffer = reader.buffer[0..reader.end];
const seek = reader.seek;
if (indexOfPos_func(u8, buffer, seek)) |end| {
@branchHint(.likely);
return buffer[seek..end + 1];
}
try reader.rebase(reader.buffer.len);
while (reader.buffer.len - reader.end != 0) {
const end_cap = reader.buffer[reader.end..];
var writer: std.io.Writer = .fixed(end_cap);
const n = reader.vtable.stream(reader, &writer, .limited(end_cap.len)) catch |err| switch (err) {
error.WriteFailed => unreachable,
else => |e| return e,
};
reader.end += n;
if (indexOfPos_func(end_cap[0..n], 0)) |end| {
return reader.buffer[0 .. reader.end - n + end + 1];
}
}
return error.StreamTooLong;
}
and usage will be :
fn foo(reader: *Reader) {
reader.peekUntilInclusiveGeneric(struct {
pub fn indexOf(buf:[]u8, pos:usize) ?usize {
return std.mem.indexOfAnyPos(u8, buf, pos, std.ascii.whitespace);
}
}.indexOf);
}
also the original peekDelimiterInclusive would be :
fn peekDelimiterInclusive_new(reader: *std.io.Reader, delim: u8) ?usize) ![]u8 {
return reader.peekUntilInclusiveGeneric(struct {
pub fn indexOf(buf:[]u8, pos:usize) ?usize {
return std.mem.indexOfScalarPos(u8, buf, pos, delim);
}
}.indexOf);
}