encoder: simplify quoted strings escaping
This commit is contained in:
+11
-26
@@ -10,7 +10,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Marshal serializes a Go value as a TOML document.
|
// Marshal serializes a Go value as a TOML document.
|
||||||
@@ -222,51 +221,37 @@ func (enc *Encoder) encodeLiteralString(b []byte, v string) []byte {
|
|||||||
|
|
||||||
func (enc *Encoder) encodeQuotedString(b []byte, v string) []byte {
|
func (enc *Encoder) encodeQuotedString(b []byte, v string) []byte {
|
||||||
const stringQuote = '"'
|
const stringQuote = '"'
|
||||||
|
const hextable = "0123456789ABCDEF"
|
||||||
|
|
||||||
b = append(b, stringQuote)
|
b = append(b, stringQuote)
|
||||||
|
|
||||||
for _, r := range v {
|
for _, r := range []byte(v) {
|
||||||
switch r {
|
switch r {
|
||||||
case '\\':
|
case '\\':
|
||||||
b = append(b, `\\`...)
|
b = append(b, `\\`...)
|
||||||
continue
|
|
||||||
case '"':
|
case '"':
|
||||||
b = append(b, `\"`...)
|
b = append(b, `\"`...)
|
||||||
continue
|
|
||||||
case '\b':
|
case '\b':
|
||||||
b = append(b, `\b`...)
|
b = append(b, `\b`...)
|
||||||
continue
|
|
||||||
case '\f':
|
case '\f':
|
||||||
b = append(b, `\f`...)
|
b = append(b, `\f`...)
|
||||||
continue
|
|
||||||
case '\n':
|
case '\n':
|
||||||
b = append(b, `\n`...)
|
b = append(b, `\n`...)
|
||||||
continue
|
|
||||||
case '\r':
|
case '\r':
|
||||||
b = append(b, `\r`...)
|
b = append(b, `\r`...)
|
||||||
continue
|
|
||||||
case '\t':
|
case '\t':
|
||||||
b = append(b, `\t`...)
|
b = append(b, `\t`...)
|
||||||
continue
|
default:
|
||||||
}
|
switch {
|
||||||
if r == 0x20 || r == 0x09 || r == 0x21 || (r >= 0x23 && r <= 0x5B) || (r >= 0x5D && r <= 0x7E) {
|
case r >= 0x0 && r <= 0x8, r >= 0xA && r <= 0x1F, r == 0x7F:
|
||||||
b = append(b, byte(r))
|
b = append(b, `\u00`...)
|
||||||
} else if (r >= 0x80 && r <= 0xD7FF) || (r >= 0xE000 && r <= 0x10FFFF) {
|
b = append(b, hextable[r>>4])
|
||||||
l := utf8.RuneLen(r)
|
b = append(b, hextable[r&0x0f])
|
||||||
buf := make([]byte, l)
|
default:
|
||||||
utf8.EncodeRune(buf, r)
|
b = append(b, r)
|
||||||
b = append(b, buf...)
|
|
||||||
} else {
|
|
||||||
var h []byte
|
|
||||||
if r > 0xFFFF {
|
|
||||||
h = []byte(fmt.Sprintf("%08x", r))
|
|
||||||
|
|
||||||
} else {
|
|
||||||
h = []byte(fmt.Sprintf("%04x", r))
|
|
||||||
}
|
}
|
||||||
b = append(b, `\u`...)
|
|
||||||
b = append(b, h...)
|
|
||||||
}
|
}
|
||||||
|
// U+0000 to U+0008, U+000A to U+001F, U+007F
|
||||||
}
|
}
|
||||||
|
|
||||||
b = append(b, stringQuote)
|
b = append(b, stringQuote)
|
||||||
|
|||||||
@@ -174,6 +174,48 @@ name = 'Bob'
|
|||||||
name = 'Alice'
|
name = 'Alice'
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
desc: "string escapes",
|
||||||
|
v: map[string]interface{}{
|
||||||
|
"a": `'"\`,
|
||||||
|
},
|
||||||
|
expected: `a = "'\"\\"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "string utf8 low",
|
||||||
|
v: map[string]interface{}{
|
||||||
|
"a": "'Ę",
|
||||||
|
},
|
||||||
|
expected: `a = "'Ę"`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "string utf8 low 2",
|
||||||
|
v: map[string]interface{}{
|
||||||
|
"a": "'\u10A85",
|
||||||
|
},
|
||||||
|
expected: "a = \"'\u10A85\"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "string utf8 low 2",
|
||||||
|
v: map[string]interface{}{
|
||||||
|
"a": "'\u10A85",
|
||||||
|
},
|
||||||
|
expected: "a = \"'\u10A85\"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "emoji",
|
||||||
|
v: map[string]interface{}{
|
||||||
|
"a": "'😀",
|
||||||
|
},
|
||||||
|
expected: "a = \"'😀\"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
desc: "control char",
|
||||||
|
v: map[string]interface{}{
|
||||||
|
"a": "'\u001A",
|
||||||
|
},
|
||||||
|
expected: `a = "'\u001A"`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, e := range examples {
|
for _, e := range examples {
|
||||||
|
|||||||
Reference in New Issue
Block a user