diff --git a/tape/dynamic.go b/tape/dynamic.go index dd89055..ab78e01 100644 --- a/tape/dynamic.go +++ b/tape/dynamic.go @@ -99,6 +99,10 @@ func decodeAny(decoder *Decoder, destination reflect.Value, tag Tag) (n int, err if err != nil { return n, err } case LI: // LI: + nn, err := decodeAndSetUint(decoder, destination, tag.CN() + 1) + n += nn; if err != nil { return n, err } + case LSI: + // LSI: nn, err := decodeAndSetInt(decoder, destination, tag.CN() + 1) n += nn; if err != nil { return n, err } case FP: @@ -171,13 +175,18 @@ func TagAny(value any) (Tag, error) { // TODO use reflection for all of this to ignore type names // primitives switch value := value.(type) { - case int, uint: return LI.WithCN(3), nil - case int8, uint8: return LI.WithCN(0), nil - case int16, uint16: return LI.WithCN(1), nil - case int32, uint32: return LI.WithCN(3), nil - case int64, uint64: return LI.WithCN(7), nil - case string: return bufferLenTag(len(value)), nil - case []byte: return bufferLenTag(len(value)), nil + case int: return LSI.WithCN(3), nil + case int8: return LSI.WithCN(0), nil + case int16: return LSI.WithCN(1), nil + case int32: return LSI.WithCN(3), nil + case int64: return LSI.WithCN(7), nil + case uint: return LI.WithCN(3), nil + case uint8: return LI.WithCN(0), nil + case uint16: return LI.WithCN(1), nil + case uint32: return LI.WithCN(3), nil + case uint64: return LI.WithCN(7), nil + case string: return bufferLenTag(len(value)), nil + case []byte: return bufferLenTag(len(value)), nil } // aggregates @@ -241,7 +250,7 @@ func encodeAnyMap(encoder *Encoder, value any, tag Tag) (n int, err error) { } // setInt expects a settable destination. -func setInt(destination reflect.Value, value uint64) error { +func setInt[T int64 | uint64](destination reflect.Value, value T) error { switch { case destination.CanInt(): destination.Set(reflect.ValueOf(int64(value)).Convert(destination.Type())) @@ -277,6 +286,13 @@ func setByteArray(destination reflect.Value, value []byte) error { // decodeAndSetInt expects a settable destination. func decodeAndSetInt(decoder *Decoder, destination reflect.Value, bytes int) (n int, err error) { + value, nn, err := decoder.ReadIntN(bytes) + n += nn; if err != nil { return n, err } + return n, setInt(destination, value) +} + +// decodeAndSetUint expects a settable destination. +func decodeAndSetUint(decoder *Decoder, destination reflect.Value, bytes int) (n int, err error) { value, nn, err := decoder.ReadUintN(bytes) n += nn; if err != nil { return n, err } return n, setInt(destination, value)