mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
Minor Reader tweaks
1- Remove `parser.trim`, it was only being used in 1 place. All other places are using `std.mem.trim(u8, X, &std.ascii.whitespace)`, so i updated MIME to use this as well 2- Use slightly more meaningful field name, i => pos, s = data 3- Leverage std.mem.indexOfScalarPos which can be more efficient for longer inputs (since it leverages SIMD)
This commit is contained in:
@@ -19,9 +19,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
const strparser = @import("../str/parser.zig");
|
const Reader = @import("../str/parser.zig").Reader;
|
||||||
const Reader = strparser.Reader;
|
|
||||||
const trim = strparser.trim;
|
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
@@ -70,7 +68,7 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
|
|||||||
if (ln > 255) return MimeError.TooBig;
|
if (ln > 255) return MimeError.TooBig;
|
||||||
|
|
||||||
var res = Self{ .mtype = "", .msubtype = "" };
|
var res = Self{ .mtype = "", .msubtype = "" };
|
||||||
var r = Reader{ .s = s };
|
var r = Reader{ .data = s };
|
||||||
|
|
||||||
res.mtype = trim(r.until('/'));
|
res.mtype = trim(r.until('/'));
|
||||||
if (res.mtype.len == 0) return MimeError.Invalid;
|
if (res.mtype.len == 0) return MimeError.Invalid;
|
||||||
@@ -87,7 +85,7 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
|
|||||||
|
|
||||||
// parse well known parameters.
|
// parse well known parameters.
|
||||||
// don't check invalid parameter format.
|
// don't check invalid parameter format.
|
||||||
var rp = Reader{ .s = res.params };
|
var rp = Reader{ .data = res.params };
|
||||||
while (true) {
|
while (true) {
|
||||||
const name = trim(rp.until('='));
|
const name = trim(rp.until('='));
|
||||||
if (!rp.skip()) return res;
|
if (!rp.skip()) return res;
|
||||||
@@ -106,6 +104,10 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trim(s: []const u8) []const u8 {
|
||||||
|
return std.mem.trim(u8, s, &std.ascii.whitespace);
|
||||||
|
}
|
||||||
|
|
||||||
test "parse valid" {
|
test "parse valid" {
|
||||||
for ([_][]const u8{
|
for ([_][]const u8{
|
||||||
"text/html",
|
"text/html",
|
||||||
|
|||||||
@@ -18,89 +18,70 @@
|
|||||||
|
|
||||||
// some utils to parser strings.
|
// some utils to parser strings.
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const testing = std.testing;
|
|
||||||
|
|
||||||
pub const Reader = struct {
|
pub const Reader = struct {
|
||||||
s: []const u8,
|
pos: usize = 0,
|
||||||
i: usize = 0,
|
data: []const u8,
|
||||||
|
|
||||||
pub fn until(self: *Reader, c: u8) []const u8 {
|
pub fn until(self: *Reader, c: u8) []const u8 {
|
||||||
const ln = self.s.len;
|
const pos = self.pos;
|
||||||
const start = self.i;
|
const data = self.data;
|
||||||
while (self.i < ln) {
|
|
||||||
if (c == self.s[self.i]) return self.s[start..self.i];
|
|
||||||
self.i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.s[start..self.i];
|
const index = std.mem.indexOfScalarPos(u8, data, pos, c) orelse data.len;
|
||||||
|
self.pos = index;
|
||||||
|
return data[pos..index];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tail(self: *Reader) []const u8 {
|
pub fn tail(self: *Reader) []const u8 {
|
||||||
if (self.i > self.s.len) return "";
|
const pos = self.pos;
|
||||||
defer self.i = self.s.len;
|
const data = self.data;
|
||||||
return self.s[self.i..];
|
if (pos > data.len) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
self.pos = data.len;
|
||||||
|
return data[pos..];
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn skip(self: *Reader) bool {
|
pub fn skip(self: *Reader) bool {
|
||||||
if (self.i >= self.s.len) return false;
|
const pos = self.pos;
|
||||||
self.i += 1;
|
if (pos >= self.data.len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.pos = pos + 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test "Reader.skip" {
|
const testing = std.testing;
|
||||||
var r = Reader{ .s = "foo" };
|
test "parser.Reader: skip" {
|
||||||
try testing.expect(r.skip());
|
var r = Reader{ .data = "foo" };
|
||||||
try testing.expect(r.skip());
|
try testing.expectEqual(true, r.skip());
|
||||||
try testing.expect(r.skip());
|
try testing.expectEqual(true, r.skip());
|
||||||
try testing.expect(!r.skip());
|
try testing.expectEqual(true, r.skip());
|
||||||
try testing.expect(!r.skip());
|
try testing.expectEqual(false, r.skip());
|
||||||
|
try testing.expectEqual(false, r.skip());
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Reader.tail" {
|
test "parser.Reader: tail" {
|
||||||
var r = Reader{ .s = "foo" };
|
var r = Reader{ .data = "foo" };
|
||||||
try testing.expectEqualStrings("foo", r.tail());
|
try testing.expectEqualStrings("foo", r.tail());
|
||||||
try testing.expectEqualStrings("", r.tail());
|
try testing.expectEqualStrings("", r.tail());
|
||||||
|
try testing.expectEqualStrings("", r.tail());
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Reader.until" {
|
test "parser.Reader: until" {
|
||||||
var r = Reader{ .s = "foo.bar.baz" };
|
var r = Reader{ .data = "foo.bar.baz" };
|
||||||
try testing.expectEqualStrings("foo", r.until('.'));
|
try testing.expectEqualStrings("foo", r.until('.'));
|
||||||
_ = r.skip();
|
_ = r.skip();
|
||||||
try testing.expectEqualStrings("bar", r.until('.'));
|
try testing.expectEqualStrings("bar", r.until('.'));
|
||||||
_ = r.skip();
|
_ = r.skip();
|
||||||
try testing.expectEqualStrings("baz", r.until('.'));
|
try testing.expectEqualStrings("baz", r.until('.'));
|
||||||
|
|
||||||
r = Reader{ .s = "foo" };
|
r = Reader{ .data = "foo" };
|
||||||
try testing.expectEqualStrings("foo", r.until('.'));
|
try testing.expectEqualStrings("foo", r.until('.'));
|
||||||
|
try testing.expectEqualStrings("", r.tail());
|
||||||
|
|
||||||
r = Reader{ .s = "" };
|
r = Reader{ .data = "" };
|
||||||
try testing.expectEqualStrings("", r.until('.'));
|
try testing.expectEqualStrings("", r.until('.'));
|
||||||
}
|
try testing.expectEqualStrings("", r.tail());
|
||||||
|
|
||||||
pub fn trim(s: []const u8) []const u8 {
|
|
||||||
const ln = s.len;
|
|
||||||
if (ln == 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
var start: usize = 0;
|
|
||||||
while (start < ln) {
|
|
||||||
if (!std.ascii.isWhitespace(s[start])) break;
|
|
||||||
start += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var end: usize = ln;
|
|
||||||
while (end > 0) {
|
|
||||||
if (!std.ascii.isWhitespace(s[end - 1])) break;
|
|
||||||
end -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s[start..end];
|
|
||||||
}
|
|
||||||
|
|
||||||
test "trim" {
|
|
||||||
try testing.expectEqualStrings("", trim(""));
|
|
||||||
try testing.expectEqualStrings("foo", trim("foo"));
|
|
||||||
try testing.expectEqualStrings("foo", trim(" \n\tfoo"));
|
|
||||||
try testing.expectEqualStrings("foo", trim("foo \n\t"));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,12 +199,12 @@ pub fn parseQuery(alloc: std.mem.Allocator, s: []const u8) !Values {
|
|||||||
const ln = s.len;
|
const ln = s.len;
|
||||||
if (ln == 0) return values;
|
if (ln == 0) return values;
|
||||||
|
|
||||||
var r = Reader{ .s = s };
|
var r = Reader{ .data = s };
|
||||||
while (true) {
|
while (true) {
|
||||||
const param = r.until('&');
|
const param = r.until('&');
|
||||||
if (param.len == 0) break;
|
if (param.len == 0) break;
|
||||||
|
|
||||||
var rr = Reader{ .s = param };
|
var rr = Reader{ .data = param };
|
||||||
const k = rr.until('=');
|
const k = rr.until('=');
|
||||||
if (k.len == 0) continue;
|
if (k.len == 0) continue;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user