|
|
|
@ -190,7 +190,26 @@ func UnwrapStack(ctx *Context, stack []SerializedType) (reflect.Type, []Serializ
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
func Serialize[T any](ctx *Context, value T) ([]byte, error) {
|
|
|
|
|
return serializeValue(ctx, reflect.ValueOf(value))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Deserialize[T any](ctx *Context, data []byte) (T, error) {
|
|
|
|
|
reflect_type := reflect.TypeFor[T]()
|
|
|
|
|
var zero T
|
|
|
|
|
value, left, err := deserializeValue(ctx, data, reflect_type)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return zero, err
|
|
|
|
|
} else if len(left) != 0 {
|
|
|
|
|
return zero, fmt.Errorf("%d bytes left after deserializing %+v", len(left), value)
|
|
|
|
|
} else if value.Type() != reflect_type {
|
|
|
|
|
return zero, fmt.Errorf("Deserialized type %s does not match %s", value.Type(), reflect_type)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value.Interface().(T), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func serializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
var serialize SerializeFn = nil
|
|
|
|
|
|
|
|
|
|
info, registered := ctx.TypeTypes[value.Type()]
|
|
|
|
@ -243,7 +262,7 @@ func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
if value.IsNil() {
|
|
|
|
|
return []byte{0x00}, nil
|
|
|
|
|
} else {
|
|
|
|
|
elem, err := SerializeValue(ctx, value.Elem())
|
|
|
|
|
elem, err := serializeValue(ctx, value.Elem())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -260,7 +279,7 @@ func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
|
|
|
|
|
data := []byte{}
|
|
|
|
|
for i := 0; i < value.Len(); i++ {
|
|
|
|
|
elem, err := SerializeValue(ctx, value.Index(i))
|
|
|
|
|
elem, err := serializeValue(ctx, value.Index(i))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -274,7 +293,7 @@ func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
case reflect.Array:
|
|
|
|
|
data := []byte{}
|
|
|
|
|
for i := 0; i < value.Len(); i++ {
|
|
|
|
|
elem, err := SerializeValue(ctx, value.Index(i))
|
|
|
|
|
elem, err := serializeValue(ctx, value.Index(i))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -290,14 +309,14 @@ func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
data := []byte{}
|
|
|
|
|
iter := value.MapRange()
|
|
|
|
|
for iter.Next() {
|
|
|
|
|
k, err := SerializeValue(ctx, iter.Key())
|
|
|
|
|
k, err := serializeValue(ctx, iter.Key())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data = append(data, k...)
|
|
|
|
|
|
|
|
|
|
v, err := SerializeValue(ctx, iter.Value())
|
|
|
|
|
v, err := serializeValue(ctx, iter.Value())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -314,7 +333,7 @@ func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
|
|
|
|
|
for field_tag, field_info := range(info.Fields) {
|
|
|
|
|
data = append(data, binary.BigEndian.AppendUint64(nil, uint64(field_tag))...)
|
|
|
|
|
field_bytes, err := SerializeValue(ctx, value.FieldByIndex(field_info.Index))
|
|
|
|
|
field_bytes, err := serializeValue(ctx, value.FieldByIndex(field_info.Index))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -336,7 +355,7 @@ func split(data []byte, n int) ([]byte, []byte) {
|
|
|
|
|
return data[:n], data[n:]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func DeserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value, []byte, error) {
|
|
|
|
|
func deserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value, []byte, error) {
|
|
|
|
|
var deserialize DeserializeFn = nil
|
|
|
|
|
|
|
|
|
|
info, registered := ctx.TypeTypes[t]
|
|
|
|
@ -423,7 +442,7 @@ func DeserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
value.SetZero()
|
|
|
|
|
return value, after_flags, nil
|
|
|
|
|
} else {
|
|
|
|
|
elem_value, after_elem, err := DeserializeValue(ctx, after_flags, t.Elem())
|
|
|
|
|
elem_value, after_elem, err := deserializeValue(ctx, after_flags, t.Elem())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
@ -438,7 +457,7 @@ func DeserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
for i := 0; i < length; i++ {
|
|
|
|
|
var elem_value reflect.Value
|
|
|
|
|
var err error
|
|
|
|
|
elem_value, left, err = DeserializeValue(ctx, left, t.Elem())
|
|
|
|
|
elem_value, left, err = deserializeValue(ctx, left, t.Elem())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
@ -452,7 +471,7 @@ func DeserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
for i := 0; i < t.Len(); i++ {
|
|
|
|
|
var elem_value reflect.Value
|
|
|
|
|
var err error
|
|
|
|
|
elem_value, left, err = DeserializeValue(ctx, left, t.Elem())
|
|
|
|
|
elem_value, left, err = deserializeValue(ctx, left, t.Elem())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
@ -471,12 +490,12 @@ func DeserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
var val_value reflect.Value
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
key_value, left, err = DeserializeValue(ctx, left, t.Key())
|
|
|
|
|
key_value, left, err = deserializeValue(ctx, left, t.Key())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val_value, left, err = DeserializeValue(ctx, left, t.Elem())
|
|
|
|
|
val_value, left, err = deserializeValue(ctx, left, t.Elem())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
@ -504,7 +523,7 @@ func DeserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
if mapped {
|
|
|
|
|
var field_val reflect.Value
|
|
|
|
|
var err error
|
|
|
|
|
field_val, left, err = DeserializeValue(ctx, left, field_info.Type)
|
|
|
|
|
field_val, left, err = deserializeValue(ctx, left, field_info.Type)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
|