meta/msgpack_reader.go

283 lines
5.8 KiB
Go
Raw Permalink Normal View History

2022-10-01 21:09:54 +03:00
package meta
import (
"io"
2022-10-01 21:09:54 +03:00
"github.com/pkg/errors"
"github.com/vmihailenco/msgpack/v5"
"github.com/vmihailenco/msgpack/v5/msgpcode"
2022-10-01 21:09:54 +03:00
)
2023-09-11 16:51:34 +03:00
var (
FieldNotFound = errors.New("field not found")
NoOpenContainer = errors.New("there is no open container")
)
type msgpackReader struct {
2023-06-16 13:52:56 +03:00
dec *msgpack.Decoder
stack []readContainer
curr readContainer
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
type readContainer struct {
2023-09-11 16:51:34 +03:00
length int
2022-10-01 21:09:54 +03:00
}
func NewMsgpackReader(r io.Reader) Reader {
return &msgpackReader{
2023-06-16 13:52:56 +03:00
dec: msgpack.NewDecoder(r),
stack: make([]readContainer, 0, 2),
2023-09-11 16:51:34 +03:00
curr: readContainer{},
2023-06-16 13:52:56 +03:00
}
}
func (rd *msgpackReader) ReadInt8(v *int8, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeInt8(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadInt16(v *int16, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeInt16(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadInt32(v *int32, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeInt32(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadInt64(v *int64, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeInt64(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadUint8(v *uint8, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeUint8(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadUint16(v *uint16, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeUint16(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadUint32(v *uint32, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeUint32(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadUint64(v *uint64, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeUint64(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadBool(v *bool, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeBool(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadFloat32(v *float32, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeFloat32(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadFloat64(v *float64, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeFloat64(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadString(v *string, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeString(rd.dec, v)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) ReadBytes(v *[]byte, targetField string) error {
2023-09-11 16:51:34 +03:00
return decodeBytes(rd.dec, v)
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) BeginContainer(targetField string) error {
return rd.beginContainer(targetField)
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) EndContainer() error {
return rd.endContainer()
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) BeginCollection(targetField string) error {
return rd.beginContainer(targetField)
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) EndCollection() error {
return rd.endContainer()
2022-10-01 21:09:54 +03:00
}
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) ContainerSize() (int, error) {
return rd.curr.length, nil
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) IsContainerAssoc() (bool, error) {
return false, nil
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) Skip() error {
return errors.WithStack(rd.dec.Skip())
}
func (rd *msgpackReader) TryReadMask() (bool, FieldsMask, error) {
maskLen, err := rd.dec.DecodeArrayLen()
if err != nil {
if err == io.EOF {
return false, FieldsMask{}, nil
2023-06-16 13:52:56 +03:00
}
2023-09-11 16:51:34 +03:00
return false, FieldsMask{}, errors.WithStack(err)
}
2023-06-16 13:52:56 +03:00
2023-09-11 16:51:34 +03:00
var mask FieldsMask
for i := 0; i < maskLen; i++ {
maskPart, err := rd.dec.DecodeUint64()
2023-06-16 13:52:56 +03:00
if err != nil {
2023-09-11 16:51:34 +03:00
return false, FieldsMask{}, errors.WithStack(err)
2023-06-16 13:52:56 +03:00
}
2023-09-11 16:51:34 +03:00
mask.SetPartFromUint64(i, maskPart)
2023-06-16 13:52:56 +03:00
}
2023-09-11 16:51:34 +03:00
return true, mask, nil
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
func (rd *msgpackReader) beginContainer(field string) error {
code, err := rd.dec.PeekCode()
2022-10-01 21:09:54 +03:00
if err != nil {
return errors.WithStack(err)
2022-10-01 21:09:54 +03:00
}
switch {
case msgpcode.IsFixedArray(code), code == msgpcode.Array16, code == msgpcode.Array32:
l, err := rd.dec.DecodeArrayLen()
2022-10-01 21:09:54 +03:00
if err != nil {
return errors.WithStack(err)
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
rd.stack = append(rd.stack, rd.curr)
rd.curr = readContainer{
2023-09-11 16:51:34 +03:00
length: l,
2023-06-16 13:52:56 +03:00
}
default:
2023-09-11 16:51:34 +03:00
return errors.Errorf("field `%s` is not an array", field)
2022-10-01 21:09:54 +03:00
}
return nil
}
2022-10-01 21:09:54 +03:00
2023-09-11 16:51:34 +03:00
func (rd *msgpackReader) endContainer() error {
2023-06-16 13:52:56 +03:00
if len(rd.stack) == 0 {
return NoOpenContainer
2022-10-01 21:09:54 +03:00
}
2023-06-16 13:52:56 +03:00
rd.curr = rd.stack[len(rd.stack)-1]
rd.stack = rd.stack[:len(rd.stack)-1]
return nil
}
2022-10-01 21:09:54 +03:00
2023-06-16 13:52:56 +03:00
func decodeUint8(dec *msgpack.Decoder, v *uint8) error {
tmp, err := dec.DecodeUint8()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeUint16(dec *msgpack.Decoder, v *uint16) error {
tmp, err := dec.DecodeUint16()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeUint32(dec *msgpack.Decoder, v *uint32) error {
tmp, err := dec.DecodeUint32()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeUint64(dec *msgpack.Decoder, v *uint64) error {
tmp, err := dec.DecodeUint64()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeInt8(dec *msgpack.Decoder, v *int8) error {
tmp, err := dec.DecodeInt8()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeInt16(dec *msgpack.Decoder, v *int16) error {
tmp, err := dec.DecodeInt16()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeInt32(dec *msgpack.Decoder, v *int32) error {
tmp, err := dec.DecodeInt32()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeInt64(dec *msgpack.Decoder, v *int64) error {
tmp, err := dec.DecodeInt64()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeBool(dec *msgpack.Decoder, v *bool) error {
tmp, err := dec.DecodeBool()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeFloat32(dec *msgpack.Decoder, v *float32) error {
tmp, err := dec.DecodeFloat32()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeFloat64(dec *msgpack.Decoder, v *float64) error {
tmp, err := dec.DecodeFloat64()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeString(dec *msgpack.Decoder, v *string) error {
tmp, err := dec.DecodeString()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}
func decodeBytes(dec *msgpack.Decoder, v *[]byte) error {
tmp, err := dec.DecodeBytes()
if err != nil {
return errors.WithStack(err)
}
*v = tmp
return nil
}