Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions src/browser/mime.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
const std = @import("std");
const testing = std.testing;

const strparser = @import("../str/parser.zig");
const Reader = strparser.Reader;
const trim = strparser.trim;
const Reader = @import("../str/parser.zig").Reader;

const Self = @This();

Expand Down Expand Up @@ -70,7 +68,7 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
if (ln > 255) return MimeError.TooBig;

var res = Self{ .mtype = "", .msubtype = "" };
var r = Reader{ .s = s };
var r = Reader{ .data = s };

res.mtype = trim(r.until('/'));
if (res.mtype.len == 0) return MimeError.Invalid;
Expand All @@ -87,7 +85,7 @@ pub fn parse(s: []const u8) Self.MimeError!Self {

// parse well known parameters.
// don't check invalid parameter format.
var rp = Reader{ .s = res.params };
var rp = Reader{ .data = res.params };
while (true) {
const name = trim(rp.until('='));
if (!rp.skip()) return res;
Expand All @@ -106,6 +104,10 @@ pub fn parse(s: []const u8) Self.MimeError!Self {
return res;
}

fn trim(s: []const u8) []const u8 {
return std.mem.trim(u8, s, &std.ascii.whitespace);
}

test "parse valid" {
for ([_][]const u8{
"text/html",
Expand Down
91 changes: 36 additions & 55 deletions src/str/parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,89 +18,70 @@

// some utils to parser strings.
const std = @import("std");
const testing = std.testing;

pub const Reader = struct {
s: []const u8,
i: usize = 0,
pos: usize = 0,
data: []const u8,

pub fn until(self: *Reader, c: u8) []const u8 {
const ln = self.s.len;
const start = self.i;
while (self.i < ln) {
if (c == self.s[self.i]) return self.s[start..self.i];
self.i += 1;
}
const pos = self.pos;
const data = self.data;

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 {
if (self.i > self.s.len) return "";
defer self.i = self.s.len;
return self.s[self.i..];
const pos = self.pos;
const data = self.data;
if (pos > data.len) {
return "";
}
self.pos = data.len;
return data[pos..];
}

pub fn skip(self: *Reader) bool {
if (self.i >= self.s.len) return false;
self.i += 1;
const pos = self.pos;
if (pos >= self.data.len) {
return false;
}
self.pos = pos + 1;
return true;
}
};

test "Reader.skip" {
var r = Reader{ .s = "foo" };
try testing.expect(r.skip());
try testing.expect(r.skip());
try testing.expect(r.skip());
try testing.expect(!r.skip());
try testing.expect(!r.skip());
const testing = std.testing;
test "parser.Reader: skip" {
var r = Reader{ .data = "foo" };
try testing.expectEqual(true, r.skip());
try testing.expectEqual(true, r.skip());
try testing.expectEqual(true, r.skip());
try testing.expectEqual(false, r.skip());
try testing.expectEqual(false, r.skip());
}

test "Reader.tail" {
var r = Reader{ .s = "foo" };
test "parser.Reader: tail" {
var r = Reader{ .data = "foo" };
try testing.expectEqualStrings("foo", r.tail());
try testing.expectEqualStrings("", r.tail());
try testing.expectEqualStrings("", r.tail());
}

test "Reader.until" {
var r = Reader{ .s = "foo.bar.baz" };
test "parser.Reader: until" {
var r = Reader{ .data = "foo.bar.baz" };
try testing.expectEqualStrings("foo", r.until('.'));
_ = r.skip();
try testing.expectEqualStrings("bar", r.until('.'));
_ = r.skip();
try testing.expectEqualStrings("baz", r.until('.'));

r = Reader{ .s = "foo" };
r = Reader{ .data = "foo" };
try testing.expectEqualStrings("foo", r.until('.'));
try testing.expectEqualStrings("", r.tail());

r = Reader{ .s = "" };
r = Reader{ .data = "" };
try testing.expectEqualStrings("", r.until('.'));
}

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"));
try testing.expectEqualStrings("", r.tail());
}
4 changes: 2 additions & 2 deletions src/url/query.zig
Original file line number Diff line number Diff line change
Expand Up @@ -199,12 +199,12 @@ pub fn parseQuery(alloc: std.mem.Allocator, s: []const u8) !Values {
const ln = s.len;
if (ln == 0) return values;

var r = Reader{ .s = s };
var r = Reader{ .data = s };
while (true) {
const param = r.until('&');
if (param.len == 0) break;

var rr = Reader{ .s = param };
var rr = Reader{ .data = param };
const k = rr.until('=');
if (k.len == 0) continue;

Expand Down