github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_decoder_native_interface.go (about)

     1  package jzon
     2  
     3  import (
     4  	"reflect"
     5  	"unsafe"
     6  )
     7  
     8  /*
     9   * Interface decoder is special, when the object is not nil,
    10   * the internal type cannot be analysed by reflect.TypeOf,
    11   * the value must be used during runtime
    12   */
    13  type efaceDecoder struct {
    14  }
    15  
    16  func (dec *efaceDecoder) checkLoop(ptr unsafe.Pointer, it *Iterator) bool {
    17  	uptr := uintptr(ptr)
    18  	curOffset := it.offset + it.head
    19  	if it.lastEfacePtr == 0 || curOffset != it.lastEfaceOffset {
    20  		// - no eface has been recorded, or
    21  		// - the iterator moved
    22  		it.lastEfacePtr = uptr
    23  		it.lastEfaceOffset = curOffset
    24  		return true
    25  	}
    26  	// the iterator didn't move, check the pointer we first met
    27  	// at this location
    28  	return uptr != it.lastEfacePtr
    29  }
    30  
    31  func (dec *efaceDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
    32  	// one risk here is that we may enter an infinite loop which
    33  	// will cause stack overflow:
    34  	//   var o interface{}
    35  	//   o = &o
    36  	// or cross nested interface{}
    37  	//   var o1, o2 interface{}
    38  	//   o1 = &o2
    39  	//   o2 = &o1
    40  	// so we have this looping check here
    41  	if !dec.checkLoop(ptr, it) {
    42  		return ErrEfaceLooping
    43  	}
    44  	ef := (*eface)(ptr)
    45  	if ef.data == nil {
    46  		// the pointer is a nil pointer
    47  		// or the element is a nil typed pointer (kinda tricky here)
    48  		o, err := it.Read()
    49  		if err != nil {
    50  			return err
    51  		}
    52  		*(*interface{})(ptr) = o
    53  		return nil
    54  	}
    55  	pObj := (*interface{})(ptr)
    56  	obj := *pObj
    57  	typ := reflect.TypeOf(obj)
    58  	if typ.Kind() != reflect.Ptr {
    59  		/*
    60  		 * Example:
    61  		 *   var o interface{} = 1
    62  		 *   Unmarshal(`"string"`, &o)
    63  		 */
    64  		o, err := it.Read()
    65  		if err != nil {
    66  			return err
    67  		}
    68  		*pObj = o
    69  		return nil
    70  	}
    71  	// obj is pointer
    72  	c, err := it.nextToken()
    73  	if err != nil {
    74  		return err
    75  	}
    76  	ptrElemType := typ.Elem()
    77  	if c == 'n' {
    78  		it.head++
    79  		if err := it.expectBytes("ull"); err != nil {
    80  			return err
    81  		}
    82  		// we have already check above so that
    83  		// obj is not nil
    84  		if ptrElemType.Kind() != reflect.Ptr {
    85  			/*
    86  			 * Example:
    87  			 *   i := 1
    88  			 *   var o interface{} = &i
    89  			 *   Unmarshal(`null`, &o)
    90  			 */
    91  			*pObj = nil
    92  			return nil
    93  		}
    94  		/*
    95  		 * Example:
    96  		 *   i := 1
    97  		 *   pi := &i
    98  		 *   var o interface{} = &pi
    99  		 *   Unmarshal(`null`, &o)
   100  		 */
   101  		*pObj = reflect.New(ptrElemType).Interface()
   102  		return nil
   103  	}
   104  	// when we arrive here, we have:
   105  	//   1. obj is pointer
   106  	//   2. obj != nil
   107  	if err := it.ReadVal(obj); err != nil {
   108  		return err
   109  	}
   110  	*pObj = obj
   111  	return nil
   112  }
   113  
   114  type ifaceDecoder struct {
   115  }
   116  
   117  func (dec *ifaceDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) error {
   118  	c, err := it.nextToken()
   119  	if err != nil {
   120  		return err
   121  	}
   122  	if c == 'n' {
   123  		it.head++
   124  		if err = it.expectBytes("ull"); err != nil {
   125  			return err
   126  		}
   127  		*(*interface{})(ptr) = nil
   128  		return nil
   129  	}
   130  	o := packIFace(ptr)
   131  	if o == nil {
   132  		return ErrEmptyIFace
   133  	}
   134  	return it.ReadVal(o)
   135  }