json2: reorganize encode string (#20862)

This commit is contained in:
Hitalo Souza 2024-02-18 09:43:15 -04:00 committed by GitHub
parent 2568d336f8
commit f472355ef7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -415,17 +415,21 @@ fn (mut iter CharLengthIterator) next() ?int {
if iter.idx >= iter.text.len { if iter.idx >= iter.text.len {
return none return none
} }
defer { defer {
iter.idx++ iter.idx++
} }
mut len := 1 mut len := 1
c := iter.text[iter.idx] c := iter.text[iter.idx]
if (c & (1 << 7)) != 0 { if (c & (1 << 7)) != 0 {
for t := u8(1 << 6); (c & t) != 0; t >>= 1 { for t := u8(1 << 6); (c & t) != 0; t >>= 1 {
len++ len++
iter.idx++ iter.idx++
} }
} }
return len return len
} }
@ -438,9 +442,27 @@ fn (e &Encoder) encode_string(s string, mut buf []u8) ! {
} }
mut i := 0 mut i := 0
buf << json2.quote_rune buf << json2.quote_rune
for char_len in char_lens { for char_len in char_lens {
if char_len == 1 {
chr := s[i] chr := s[i]
if (char_len == 1 && chr < 0x20) || chr == `\\` || chr == `"` || chr == `/` {
handle_special_char(e, mut buf, chr)
} else {
if char_len == 1 {
buf << chr
} else {
handle_multi_byte_char(e, mut buf, s[i..i + char_len])
}
}
i += char_len
}
buf << json2.quote_rune
}
fn handle_special_char(e &Encoder, mut buf []u8, chr u8) {
if chr in important_escapable_chars { if chr in important_escapable_chars {
for j := 0; j < important_escapable_chars.len; j++ { for j := 0; j < important_escapable_chars.len; j++ {
if chr == important_escapable_chars[j] { if chr == important_escapable_chars[j] {
@ -451,29 +473,26 @@ fn (e &Encoder) encode_string(s string, mut buf []u8) ! {
} else if chr == `"` || chr == `/` || chr == `\\` { } else if chr == `"` || chr == `/` || chr == `\\` {
buf << `\\` buf << `\\`
buf << chr buf << chr
} else if int(chr) < 0x20 { } else {
// unsafe { buf.push_many(json2.unicode_escape_chars.str, json2.unicode_escape_chars.len) } // \u
for r in json2.unicode_escape_chars { for r in json2.unicode_escape_chars {
buf << r buf << r
} }
buf << json2.zero_rune // \u0 buf << json2.zero_rune // \u0
buf << json2.zero_rune // \u00 buf << json2.zero_rune // \u00
hex_code := chr.hex() hex_code := chr.hex()
unsafe { buf.push_many(hex_code.str, hex_code.len) } unsafe { buf.push_many(hex_code.str, hex_code.len) }
} else {
buf << chr
} }
} else { }
slice := s[i..i + char_len]
hex_code := slice.utf32_code().hex() fn handle_multi_byte_char(e &Encoder, mut buf []u8, slice string) {
hex_code := slice.utf32_code().hex() // slow
if !e.escape_unicode || hex_code.len < 4 { if !e.escape_unicode || hex_code.len < 4 {
// unescaped non-ASCII char
unsafe { buf.push_many(slice.str, slice.len) } unsafe { buf.push_many(slice.str, slice.len) }
} else if hex_code.len == 4 { } else if hex_code.len == 4 {
// a unicode endpoint // Handle unicode endpoint
// unsafe { buf.push_many(json2.unicode_escape_chars.str, json2.unicode_escape_chars.len) }
for r in json2.unicode_escape_chars { for r in json2.unicode_escape_chars {
buf << r buf << r
} }
@ -485,13 +504,9 @@ fn (e &Encoder) encode_string(s string, mut buf []u8) ! {
// so just passing it along should hopefully also work. // so just passing it along should hopefully also work.
unsafe { buf.push_many(slice.str, slice.len) } unsafe { buf.push_many(slice.str, slice.len) }
} }
unsafe { unsafe {
slice.free() slice.free()
hex_code.free() hex_code.free()
} }
}
i += char_len
}
buf << json2.quote_rune
} }