reflect_dynamic.go raw

   1  package jsoniter
   2  
   3  import (
   4  	"github.com/modern-go/reflect2"
   5  	"reflect"
   6  	"unsafe"
   7  )
   8  
   9  type dynamicEncoder struct {
  10  	valType reflect2.Type
  11  }
  12  
  13  func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
  14  	obj := encoder.valType.UnsafeIndirect(ptr)
  15  	stream.WriteVal(obj)
  16  }
  17  
  18  func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  19  	return encoder.valType.UnsafeIndirect(ptr) == nil
  20  }
  21  
  22  type efaceDecoder struct {
  23  }
  24  
  25  func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  26  	pObj := (*interface{})(ptr)
  27  	obj := *pObj
  28  	if obj == nil {
  29  		*pObj = iter.Read()
  30  		return
  31  	}
  32  	typ := reflect2.TypeOf(obj)
  33  	if typ.Kind() != reflect.Ptr {
  34  		*pObj = iter.Read()
  35  		return
  36  	}
  37  	ptrType := typ.(*reflect2.UnsafePtrType)
  38  	ptrElemType := ptrType.Elem()
  39  	if iter.WhatIsNext() == NilValue {
  40  		if ptrElemType.Kind() != reflect.Ptr {
  41  			iter.skipFourBytes('n', 'u', 'l', 'l')
  42  			*pObj = nil
  43  			return
  44  		}
  45  	}
  46  	if reflect2.IsNil(obj) {
  47  		obj := ptrElemType.New()
  48  		iter.ReadVal(obj)
  49  		*pObj = obj
  50  		return
  51  	}
  52  	iter.ReadVal(obj)
  53  }
  54  
  55  type ifaceDecoder struct {
  56  	valType *reflect2.UnsafeIFaceType
  57  }
  58  
  59  func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
  60  	if iter.ReadNil() {
  61  		decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew())
  62  		return
  63  	}
  64  	obj := decoder.valType.UnsafeIndirect(ptr)
  65  	if reflect2.IsNil(obj) {
  66  		iter.ReportError("decode non empty interface", "can not unmarshal into nil")
  67  		return
  68  	}
  69  	iter.ReadVal(obj)
  70  }
  71