| ... | @@ -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 | } |
| | 1476 | pub 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 | } |
| 1488 | | 1491 | |
| 1489 | /// https://url.spec.whatwg.org/#concept-domain-to-ascii | 1492 | /// 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 | } |
| | 1805 | pub 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 | } |
| 1802 | pub fn percentEncodeAL(list: *std.ArrayList(u8), input: []const u8, comptime set: fn (u8) bool) !void { | 1818 | pub 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| { |