authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-03-27 16:05:41 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-03-27 16:05:41 -07:00
logf52f04adda19250baac614827e88fb66c08ce6ed
tree7d820731e2a1d88bedd6d0b5373ea362102acb06
parent1c536bb7f1f6a633e122e704ad58a022fc7ee288
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

add percentEncodeW and percentDecodeW


1 files changed, 19 insertions(+), 3 deletions(-)

url.zig+19-3
...@@ -1470,20 +1470,23 @@ pub fn percentDecode(allocator: std.mem.Allocator, input: []const u8) ![]u8 {...@@ -1470,20 +1470,23 @@ pub fn percentDecode(allocator: std.mem.Allocator, input: []const u8) ![]u8 {
1470 var result = std.ArrayList(u8).init(allocator);1470 var result = std.ArrayList(u8).init(allocator);
1471 errdefer result.deinit();1471 errdefer result.deinit();
1472 try result.ensureUnusedCapacity(input.len);1472 try result.ensureUnusedCapacity(input.len);
1473 try percentDecodeW(result.writer(), input);
1474 return result.toOwnedSlice();
1475}
1476pub fn percentDecodeW(writer: anytype, input: []const u8) !void {
1473 var i: usize = 0;1477 var i: usize = 0;
1474 while (i < input.len) : (i += 1) {1478 while (i < input.len) : (i += 1) {
1475 if (input[i] == '%') {1479 if (input[i] == '%') {
1476 if (input.len >= i + 1 + 2) {1480 if (input.len >= i + 1 + 2) {
1477 if (std.ascii.isHex(input[i + 1]) and std.ascii.isHex(input[i + 2])) {1481 if (std.ascii.isHex(input[i + 1]) and std.ascii.isHex(input[i + 2])) {
1478 try result.append(extras.parseDigits(u8, input[i + 1 ..][0..2], 16) catch unreachable);1482 try writer.writeAll(&.{extras.parseDigits(u8, input[i + 1 ..][0..2], 16) catch unreachable});
1479 i += 2;1483 i += 2;
1480 continue;1484 continue;
1481 }1485 }
1482 }1486 }
1483 }1487 }
1484 try result.append(input[i]);1488 try writer.writeAll(&.{input[i]});
1485 }1489 }
1486 return result.toOwnedSlice();
1487}1490}
14881491
1489/// https://url.spec.whatwg.org/#concept-domain-to-ascii1492/// https://url.spec.whatwg.org/#concept-domain-to-ascii
...@@ -1799,6 +1802,19 @@ pub fn percentEncodeScalarAL(list: *std.ArrayList(u8), cp: []const u8, comptime...@@ -1799,6 +1802,19 @@ pub fn percentEncodeScalarAL(list: *std.ArrayList(u8), cp: []const u8, comptime
1799 try list.append(cp[0]);1802 try list.append(cp[0]);
1800 }1803 }
1801}1804}
1805pub fn percentEncodeW(writer: anytype, input: []const u8, comptime set: fn (u8) bool) !void {
1806 var it = std.unicode.Utf8View.initUnchecked(input).iterator();
1807 while (it.nextCodepointSlice()) |sl| {
1808 if (set(sl[0])) {
1809 for (sl) |b| {
1810 try writer.writeAll(&.{'%'});
1811 try writer.print("{X:0>2}", .{b});
1812 }
1813 } else {
1814 try writer.writeAll(sl);
1815 }
1816 }
1817}
1802pub fn percentEncodeAL(list: *std.ArrayList(u8), input: []const u8, comptime set: fn (u8) bool) !void {1818pub fn percentEncodeAL(list: *std.ArrayList(u8), input: []const u8, comptime set: fn (u8) bool) !void {
1803 var it = std.unicode.Utf8View.initUnchecked(input).iterator();1819 var it = std.unicode.Utf8View.initUnchecked(input).iterator();
1804 while (it.nextCodepointSlice()) |sl| {1820 while (it.nextCodepointSlice()) |sl| {