mirror of https://github.com/goccy/go-json.git
Optimize HTML escape operation
This commit is contained in:
parent
5741c733a6
commit
b8f43ca445
61
encode.go
61
encode.go
|
@ -34,10 +34,19 @@ const (
|
|||
bufSize = 1024
|
||||
)
|
||||
|
||||
const (
|
||||
opCodeEscapedType = iota
|
||||
opCodeEscapedIndentType
|
||||
opCodeNoEscapeType
|
||||
opCodeNoEscapeIndentType
|
||||
)
|
||||
|
||||
type opcodeSet struct {
|
||||
codeIndent *opcode
|
||||
code *opcode
|
||||
codeLength int
|
||||
escapedCode *opcode
|
||||
escapedCodeIndent *opcode
|
||||
code *opcode
|
||||
codeIndent *opcode
|
||||
codeLength int
|
||||
}
|
||||
|
||||
func loadOpcodeMap() map[uintptr]*opcodeSet {
|
||||
|
@ -187,9 +196,17 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
|||
if codeSet, exists := opcodeMap[typeptr]; exists {
|
||||
var code *opcode
|
||||
if e.enabledIndent {
|
||||
code = codeSet.codeIndent
|
||||
if e.enabledHTMLEscape {
|
||||
code = codeSet.escapedCodeIndent
|
||||
} else {
|
||||
code = codeSet.codeIndent
|
||||
}
|
||||
} else {
|
||||
code = codeSet.code
|
||||
if e.enabledHTMLEscape {
|
||||
code = codeSet.escapedCode
|
||||
} else {
|
||||
code = codeSet.code
|
||||
}
|
||||
}
|
||||
ctx := e.ctx
|
||||
p := uintptr(header.ptr)
|
||||
|
@ -212,9 +229,11 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
|||
codeIndent := toIndent(code)
|
||||
codeLength := code.totalLength()
|
||||
codeSet := &opcodeSet{
|
||||
codeIndent: codeIndent,
|
||||
code: code,
|
||||
codeLength: codeLength,
|
||||
escapedCode: toEscaped(code),
|
||||
escapedCodeIndent: toEscaped(codeIndent),
|
||||
code: code,
|
||||
codeIndent: codeIndent,
|
||||
codeLength: codeLength,
|
||||
}
|
||||
|
||||
storeOpcodeSet(typeptr, codeSet, opcodeMap)
|
||||
|
@ -224,9 +243,17 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
|||
|
||||
var c *opcode
|
||||
if e.enabledIndent {
|
||||
c = codeIndent
|
||||
if e.enabledHTMLEscape {
|
||||
c = codeSet.escapedCodeIndent
|
||||
} else {
|
||||
c = codeSet.codeIndent
|
||||
}
|
||||
} else {
|
||||
c = code
|
||||
if e.enabledHTMLEscape {
|
||||
c = codeSet.escapedCode
|
||||
} else {
|
||||
c = codeSet.code
|
||||
}
|
||||
}
|
||||
|
||||
b, err = e.run(ctx, b, c)
|
||||
|
@ -285,20 +312,6 @@ func encodeIndentComma(b []byte) []byte {
|
|||
return append(b, ',', '\n')
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeKey(b []byte, code *opcode) []byte {
|
||||
if e.enabledHTMLEscape {
|
||||
return append(b, code.escapedKey...)
|
||||
}
|
||||
return append(b, code.key...)
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeString(b []byte, s string) []byte {
|
||||
if e.enabledHTMLEscape {
|
||||
return encodeEscapedString(b, s)
|
||||
}
|
||||
return encodeNoEscapedString(b, s)
|
||||
}
|
||||
|
||||
func encodeByteSlice(b []byte, src []byte) []byte {
|
||||
encodedLen := base64.StdEncoding.EncodedLen(len(src))
|
||||
b = append(b, '"')
|
||||
|
|
|
@ -67,6 +67,20 @@ func toIndent(c *opcode) *opcode {
|
|||
return c
|
||||
}
|
||||
|
||||
func toEscaped(c *opcode) *opcode {
|
||||
c = copyOpcode(c)
|
||||
for code := c; code.op != opEnd; {
|
||||
code.op = code.op.toEscaped()
|
||||
switch code.op.codeType() {
|
||||
case codeArrayElem, codeSliceElem, codeMapKey:
|
||||
code = code.end
|
||||
default:
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
||||
return &opcode{
|
||||
op: op,
|
||||
|
|
6156
encode_vm.go
6156
encode_vm.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue