1
0
mirror of https://github.com/golang/go synced 2024-09-25 09:10:14 -06:00

json: support \u escaping in strings

Fixes #73.

R=rsc
CC=golang-dev
https://golang.org/cl/154072
This commit is contained in:
Adam Langley 2009-11-11 17:13:14 -08:00
parent ae3341476d
commit 3b092fec36
2 changed files with 28 additions and 12 deletions

View File

@ -21,6 +21,7 @@ var jsontests = []string{
`[1,2,"abc",null,true,false]`,
`{}`,
`{"a":1}`,
`"q\u0302"`,
}
func TestJson(t *testing.T) {

View File

@ -43,6 +43,14 @@ func _UnHex(p string, r, l int) (v int, ok bool) {
return v, true;
}
func _ToHex(b []byte, rune int) {
const hexDigits = "0123456789abcdef";
b[0] = hexDigits[rune>>12&0xf];
b[1] = hexDigits[rune>>8&0xf];
b[2] = hexDigits[rune>>4&0xf];
b[3] = hexDigits[rune&0xf];
}
// Unquote unquotes the JSON-quoted string s,
// returning a raw string t. If s is not a valid
// JSON-quoted string, Unquote returns with ok set to false.
@ -88,7 +96,7 @@ func Unquote(s string) (t string, ok bool) {
w++;
case 'u':
r++;
rune, ok := _UnHex(s, r, 4);
rune, ok := _UnHex(s, r, r+4);
if !ok {
return
}
@ -122,46 +130,53 @@ func Unquote(s string) (t string, ok bool) {
// Quote quotes the raw string s using JSON syntax,
// so that Unquote(Quote(s)) = s, true.
func Quote(s string) string {
chr := make([]byte, utf8.UTFMax);
chr := make([]byte, 6);
chr0 := chr[0:1];
b := new(bytes.Buffer);
chr[0] = '"';
b.Write(chr0);
for i := 0; i < len(s); i++ {
for _, rune := range s {
switch {
case s[i] == '"' || s[i] == '\\':
case rune == '"' || rune == '\\':
chr[0] = '\\';
chr[1] = s[i];
chr[1] = byte(rune);
b.Write(chr[0:2]);
case s[i] == '\b':
case rune == '\b':
chr[0] = '\\';
chr[1] = 'b';
b.Write(chr[0:2]);
case s[i] == '\f':
case rune == '\f':
chr[0] = '\\';
chr[1] = 'f';
b.Write(chr[0:2]);
case s[i] == '\n':
case rune == '\n':
chr[0] = '\\';
chr[1] = 'n';
b.Write(chr[0:2]);
case s[i] == '\r':
case rune == '\r':
chr[0] = '\\';
chr[1] = 'r';
b.Write(chr[0:2]);
case s[i] == '\t':
case rune == '\t':
chr[0] = '\\';
chr[1] = 't';
b.Write(chr[0:2]);
case 0x20 <= s[i] && s[i] < utf8.RuneSelf:
chr[0] = s[i];
case 0x20 <= rune && rune < utf8.RuneSelf:
chr[0] = byte(rune);
b.Write(chr0);
default:
chr[0] = '\\';
chr[1] = 'u';
_ToHex(chr[2:6], rune);
b.Write(chr);
}
}
chr[0] = '"';