Skip to content

Commit 024abcd

Browse files
authored
Merge pull request #49 from goccy/feature/fix-stream-encoding
Fix stream encoding
2 parents 043377d + 067d4c5 commit 024abcd

9 files changed

+802
-296
lines changed

encode.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,11 @@ func (e *Encoder) EncodeWithOption(v interface{}, opts ...EncodeOption) error {
102102
if err := e.encode(v); err != nil {
103103
return err
104104
}
105+
e.buf = append(e.buf, '\n')
105106
if _, err := e.w.Write(e.buf); err != nil {
106107
return err
107108
}
109+
e.buf = e.buf[:0]
108110
return nil
109111
}
110112

@@ -315,6 +317,14 @@ func (e *Encoder) encodeNull() {
315317
e.buf = append(e.buf, 'n', 'u', 'l', 'l')
316318
}
317319

320+
func (e *Encoder) encodeKey(code *opcode) {
321+
if e.enabledHTMLEscape {
322+
e.encodeBytes(code.escapedKey)
323+
} else {
324+
e.encodeBytes(code.key)
325+
}
326+
}
327+
318328
func (e *Encoder) encodeString(s string) {
319329
if e.enabledHTMLEscape {
320330
e.encodeEscapedString(s)

encode_compile.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package json
22

33
import (
4+
"bytes"
45
"fmt"
56
"reflect"
67
"unsafe"
@@ -890,6 +891,12 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
890891
}
891892
}
892893
key := fmt.Sprintf(`"%s":`, tag.key)
894+
895+
var buf bytes.Buffer
896+
enc := NewEncoder(&buf)
897+
enc.encodeEscapedString(tag.key)
898+
escapedKey := fmt.Sprintf(`%s:`, string(enc.buf))
899+
enc.release()
893900
fieldCode := &opcode{
894901
typ: valueCode.typ,
895902
displayIdx: fieldOpcodeIndex,
@@ -898,6 +905,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
898905
indent: ctx.indent,
899906
anonymousKey: field.Anonymous,
900907
key: []byte(key),
908+
escapedKey: []byte(escapedKey),
901909
isTaggedKey: tag.isTaggedKey,
902910
displayKey: tag.key,
903911
offset: field.Offset,

encode_opcode.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type opcode struct {
1313
typ *rtype // go type
1414
displayIdx int // opcode index
1515
key []byte // struct field key
16+
escapedKey []byte // struct field key ( HTML escaped )
1617
displayKey string // key text to display
1718
isTaggedKey bool // whether tagged key
1819
anonymousKey bool // whether anonymous key
@@ -78,6 +79,7 @@ func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode {
7879
typ: c.typ,
7980
displayIdx: c.displayIdx,
8081
key: c.key,
82+
escapedKey: c.escapedKey,
8183
displayKey: c.displayKey,
8284
isTaggedKey: c.isTaggedKey,
8385
anonymousKey: c.anonymousKey,

encode_string.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,22 +308,22 @@ func (e *Encoder) writeStringSlowPathWithHTMLEscaped(i int, s string, valLen int
308308

309309
func (e *Encoder) encodeNoEscapedString(s string) {
310310
valLen := len(s)
311-
e.buf = append(e.buf, '"')
312311

313312
// write string, the fast path, without utf8 and escape support
314313
i := 0
315314
for ; i < valLen; i++ {
316315
c := s[i]
317-
if c > 31 && c != '"' && c != '\\' {
318-
e.buf = append(e.buf, c)
319-
} else {
316+
if c <= 31 || c == '"' || c == '\\' {
320317
break
321318
}
322319
}
320+
e.buf = append(e.buf, '"')
323321
if i == valLen {
322+
e.buf = append(e.buf, s...)
324323
e.buf = append(e.buf, '"')
325324
return
326325
}
326+
e.buf = append(e.buf, s[:i]...)
327327
e.writeStringSlowPath(i, s, valLen)
328328
}
329329

0 commit comments

Comments
 (0)