|
| 1 | +package arrow |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "reflect" |
| 6 | + |
| 7 | + "github.com/vmihailenco/msgpack/v5" |
| 8 | +) |
| 9 | + |
| 10 | +// Arrow MessagePack extension type |
| 11 | +const arrowExtId = 8 |
| 12 | + |
| 13 | +// Arrow struct wraps a raw arrow data buffer. |
| 14 | +type Arrow struct { |
| 15 | + data []byte |
| 16 | +} |
| 17 | + |
| 18 | +// MakeArrow returns a new arrow.Arrow object that contains |
| 19 | +// wrapped a raw arrow data buffer. |
| 20 | +func MakeArrow(arrow []byte) (Arrow, error) { |
| 21 | + if len(arrow) == 0 { |
| 22 | + return Arrow{}, fmt.Errorf("no Arrow data") |
| 23 | + } |
| 24 | + return Arrow{arrow}, nil |
| 25 | +} |
| 26 | + |
| 27 | +// ToArrow returns a []byte that contains Arrow raw data. |
| 28 | +func (a *Arrow) ToArrow() []byte { |
| 29 | + return a.data |
| 30 | +} |
| 31 | + |
| 32 | +func arrowDecoder(d *msgpack.Decoder, v reflect.Value, extLen int) error { |
| 33 | + arrow := Arrow{ |
| 34 | + data: make([]byte, 0, extLen), |
| 35 | + } |
| 36 | + n, err := d.Buffered().Read(arrow.data) |
| 37 | + if err != nil { |
| 38 | + return fmt.Errorf("msgpack: can't read bytes on Arrow decode: %w", err) |
| 39 | + } |
| 40 | + if n < extLen || n != len(arrow.data) { |
| 41 | + return fmt.Errorf("msgpack: unexpected end of stream after %d Arrow bytes", n) |
| 42 | + } |
| 43 | + |
| 44 | + v.Set(reflect.ValueOf(arrow)) |
| 45 | + return nil |
| 46 | +} |
| 47 | + |
| 48 | +func arrowEncoder(e *msgpack.Encoder, v reflect.Value) ([]byte, error) { |
| 49 | + if v.IsValid() { |
| 50 | + return v.Interface().(Arrow).data, nil |
| 51 | + } |
| 52 | + |
| 53 | + return []byte{}, fmt.Errorf("msgpack: not valid Arrow value") |
| 54 | +} |
| 55 | + |
| 56 | +func init() { |
| 57 | + msgpack.RegisterExtDecoder(arrowExtId, Arrow{}, arrowDecoder) |
| 58 | + msgpack.RegisterExtEncoder(arrowExtId, Arrow{}, arrowEncoder) |
| 59 | +} |
0 commit comments