Open schalekamp opened 2 years ago
If you can, change the code to msg2[208] = &md
. Proper fix requires changes to the library.
this seems to work btw
func decimalDecoder(dec *msgpack.Decoder, v reflect.Value, extLen int) error {
rdr := dec.Buffered()
data := make([]byte, extLen)
rdr.Read(data)
d, err := decimal.NewFromString(string(data))
if err != nil {
return err
}
if d_ptr, ok := v.Addr().Interface().(*decimal.Decimal); ok {
*d_ptr = d
return nil
} else {
return errors.New("decoding msgpack decimal value to wrong type")
}
}
func decimalEncoder(enc *msgpack.Encoder, v reflect.Value) ([]byte, error) {
if d, ok := v.Interface().(decimal.Decimal); ok {
s := d.String()
return []byte(s), nil
} else {
return nil, errors.New("could not convert value to *decimal.Decimal")
}
}
func init() {
msgpack.RegisterExtDecoder(4, decimal.Decimal{}, decimalDecoder)
msgpack.RegisterExtEncoder(4, decimal.Decimal{}, decimalEncoder)
}
Yes, you got the right idea. Ideally, the library should handle such situations better automatically...
I agree. whenever you have time for that ofcourse. Meanwhile thank you for writing and maintaining the library. It is great.
For those of you who are still having issues with this, I used this function. Essentially, I made all the encoding into non-pointer functions and made an "asymmetric ext registration". It's a workaround that works, I suppose, but you don't get that nice clean everything-is-a-pointer declaration.
func RegisterAsymmetricExt(extID int8, marshalType msgpack.Marshaler, unmarshalType msgpack.Unmarshaler) {
msgpack.RegisterExtEncoder(extID, marshalType, func(e *msgpack.Encoder, v reflect.Value) ([]byte, error) {
marshaler := v.Interface().(msgpack.Marshaler)
return marshaler.MarshalMsgpack()
})
msgpack.RegisterExtDecoder(extID, unmarshalType, func(d *msgpack.Decoder, v reflect.Value, extLen int) error {
b := make([]byte, extLen)
err := d.ReadFull(b)
// b, err := d.readN(extLen)
if err != nil {
return err
}
return v.Interface().(msgpack.Unmarshaler).UnmarshalMsgpack(b)
})
}
func init() {
RegisterAsymmetricExt(int8(VECTOR4_TYPE_CODE), Vector4{}, (*Vector4)(nil))
}
func (v Vector4) MarshalMsgpack() ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.BigEndian, v)
if err != nil {
return nil, err
}
return buf.Bytes(), err
}
func (v *Vector4) UnmarshalMsgpack(b []byte) error {
if len(b) != 16 {
return fmt.Errorf("invalid data length: got %d, wanted 16", len(b))
}
r := bytes.NewReader(b)
return binary.Read(r, binary.BigEndian, v)
}
this seems to work btw
Thank you, I suggest another solution that will work on other types too.
// RegisterBinaryExt registers a binary marshaler/unmarshaler for the given type.
// The type must be implemented both interfaces.
func RegisterBinaryExt[T encoding.BinaryMarshaler, _ interface {
encoding.BinaryUnmarshaler
*T
}](extID int8) {
var zero T
msgpack.RegisterExtEncoder(extID, zero, func(e *msgpack.Encoder, v reflect.Value) ([]byte, error) {
m := v.Interface().(encoding.BinaryMarshaler)
return m.MarshalBinary()
})
msgpack.RegisterExtDecoder(extID, zero, func(d *msgpack.Decoder, v reflect.Value, extLen int) error {
u := v.Addr().Interface().(encoding.BinaryUnmarshaler)
b := make([]byte, extLen)
if err := d.ReadFull(b); err != nil {
return err
}
return u.UnmarshalBinary(b)
})
}
func init() {
RegisterBinaryExt[decimal.Decimal](1)
}
When I try the run the following code I get the following error:
error encoding message with encoder msgpack: Decode(nonaddressable main.MyDecimal) encoded bytes: [131 204 204 204 188 205 1 44 207 0 0 1 119 10 189 34 219 204 208] error decoding message EOF decoded map: map[204:188 300:1610792903387]