json2: unescape characters (#6836)
parent
c8b7cfc297
commit
fe3d2a9aba
|
@ -223,8 +223,6 @@ fn (mut p Parser) decode_value() ?Any {
|
||||||
fn (mut p Parser) decode_string() ?Any {
|
fn (mut p Parser) decode_string() ?Any {
|
||||||
mut strwr := strings.new_builder(200)
|
mut strwr := strings.new_builder(200)
|
||||||
for i := 0; i < p.tok.lit.len; i++ {
|
for i := 0; i < p.tok.lit.len; i++ {
|
||||||
// s := p.tok.lit[i].str()
|
|
||||||
// println('$i $s')
|
|
||||||
if ((i-1 >= 0 && p.tok.lit[i-1] != `/`) || i == 0) && int(p.tok.lit[i]) in [9, 10, 0] {
|
if ((i-1 >= 0 && p.tok.lit[i-1] != `/`) || i == 0) && int(p.tok.lit[i]) in [9, 10, 0] {
|
||||||
return error('character must be escaped with a backslash.')
|
return error('character must be escaped with a backslash.')
|
||||||
}
|
}
|
||||||
|
@ -235,8 +233,33 @@ fn (mut p Parser) decode_string() ?Any {
|
||||||
|
|
||||||
if i+1 < p.tok.lit.len && p.tok.lit[i] == 92 {
|
if i+1 < p.tok.lit.len && p.tok.lit[i] == 92 {
|
||||||
peek := p.tok.lit[i+1]
|
peek := p.tok.lit[i+1]
|
||||||
if peek in [`b`, `f`, `n`, `r`, `t`, `u`, `\\`, `"`, `/`] {
|
match peek{
|
||||||
if peek == `u` {
|
`b` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`\b`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
`f` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`\f`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
`n` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`\n`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
`r` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`\r`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
`t` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`\t`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
`u` {
|
||||||
if i+5 < p.tok.lit.len {
|
if i+5 < p.tok.lit.len {
|
||||||
codepoint := p.tok.lit[i+2..i+6]
|
codepoint := p.tok.lit[i+2..i+6]
|
||||||
check_valid_hex(codepoint)?
|
check_valid_hex(codepoint)?
|
||||||
|
@ -248,12 +271,22 @@ fn (mut p Parser) decode_string() ?Any {
|
||||||
return error('incomplete unicode escape.')
|
return error('incomplete unicode escape.')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
`\\` {
|
||||||
i++
|
i++
|
||||||
strwr.write_b(p.tok.lit[i])
|
strwr.write_b(`\\`)
|
||||||
continue
|
continue
|
||||||
} else {
|
}
|
||||||
return error('invalid backslash escape.')
|
`"` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`\"`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
`/` {
|
||||||
|
i++
|
||||||
|
strwr.write_b(`/`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
else { return error('invalid backslash escape.') }
|
||||||
}
|
}
|
||||||
|
|
||||||
if int(peek) == 85 {
|
if int(peek) == 85 {
|
||||||
|
|
|
@ -7,7 +7,11 @@ import strings
|
||||||
|
|
||||||
fn write_value(v Any, i int, len int, mut wr strings.Builder) {
|
fn write_value(v Any, i int, len int, mut wr strings.Builder) {
|
||||||
str := v.str()
|
str := v.str()
|
||||||
wr.write(if v is string { '"$str"' } else { str })
|
if v is string {
|
||||||
|
wr.write('"$str"')
|
||||||
|
} else {
|
||||||
|
wr.write(str)
|
||||||
|
}
|
||||||
if i >= len-1 { return }
|
if i >= len-1 { return }
|
||||||
wr.write_b(`,`)
|
wr.write_b(`,`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,28 @@ fn test_fast_raw_decode() {
|
||||||
assert str == '{"name":"Peter","age":"28","salary":"95000.5","title":"2"}'
|
assert str == '{"name":"Peter","age":"28","salary":"95000.5","title":"2"}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_character_unescape() {
|
||||||
|
// Need to test `\r`, `\b`, `\f` ??
|
||||||
|
message := '{
|
||||||
|
"newline":"new\\nline",
|
||||||
|
"tab":"\\ttab",
|
||||||
|
"backslash": "back\\\\slash",
|
||||||
|
"quotes": "\\"quotes\\"",
|
||||||
|
"slash":"\/dev\/null"
|
||||||
|
}'
|
||||||
|
mut obj := json2.raw_decode(message) or {
|
||||||
|
assert false
|
||||||
|
json2.Any{}
|
||||||
|
}
|
||||||
|
lines := obj.as_map()
|
||||||
|
eprintln("$lines")
|
||||||
|
assert lines['newline'].str() == 'new\nline'
|
||||||
|
assert lines['tab'].str() == '\ttab'
|
||||||
|
assert lines['backslash'].str() == 'back\\slash'
|
||||||
|
assert lines['quotes'].str() == '\"quotes\"'
|
||||||
|
assert lines['slash'].str() == '/dev/null'
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
struct User2 {
|
struct User2 {
|
||||||
age int
|
age int
|
||||||
|
|
Loading…
Reference in New Issue