authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2019-09-03 04:24:39+10:00
committergravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2019-12-30 22:34:19+11:00
log17cc511ea431c872e4312843f90297b2d552fb3d
tree374bd4c2752d8b98b2147aa5af043659f0efcbcb
parentc70a673c6eb92383d2a8e026374b4b23647db059
signaturelock-open Commit is signed but in an unrecognized format.

std: fmt std/json.zig


1 files changed, 27 insertions(+), 25 deletions(-)

lib/std/json.zig+27-25
......@@ -15,12 +15,16 @@ pub const WriteStream = @import("json/write_stream.zig").WriteStream;
1515/// Use `token.slice()` on the input at the current position to get the current slice.
1616pub const Token = struct {
1717 id: Id,
18
1819 /// How many bytes do we skip before counting
1920 offset: u1,
21
2022 /// Whether string contains an escape sequence and cannot be zero-copied
2123 string_has_escape: bool,
24
2225 /// Whether number is simple and can be represented by an integer (i.e. no `.` or `e`)
2326 number_is_integer: bool,
27
2428 /// How many bytes from the current position behind the start of this token is.
2529 count: usize,
2630
......@@ -1299,54 +1303,52 @@ pub const Parser = struct {
12991303fn unescapeStringAlloc(alloc: *Allocator, input: []const u8) ![]u8 {
13001304 const output = try alloc.alloc(u8, input.len);
13011305 errdefer alloc.free(output);
1302
1306
13031307 var inIndex: usize = 0;
13041308 var outIndex: usize = 0;
13051309
1306 while(inIndex < input.len) {
1307 if(input[inIndex] != '\\'){
1310 while (inIndex < input.len) {
1311 if (input[inIndex] != '\\') {
13081312 // not an escape sequence
13091313 output[outIndex] = input[inIndex];
13101314 inIndex += 1;
13111315 outIndex += 1;
1312 } else if(input[inIndex + 1] != 'u'){
1316 } else if (input[inIndex + 1] != 'u') {
13131317 // a simple escape sequence
1314 output[outIndex] = @as(u8,
1315 switch(input[inIndex + 1]){
1316 '\\' => '\\',
1317 '/' => '/',
1318 'n' => '\n',
1319 'r' => '\r',
1320 't' => '\t',
1321 'f' => 12,
1322 'b' => 8,
1323 '"' => '"',
1324 else => unreachable
1325 }
1326 );
1318 output[outIndex] = @as(u8, switch (input[inIndex + 1]) {
1319 '\\' => '\\',
1320 '/' => '/',
1321 'n' => '\n',
1322 'r' => '\r',
1323 't' => '\t',
1324 'f' => 12,
1325 'b' => 8,
1326 '"' => '"',
1327 else => unreachable,
1328 });
13271329 inIndex += 2;
13281330 outIndex += 1;
13291331 } else {
13301332 // a unicode escape sequence
1331 const firstCodeUnit = std.fmt.parseInt(u16, input[inIndex+2 .. inIndex+6], 16) catch unreachable;
1333 const firstCodeUnit = std.fmt.parseInt(u16, input[inIndex + 2 .. inIndex + 6], 16) catch unreachable;
13321334
13331335 // guess optimistically that it's not a surrogate pair
1334 if(std.unicode.utf8Encode(firstCodeUnit, output[outIndex..])) |byteCount| {
1336 if (std.unicode.utf8Encode(firstCodeUnit, output[outIndex..])) |byteCount| {
13351337 outIndex += byteCount;
13361338 inIndex += 6;
13371339 } else |err| {
13381340 // it might be a surrogate pair
1339 if(err != error.Utf8CannotEncodeSurrogateHalf) {
1341 if (err != error.Utf8CannotEncodeSurrogateHalf) {
13401342 return error.InvalidUnicodeHexSymbol;
13411343 }
13421344 // check if a second code unit is present
1343 if(inIndex + 7 >= input.len or input[inIndex + 6] != '\\' or input[inIndex + 7] != 'u'){
1345 if (inIndex + 7 >= input.len or input[inIndex + 6] != '\\' or input[inIndex + 7] != 'u') {
13441346 return error.InvalidUnicodeHexSymbol;
13451347 }
1346
1347 const secondCodeUnit = std.fmt.parseInt(u16, input[inIndex+8 .. inIndex+12], 16) catch unreachable;
1348
1349 if(std.unicode.utf16leToUtf8(output[outIndex..], &[2]u16{ firstCodeUnit, secondCodeUnit })) |byteCount| {
1348
1349 const secondCodeUnit = std.fmt.parseInt(u16, input[inIndex + 8 .. inIndex + 12], 16) catch unreachable;
1350
1351 if (std.unicode.utf16leToUtf8(output[outIndex..], &[2]u16{ firstCodeUnit, secondCodeUnit })) |byteCount| {
13501352 outIndex += byteCount;
13511353 inIndex += 12;
13521354 } else |_| {