diff options
Diffstat (limited to 'vendor/github.com/hamba/avro/v2/codec_ptr.go')
| -rw-r--r-- | vendor/github.com/hamba/avro/v2/codec_ptr.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/vendor/github.com/hamba/avro/v2/codec_ptr.go b/vendor/github.com/hamba/avro/v2/codec_ptr.go new file mode 100644 index 0000000..07b099e --- /dev/null +++ b/vendor/github.com/hamba/avro/v2/codec_ptr.go @@ -0,0 +1,66 @@ +package avro + +import ( + "errors" + "unsafe" + + "github.com/modern-go/reflect2" +) + +func decoderOfPtr(d *decoderContext, schema Schema, typ reflect2.Type) ValDecoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + + decoder := decoderOfType(d, schema, elemType) + + return &dereferenceDecoder{typ: elemType, decoder: decoder} +} + +type dereferenceDecoder struct { + typ reflect2.Type + decoder ValDecoder +} + +func (d *dereferenceDecoder) Decode(ptr unsafe.Pointer, r *Reader) { + if *((*unsafe.Pointer)(ptr)) == nil { + // Create new instance + newPtr := d.typ.UnsafeNew() + d.decoder.Decode(newPtr, r) + *((*unsafe.Pointer)(ptr)) = newPtr + return + } + + // Reuse existing instance + d.decoder.Decode(*((*unsafe.Pointer)(ptr)), r) +} + +func encoderOfPtr(e *encoderContext, schema Schema, typ reflect2.Type) ValEncoder { + ptrType := typ.(*reflect2.UnsafePtrType) + elemType := ptrType.Elem() + + enc := encoderOfType(e, schema, elemType) + + return &dereferenceEncoder{typ: elemType, encoder: enc} +} + +type dereferenceEncoder struct { + typ reflect2.Type + encoder ValEncoder +} + +func (d *dereferenceEncoder) Encode(ptr unsafe.Pointer, w *Writer) { + if *((*unsafe.Pointer)(ptr)) == nil { + w.Error = errors.New("avro: cannot encode nil pointer") + return + } + + d.encoder.Encode(*((*unsafe.Pointer)(ptr)), w) +} + +type referenceDecoder struct { + decoder ValDecoder +} + +func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, r *Reader) { + decoder.decoder.Decode(unsafe.Pointer(&ptr), r) +} |
