1
0
mirror of https://github.com/json-iterator/go.git synced 2025-06-15 22:50:24 +02:00

rewrite how eface and iface are handled

This commit is contained in:
Tao Wen
2018-02-21 12:16:50 +08:00
parent ea6403326b
commit 2fcbb23d96
13 changed files with 301 additions and 243 deletions

View File

@ -3,12 +3,16 @@ package jsoniter
import (
"reflect"
"unsafe"
"github.com/v2pro/plz/reflect2"
)
func decoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
elemType := typ.Elem()
decoder := decoderOfType(cfg, prefix, elemType)
return &OptionalDecoder{elemType, decoder}
if prefix == "" && elemType.Kind() == reflect.Ptr {
return &dereferenceDecoder{reflect2.Type2(elemType), decoder}
}
return &OptionalDecoder{reflect2.Type2(elemType), decoder}
}
func encoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
@ -19,7 +23,7 @@ func encoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValEn
}
type OptionalDecoder struct {
ValueType reflect.Type
ValueType reflect2.Type
ValueDecoder ValDecoder
}
@ -28,12 +32,10 @@ func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*unsafe.Pointer)(ptr)) = nil
} else {
if *((*unsafe.Pointer)(ptr)) == nil {
// TODO: use reflect2 instead
//pointer to null, we have to allocate memory to hold the value
value := reflect.New(decoder.ValueType)
newPtr := extractInterface(value.Interface()).word
newPtr := decoder.ValueType.UnsafeNew()
decoder.ValueDecoder.Decode(newPtr, iter)
*((*uintptr)(ptr)) = uintptr(newPtr)
*((*unsafe.Pointer)(ptr)) = newPtr
} else {
//reuse existing instance
decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
@ -43,17 +45,16 @@ func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
type dereferenceDecoder struct {
// only to deference a pointer
valueType reflect.Type
valueType reflect2.Type
valueDecoder ValDecoder
}
func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if *((*unsafe.Pointer)(ptr)) == nil {
//pointer to null, we have to allocate memory to hold the value
value := reflect.New(decoder.valueType)
newPtr := extractInterface(value.Interface()).word
newPtr := decoder.valueType.UnsafeNew()
decoder.valueDecoder.Decode(newPtr, iter)
*((*uintptr)(ptr)) = uintptr(newPtr)
*((*unsafe.Pointer)(ptr)) = newPtr
} else {
//reuse existing instance
decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
@ -127,4 +128,4 @@ type referenceDecoder struct {
func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.decoder.Decode(unsafe.Pointer(&ptr), iter)
}
}