github.com/hamba/avro/v2@v2.22.1-0.20240518180522-aff3955acf7d/codec_dynamic.go (about)

     1  package avro
     2  
     3  import (
     4  	"reflect"
     5  	"unsafe"
     6  
     7  	"github.com/modern-go/reflect2"
     8  )
     9  
    10  type efaceDecoder struct {
    11  	schema Schema
    12  	typ    reflect2.Type
    13  	dec    ValDecoder
    14  }
    15  
    16  func newEfaceDecoder(cfg *frozenConfig, schema Schema) *efaceDecoder {
    17  	typ, _ := genericReceiver(schema)
    18  	dec := decoderOfType(cfg, schema, typ)
    19  
    20  	return &efaceDecoder{
    21  		schema: schema,
    22  		typ:    typ,
    23  		dec:    dec,
    24  	}
    25  }
    26  
    27  func (d *efaceDecoder) Decode(ptr unsafe.Pointer, r *Reader) {
    28  	pObj := (*any)(ptr)
    29  	if *pObj == nil {
    30  		*pObj = genericDecode(d.typ, d.dec, r)
    31  		return
    32  	}
    33  
    34  	typ := reflect2.TypeOf(*pObj)
    35  	if typ.Kind() != reflect.Ptr {
    36  		*pObj = genericDecode(d.typ, d.dec, r)
    37  		return
    38  	}
    39  
    40  	ptrType := typ.(*reflect2.UnsafePtrType)
    41  	ptrElemType := ptrType.Elem()
    42  	if reflect2.IsNil(*pObj) {
    43  		obj := ptrElemType.New()
    44  		r.ReadVal(d.schema, obj)
    45  		*pObj = obj
    46  		return
    47  	}
    48  	r.ReadVal(d.schema, *pObj)
    49  }
    50  
    51  type interfaceEncoder struct {
    52  	schema Schema
    53  	typ    reflect2.Type
    54  }
    55  
    56  func (e *interfaceEncoder) Encode(ptr unsafe.Pointer, w *Writer) {
    57  	obj := e.typ.UnsafeIndirect(ptr)
    58  	w.WriteVal(e.schema, obj)
    59  }