forked from mirror/go-json
Fix encoding for struct field of pointer type
This commit is contained in:
parent
3e814f749f
commit
c515899c6d
24
encode.go
24
encode.go
|
@ -132,7 +132,7 @@ func (e *Encoder) encode(v reflect.Value) ([]byte, error) {
|
||||||
copy(copied, e.buf)
|
copy(copied, e.buf)
|
||||||
return copied, nil
|
return copied, nil
|
||||||
}
|
}
|
||||||
op, err := e.compile(v.Type())
|
op, err := e.compile(v.Elem().Type())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ func (e *Encoder) encode(v reflect.Value) ([]byte, error) {
|
||||||
func (e *Encoder) compile(typ reflect.Type) (EncodeOp, error) {
|
func (e *Encoder) compile(typ reflect.Type) (EncodeOp, error) {
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
return e.compile(typ.Elem())
|
return e.compilePtr(typ)
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return e.compileSlice(typ)
|
return e.compileSlice(typ)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
|
@ -185,6 +185,17 @@ func (e *Encoder) compile(typ reflect.Type) (EncodeOp, error) {
|
||||||
return nil, xerrors.Errorf("failed to compile %s: %w", typ, ErrUnknownType)
|
return nil, xerrors.Errorf("failed to compile %s: %w", typ, ErrUnknownType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) compilePtr(typ reflect.Type) (EncodeOp, error) {
|
||||||
|
elem := typ.Elem()
|
||||||
|
op, err := e.compile(elem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return func(enc *Encoder, p uintptr) {
|
||||||
|
op(enc, e.ptrToPtr(p))
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Encoder) compileInt() (EncodeOp, error) {
|
func (e *Encoder) compileInt() (EncodeOp, error) {
|
||||||
return func(enc *Encoder, p uintptr) { enc.EncodeInt(e.ptrToInt(p)) }, nil
|
return func(enc *Encoder, p uintptr) { enc.EncodeInt(e.ptrToInt(p)) }, nil
|
||||||
}
|
}
|
||||||
|
@ -248,6 +259,10 @@ func (e *Encoder) compileSlice(typ reflect.Type) (EncodeOp, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return func(enc *Encoder, base uintptr) {
|
return func(enc *Encoder, base uintptr) {
|
||||||
|
if base == 0 {
|
||||||
|
enc.EncodeString("null")
|
||||||
|
return
|
||||||
|
}
|
||||||
enc.EncodeByte('[')
|
enc.EncodeByte('[')
|
||||||
slice := (*reflect.SliceHeader)(unsafe.Pointer(base))
|
slice := (*reflect.SliceHeader)(unsafe.Pointer(base))
|
||||||
num := slice.Len
|
num := slice.Len
|
||||||
|
@ -287,6 +302,10 @@ func (e *Encoder) compileStruct(typ reflect.Type) (EncodeOp, error) {
|
||||||
}
|
}
|
||||||
queueNum := len(opQueue)
|
queueNum := len(opQueue)
|
||||||
return func(enc *Encoder, base uintptr) {
|
return func(enc *Encoder, base uintptr) {
|
||||||
|
if base == 0 {
|
||||||
|
enc.EncodeString("null")
|
||||||
|
return
|
||||||
|
}
|
||||||
enc.EncodeByte('{')
|
enc.EncodeByte('{')
|
||||||
for i := 0; i < queueNum; i++ {
|
for i := 0; i < queueNum; i++ {
|
||||||
opQueue[i](enc, base)
|
opQueue[i](enc, base)
|
||||||
|
@ -298,6 +317,7 @@ func (e *Encoder) compileStruct(typ reflect.Type) (EncodeOp, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Encoder) ptrToPtr(p uintptr) uintptr { return *(*uintptr)(unsafe.Pointer(p)) }
|
||||||
func (e *Encoder) ptrToInt(p uintptr) int { return *(*int)(unsafe.Pointer(p)) }
|
func (e *Encoder) ptrToInt(p uintptr) int { return *(*int)(unsafe.Pointer(p)) }
|
||||||
func (e *Encoder) ptrToInt8(p uintptr) int8 { return *(*int8)(unsafe.Pointer(p)) }
|
func (e *Encoder) ptrToInt8(p uintptr) int8 { return *(*int8)(unsafe.Pointer(p)) }
|
||||||
func (e *Encoder) ptrToInt16(p uintptr) int16 { return *(*int16)(unsafe.Pointer(p)) }
|
func (e *Encoder) ptrToInt16(p uintptr) int16 { return *(*int16)(unsafe.Pointer(p)) }
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import "unicode/utf8"
|
import (
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
// htmlSafeSet holds the value true if the ASCII character with the given
|
// htmlSafeSet holds the value true if the ASCII character with the given
|
||||||
// array position can be safely represented inside a JSON string, embedded
|
// array position can be safely represented inside a JSON string, embedded
|
||||||
|
|
Loading…
Reference in New Issue