tape: Ignore type names when encoding primitives using reflection

This commit is contained in:
Sasha Koshka 2025-07-05 22:10:55 -04:00
parent 0f20c4cdab
commit 76a8f9444a

View File

@ -12,6 +12,7 @@ import "fmt"
import "reflect" import "reflect"
var dummyMap map[uint16] any var dummyMap map[uint16] any
var dummyBuffer []byte
// EncodeAny encodes an "any" value. Returns an error if the underlying type is // EncodeAny encodes an "any" value. Returns an error if the underlying type is
// unsupported. Supported types are: // unsupported. Supported types are:
@ -24,26 +25,27 @@ var dummyMap map[uint16] any
// - []<supported type> // - []<supported type>
// - map[uint16]<supported type> // - map[uint16]<supported type>
func EncodeAny(encoder *Encoder, value any, tag Tag) (n int, err error) { func EncodeAny(encoder *Encoder, value any, tag Tag) (n int, err error) {
// TODO use reflection for all of this to ignore type names
// primitives // primitives
switch value := value.(type) { reflectValue := reflect.ValueOf(value)
case int: return encoder.WriteInt32(int32(value)) switch reflectValue.Kind() {
case uint: return encoder.WriteUint32(uint32(value)) case reflect.Int: return encoder.WriteInt32(int32(reflectValue.Int()))
case int8: return encoder.WriteInt8(value) case reflect.Uint: return encoder.WriteUint32(uint32(reflectValue.Uint()))
case uint8: return encoder.WriteUint8(value) case reflect.Int8: return encoder.WriteInt8(int8(reflectValue.Int()))
case int16: return encoder.WriteInt16(value) case reflect.Uint8: return encoder.WriteUint8(uint8(reflectValue.Uint()))
case uint16: return encoder.WriteUint16(value) case reflect.Int16: return encoder.WriteInt16(int16(reflectValue.Int()))
case int32: return encoder.WriteInt32(value) case reflect.Uint16: return encoder.WriteUint16(uint16(reflectValue.Uint()))
case uint32: return encoder.WriteUint32(value) case reflect.Int32: return encoder.WriteInt32(int32(reflectValue.Int()))
case int64: return encoder.WriteInt64(value) case reflect.Uint32: return encoder.WriteUint32(uint32(reflectValue.Uint()))
case uint64: return encoder.WriteUint64(value) case reflect.Int64: return encoder.WriteInt64(int64(reflectValue.Int()))
case string: return EncodeAny(encoder, []byte(value), tag) case reflect.Uint64: return encoder.WriteUint64(uint64(reflectValue.Uint()))
case []byte: case reflect.String: return EncodeAny(encoder, []byte(reflectValue.String()), tag)
}
if reflectValue.CanConvert(reflect.TypeOf(dummyBuffer)) {
if tag.Is(LBA) { if tag.Is(LBA) {
nn, err := encoder.WriteUintN(uint64(len(value)), tag.CN() + 1) nn, err := encoder.WriteUintN(uint64(reflectValue.Len()), tag.CN() + 1)
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
} }
nn, err := encoder.Write(value) nn, err := encoder.Write(reflectValue.Bytes())
n += nn; if err != nil { return n, err } n += nn; if err != nil { return n, err }
return n, nil return n, nil
} }