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
|
bufSize = 1024
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opCodeEscapedType = iota
|
||||||
|
opCodeEscapedIndentType
|
||||||
|
opCodeNoEscapeType
|
||||||
|
opCodeNoEscapeIndentType
|
||||||
|
)
|
||||||
|
|
||||||
type opcodeSet struct {
|
type opcodeSet struct {
|
||||||
codeIndent *opcode
|
escapedCode *opcode
|
||||||
code *opcode
|
escapedCodeIndent *opcode
|
||||||
codeLength int
|
code *opcode
|
||||||
|
codeIndent *opcode
|
||||||
|
codeLength int
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadOpcodeMap() map[uintptr]*opcodeSet {
|
func loadOpcodeMap() map[uintptr]*opcodeSet {
|
||||||
|
@ -187,9 +196,17 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
||||||
if codeSet, exists := opcodeMap[typeptr]; exists {
|
if codeSet, exists := opcodeMap[typeptr]; exists {
|
||||||
var code *opcode
|
var code *opcode
|
||||||
if e.enabledIndent {
|
if e.enabledIndent {
|
||||||
code = codeSet.codeIndent
|
if e.enabledHTMLEscape {
|
||||||
|
code = codeSet.escapedCodeIndent
|
||||||
|
} else {
|
||||||
|
code = codeSet.codeIndent
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
code = codeSet.code
|
if e.enabledHTMLEscape {
|
||||||
|
code = codeSet.escapedCode
|
||||||
|
} else {
|
||||||
|
code = codeSet.code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx := e.ctx
|
ctx := e.ctx
|
||||||
p := uintptr(header.ptr)
|
p := uintptr(header.ptr)
|
||||||
|
@ -212,9 +229,11 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
||||||
codeIndent := toIndent(code)
|
codeIndent := toIndent(code)
|
||||||
codeLength := code.totalLength()
|
codeLength := code.totalLength()
|
||||||
codeSet := &opcodeSet{
|
codeSet := &opcodeSet{
|
||||||
codeIndent: codeIndent,
|
escapedCode: toEscaped(code),
|
||||||
code: code,
|
escapedCodeIndent: toEscaped(codeIndent),
|
||||||
codeLength: codeLength,
|
code: code,
|
||||||
|
codeIndent: codeIndent,
|
||||||
|
codeLength: codeLength,
|
||||||
}
|
}
|
||||||
|
|
||||||
storeOpcodeSet(typeptr, codeSet, opcodeMap)
|
storeOpcodeSet(typeptr, codeSet, opcodeMap)
|
||||||
|
@ -224,9 +243,17 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
||||||
|
|
||||||
var c *opcode
|
var c *opcode
|
||||||
if e.enabledIndent {
|
if e.enabledIndent {
|
||||||
c = codeIndent
|
if e.enabledHTMLEscape {
|
||||||
|
c = codeSet.escapedCodeIndent
|
||||||
|
} else {
|
||||||
|
c = codeSet.codeIndent
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c = code
|
if e.enabledHTMLEscape {
|
||||||
|
c = codeSet.escapedCode
|
||||||
|
} else {
|
||||||
|
c = codeSet.code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err = e.run(ctx, b, c)
|
b, err = e.run(ctx, b, c)
|
||||||
|
@ -285,20 +312,6 @@ func encodeIndentComma(b []byte) []byte {
|
||||||
return append(b, ',', '\n')
|
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 {
|
func encodeByteSlice(b []byte, src []byte) []byte {
|
||||||
encodedLen := base64.StdEncoding.EncodedLen(len(src))
|
encodedLen := base64.StdEncoding.EncodedLen(len(src))
|
||||||
b = append(b, '"')
|
b = append(b, '"')
|
||||||
|
|
|
@ -67,6 +67,20 @@ func toIndent(c *opcode) *opcode {
|
||||||
return c
|
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 {
|
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
||||||
return &opcode{
|
return &opcode{
|
||||||
op: op,
|
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