github.com/hamba/avro@v1.8.0/codec_ptr.go (about) 1 package avro 2 3 import ( 4 "errors" 5 "unsafe" 6 7 "github.com/modern-go/reflect2" 8 ) 9 10 func decoderOfPtr(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValDecoder { 11 ptrType := typ.(*reflect2.UnsafePtrType) 12 elemType := ptrType.Elem() 13 14 decoder := decoderOfType(cfg, schema, elemType) 15 16 return &dereferenceDecoder{typ: elemType, decoder: decoder} 17 } 18 19 type dereferenceDecoder struct { 20 typ reflect2.Type 21 decoder ValDecoder 22 } 23 24 func (d *dereferenceDecoder) Decode(ptr unsafe.Pointer, r *Reader) { 25 if *((*unsafe.Pointer)(ptr)) == nil { 26 // Create new instance 27 newPtr := d.typ.UnsafeNew() 28 d.decoder.Decode(newPtr, r) 29 *((*unsafe.Pointer)(ptr)) = newPtr 30 return 31 } 32 33 // Reuse existing instance 34 d.decoder.Decode(*((*unsafe.Pointer)(ptr)), r) 35 } 36 37 func encoderOfPtr(cfg *frozenConfig, schema Schema, typ reflect2.Type) ValEncoder { 38 ptrType := typ.(*reflect2.UnsafePtrType) 39 elemType := ptrType.Elem() 40 41 enc := encoderOfType(cfg, schema, elemType) 42 43 return &dereferenceEncoder{typ: elemType, encoder: enc} 44 } 45 46 type dereferenceEncoder struct { 47 typ reflect2.Type 48 encoder ValEncoder 49 } 50 51 func (d *dereferenceEncoder) Encode(ptr unsafe.Pointer, w *Writer) { 52 if *((*unsafe.Pointer)(ptr)) == nil { 53 w.Error = errors.New("avro: cannot encode nil pointer") 54 return 55 } 56 57 d.encoder.Encode(*((*unsafe.Pointer)(ptr)), w) 58 } 59 60 type referenceDecoder struct { 61 decoder ValDecoder 62 } 63 64 func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, r *Reader) { 65 decoder.decoder.Decode(unsafe.Pointer(&ptr), r) 66 }