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 }