commit 4ddbe4cccf1017685edfbaf701f8248d743597e8
parent 8509e0d6dff41d388f3580537e58771bca26adb8
Author: francoispqt <francois@parquet.ninja>
Date: Sat, 5 May 2018 00:35:08 +0800
add escaping sequence for encoding
Diffstat:
3 files changed, 80 insertions(+), 8 deletions(-)
diff --git a/encode_builder.go b/encode_builder.go
@@ -1,7 +1,6 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-
package gojay
// grow grows b's capacity, if necessary, to guarantee space for
@@ -35,3 +34,26 @@ func (enc *Encoder) writeByte(c byte) {
func (enc *Encoder) writeString(s string) {
enc.buf = append(enc.buf, s...)
}
+
+func (enc *Encoder) writeStringEscape(s string) {
+ l := len(s)
+ for i := 0; i < l; i++ {
+ switch s[i] {
+ case '\\', '"':
+ enc.writeByte('\\')
+ enc.writeByte(s[i])
+ case '\n':
+ enc.writeByte('\\')
+ enc.writeByte('n')
+ case '\r':
+ enc.writeByte('\\')
+ enc.writeByte('r')
+ case '\t':
+ enc.writeByte('\\')
+ enc.writeByte('t')
+ default:
+ enc.writeByte(s[i])
+ }
+ }
+
+}
diff --git a/encode_string.go b/encode_string.go
@@ -17,7 +17,7 @@ func (enc *Encoder) EncodeString(s string) error {
// encodeString encodes a string to
func (enc *Encoder) encodeString(v string) ([]byte, error) {
enc.writeByte('"')
- enc.writeString(v)
+ enc.writeStringEscape(v)
enc.writeByte('"')
return enc.buf, nil
}
@@ -29,7 +29,7 @@ func (enc *Encoder) AddString(v string) {
enc.writeByte(',')
}
enc.writeByte('"')
- enc.writeString(v)
+ enc.writeStringEscape(v)
enc.writeByte('"')
}
@@ -44,7 +44,7 @@ func (enc *Encoder) AddStringOmitEmpty(v string) {
enc.writeByte(',')
}
enc.writeByte('"')
- enc.writeString(v)
+ enc.writeStringEscape(v)
enc.writeByte('"')
}
@@ -55,9 +55,9 @@ func (enc *Encoder) AddStringKey(key, v string) {
enc.writeByte(',')
}
enc.writeByte('"')
- enc.writeString(key)
+ enc.writeStringEscape(key)
enc.writeBytes(objKeyStr)
- enc.writeString(v)
+ enc.writeStringEscape(v)
enc.writeByte('"')
}
@@ -72,8 +72,8 @@ func (enc *Encoder) AddStringKeyOmitEmpty(key, v string) {
enc.writeByte(',')
}
enc.writeByte('"')
- enc.writeString(key)
+ enc.writeStringEscape(key)
enc.writeBytes(objKeyStr)
- enc.writeString(v)
+ enc.writeStringEscape(v)
enc.writeByte('"')
}
diff --git a/encode_string_test.go b/encode_string_test.go
@@ -30,6 +30,56 @@ func TestEncoderStringEncodeAPI(t *testing.T) {
builder.String(),
"Result of marshalling is different as the one expected")
})
+ t.Run("utf8-multibyte", func(t *testing.T) {
+ str := "テュールスト マーティン ヤコブ 😁"
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ err := enc.EncodeString(str)
+ assert.Nil(t, err, "Error should be nil")
+ assert.Equal(
+ t,
+ `"テュールスト マーティン ヤコブ 😁"`,
+ builder.String(),
+ "Result of marshalling is different as the one expected")
+ })
+ t.Run("escaped-sequence1", func(t *testing.T) {
+ str := `テュールスト マ\ーテ
+ィン ヤコブ 😁`
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ err := enc.EncodeString(str)
+ assert.Nil(t, err, "Error should be nil")
+ assert.Equal(
+ t,
+ `"テュールスト マ\\ーテ\nィン ヤコブ 😁"`,
+ builder.String(),
+ "Result of marshalling is different as the one expected")
+ })
+ t.Run("escaped-sequence2", func(t *testing.T) {
+ str := `テュールスト マ\ーテ
+ィン ヤコブ 😁 `
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ err := enc.EncodeString(str)
+ assert.Nil(t, err, "Error should be nil")
+ assert.Equal(
+ t,
+ `"テュールスト マ\\ーテ\nィン ヤコブ 😁\t"`,
+ builder.String(),
+ "Result of marshalling is different as the one expected")
+ })
+ t.Run("escaped-sequence3", func(t *testing.T) {
+ str := "hello \r world"
+ builder := &strings.Builder{}
+ enc := NewEncoder(builder)
+ err := enc.EncodeString(str)
+ assert.Nil(t, err, "Error should be nil")
+ assert.Equal(
+ t,
+ `"hello \r world"`,
+ builder.String(),
+ "Result of marshalling is different as the one expected")
+ })
}
func TestEncoderStringEncodeAPIErrors(t *testing.T) {