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  }