forked from mirror/go-json
Fix encoding runner interface
This commit is contained in:
parent
86ae7d931a
commit
399354d64d
55
encode.go
55
encode.go
|
@ -112,6 +112,7 @@ func (e *Encoder) EncodeWithOption(v interface{}, opts ...EncodeOption) error {
|
|||
}
|
||||
}
|
||||
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||
e.ptr = header.ptr
|
||||
buf, err := e.encode(header, v == nil)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -192,23 +193,31 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
|
|||
typ := header.typ
|
||||
|
||||
typeptr := uintptr(unsafe.Pointer(typ))
|
||||
codeSet, err := e.compileToGetCodeSet(typeptr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := e.ctx
|
||||
p := uintptr(header.ptr)
|
||||
ctx.init(p, codeSet.codeLength)
|
||||
if e.enabledIndent {
|
||||
if e.enabledHTMLEscape {
|
||||
return e.runEscapedIndent(ctx, b, codeSet)
|
||||
} else {
|
||||
return e.runIndent(ctx, b, codeSet)
|
||||
}
|
||||
}
|
||||
if e.enabledHTMLEscape {
|
||||
return e.runEscaped(ctx, b, codeSet)
|
||||
}
|
||||
return e.run(ctx, b, codeSet)
|
||||
}
|
||||
|
||||
func (e *Encoder) compileToGetCodeSet(typeptr uintptr) (*opcodeSet, error) {
|
||||
opcodeMap := loadOpcodeMap()
|
||||
if codeSet, exists := opcodeMap[typeptr]; exists {
|
||||
ctx := e.ctx
|
||||
p := uintptr(header.ptr)
|
||||
ctx.init(p, codeSet.codeLength)
|
||||
|
||||
if e.enabledIndent {
|
||||
if e.enabledHTMLEscape {
|
||||
return e.runEscapedIndent(ctx, b, codeSet.code)
|
||||
} else {
|
||||
return e.runIndent(ctx, b, codeSet.code)
|
||||
}
|
||||
}
|
||||
if e.enabledHTMLEscape {
|
||||
return e.runEscaped(ctx, b, codeSet.code)
|
||||
}
|
||||
return e.run(ctx, b, codeSet.code)
|
||||
return codeSet, nil
|
||||
}
|
||||
|
||||
// noescape trick for header.typ ( reflect.*rtype )
|
||||
|
@ -230,21 +239,7 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
|
|||
}
|
||||
|
||||
storeOpcodeSet(typeptr, codeSet, opcodeMap)
|
||||
p := uintptr(header.ptr)
|
||||
ctx := e.ctx
|
||||
ctx.init(p, codeLength)
|
||||
|
||||
if e.enabledIndent {
|
||||
if e.enabledHTMLEscape {
|
||||
return e.runEscapedIndent(ctx, b, codeSet.code)
|
||||
} else {
|
||||
return e.runIndent(ctx, b, codeSet.code)
|
||||
}
|
||||
}
|
||||
if e.enabledHTMLEscape {
|
||||
return e.runEscaped(ctx, b, codeSet.code)
|
||||
}
|
||||
return e.run(ctx, b, codeSet.code)
|
||||
return codeSet, nil
|
||||
}
|
||||
|
||||
func encodeFloat32(b []byte, v float32) []byte {
|
||||
|
|
|
@ -49,10 +49,11 @@ func errMarshaler(code *opcode, err error) *MarshalerError {
|
|||
}
|
||||
}
|
||||
|
||||
func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte, error) {
|
||||
func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ([]byte, error) {
|
||||
recursiveLevel := 0
|
||||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.ptr()
|
||||
code := codeSet.code
|
||||
|
||||
for {
|
||||
switch code.op {
|
||||
|
|
|
@ -11,11 +11,13 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte, error) {
|
||||
func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ([]byte, error) {
|
||||
recursiveLevel := 0
|
||||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.ptr()
|
||||
|
||||
code := codeSet.code
|
||||
|
||||
for {
|
||||
switch code.op {
|
||||
default:
|
||||
|
|
|
@ -11,11 +11,12 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte, error) {
|
||||
func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ([]byte, error) {
|
||||
recursiveLevel := 0
|
||||
var seenPtr map[uintptr]struct{}
|
||||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.ptr()
|
||||
code := codeSet.code
|
||||
|
||||
for {
|
||||
switch code.op {
|
||||
|
|
|
@ -11,11 +11,12 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte, error) {
|
||||
func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ([]byte, error) {
|
||||
recursiveLevel := 0
|
||||
var seenPtr map[uintptr]struct{}
|
||||
ptrOffset := uintptr(0)
|
||||
ctxptr := ctx.ptr()
|
||||
code := codeSet.code
|
||||
|
||||
for {
|
||||
switch code.op {
|
||||
|
|
Loading…
Reference in New Issue