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))
|
header := (*interfaceHeader)(unsafe.Pointer(&v))
|
||||||
|
e.ptr = header.ptr
|
||||||
buf, err := e.encode(header, v == nil)
|
buf, err := e.encode(header, v == nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -192,23 +193,31 @@ func (e *Encoder) encode(header *interfaceHeader, isNil bool) ([]byte, error) {
|
||||||
typ := header.typ
|
typ := header.typ
|
||||||
|
|
||||||
typeptr := uintptr(unsafe.Pointer(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()
|
opcodeMap := loadOpcodeMap()
|
||||||
if codeSet, exists := opcodeMap[typeptr]; exists {
|
if codeSet, exists := opcodeMap[typeptr]; exists {
|
||||||
ctx := e.ctx
|
return codeSet, nil
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// noescape trick for header.typ ( reflect.*rtype )
|
// 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)
|
storeOpcodeSet(typeptr, codeSet, opcodeMap)
|
||||||
p := uintptr(header.ptr)
|
return codeSet, nil
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeFloat32(b []byte, v float32) []byte {
|
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
|
recursiveLevel := 0
|
||||||
ptrOffset := uintptr(0)
|
ptrOffset := uintptr(0)
|
||||||
ctxptr := ctx.ptr()
|
ctxptr := ctx.ptr()
|
||||||
|
code := codeSet.code
|
||||||
|
|
||||||
for {
|
for {
|
||||||
switch code.op {
|
switch code.op {
|
||||||
|
|
|
@ -11,11 +11,13 @@ import (
|
||||||
"unsafe"
|
"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
|
recursiveLevel := 0
|
||||||
ptrOffset := uintptr(0)
|
ptrOffset := uintptr(0)
|
||||||
ctxptr := ctx.ptr()
|
ctxptr := ctx.ptr()
|
||||||
|
|
||||||
|
code := codeSet.code
|
||||||
|
|
||||||
for {
|
for {
|
||||||
switch code.op {
|
switch code.op {
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -11,11 +11,12 @@ import (
|
||||||
"unsafe"
|
"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
|
recursiveLevel := 0
|
||||||
var seenPtr map[uintptr]struct{}
|
var seenPtr map[uintptr]struct{}
|
||||||
ptrOffset := uintptr(0)
|
ptrOffset := uintptr(0)
|
||||||
ctxptr := ctx.ptr()
|
ctxptr := ctx.ptr()
|
||||||
|
code := codeSet.code
|
||||||
|
|
||||||
for {
|
for {
|
||||||
switch code.op {
|
switch code.op {
|
||||||
|
|
|
@ -11,11 +11,12 @@ import (
|
||||||
"unsafe"
|
"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
|
recursiveLevel := 0
|
||||||
var seenPtr map[uintptr]struct{}
|
var seenPtr map[uintptr]struct{}
|
||||||
ptrOffset := uintptr(0)
|
ptrOffset := uintptr(0)
|
||||||
ctxptr := ctx.ptr()
|
ctxptr := ctx.ptr()
|
||||||
|
code := codeSet.code
|
||||||
|
|
||||||
for {
|
for {
|
||||||
switch code.op {
|
switch code.op {
|
||||||
|
|
Loading…
Reference in New Issue