github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/val_decoder_native_struct_one_field.go (about) 1 package jzon 2 3 import ( 4 "bytes" 5 "reflect" 6 "unsafe" 7 ) 8 9 type oneFieldStructDecoderBuilder struct { 10 decoder *oneFieldStructDecoder 11 fieldPtrType reflect.Type 12 } 13 14 func newOneFieldStructDecoder(field *field, caseSensitive bool) *oneFieldStructDecoderBuilder { 15 var dfi decoderFieldInfo 16 dfi.initFrom(field) 17 if caseSensitive { 18 dfi.equalFold = bytes.Equal 19 } 20 return &oneFieldStructDecoderBuilder{ 21 decoder: &oneFieldStructDecoder{ 22 decoderFieldInfo: dfi, 23 }, 24 fieldPtrType: field.ptrType, 25 } 26 } 27 28 func (builder *oneFieldStructDecoderBuilder) build(cache decoderCache) { 29 builder.decoder.decoder = cache[rtypeOfType(builder.fieldPtrType)] 30 } 31 32 type oneFieldStructDecoder struct { 33 decoderFieldInfo 34 } 35 36 func (dec *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, it *Iterator, _ *DecOpts) (err error) { 37 c, err := it.nextToken() 38 if err != nil { 39 return err 40 } 41 if c == 'n' { 42 it.head++ 43 err = it.expectBytes("ull") 44 return 45 } 46 if c != '{' { 47 return UnexpectedByteError{got: c, exp2: 'n', exp: '{'} 48 } 49 it.head++ 50 c, err = it.nextToken() 51 if err != nil { 52 return 53 } 54 if c == '}' { 55 it.head++ 56 return 57 } 58 if c != '"' { 59 return UnexpectedByteError{got: c, exp: '}', exp2: '"'} 60 } 61 it.head++ 62 for { 63 field, err := it.readObjectFieldAsSlice() 64 if err != nil { 65 return err 66 } 67 if dec.equalFold(field, dec.nameBytes) { 68 curPtr := add(ptr, dec.offsets[0].val, "struct field") 69 for _, offset := range dec.offsets[1:] { 70 subPtr := *(*unsafe.Pointer)(curPtr) 71 if subPtr == nil { 72 if offset.rtype == 0 { // the ptr field is not exported 73 return ErrNilEmbeddedPointer 74 } 75 subPtr = unsafe_New(offset.rtype) 76 *(*unsafe.Pointer)(curPtr) = subPtr 77 } 78 curPtr = add(subPtr, offset.val, "struct field") 79 } 80 opt := DecOpts{ 81 Quoted: dec.quoted, 82 } 83 if err = dec.decoder.Decode(curPtr, it, opt.noescape()); err != nil { 84 return err 85 } 86 } else { 87 if it.disallowUnknownFields { 88 return UnknownFieldError(field) 89 } 90 if err = it.Skip(); err != nil { 91 return err 92 } 93 } 94 c, err = it.nextToken() 95 if err != nil { 96 return err 97 } 98 switch c { 99 case '}': 100 it.head++ 101 return nil 102 case ',': 103 it.head++ 104 c, err = it.nextToken() 105 if err != nil { 106 return err 107 } 108 if c != '"' { 109 return UnexpectedByteError{got: c, exp: '"'} 110 } 111 it.head++ 112 default: 113 return UnexpectedByteError{got: c, exp: '}', exp2: ','} 114 } 115 } 116 }