|
|
|
@ -6,7 +6,6 @@ import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"reflect"
|
|
|
|
|
"math"
|
|
|
|
|
"slices"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type SerializedType uint64
|
|
|
|
@ -39,14 +38,8 @@ func (t FieldTag) String() string {
|
|
|
|
|
return fmt.Sprintf("0x%x", uint64(t))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NodeTypeFor(extensions []ExtType) NodeType {
|
|
|
|
|
digest := []byte("GRAPHVENT_NODE - ")
|
|
|
|
|
|
|
|
|
|
slices.Sort(extensions)
|
|
|
|
|
|
|
|
|
|
for _, ext := range(extensions) {
|
|
|
|
|
digest = binary.BigEndian.AppendUint64(digest, uint64(ext))
|
|
|
|
|
}
|
|
|
|
|
func NodeTypeFor(name string) NodeType {
|
|
|
|
|
digest := []byte("GRAPHVENT_NODE - " + name)
|
|
|
|
|
|
|
|
|
|
hash := sha512.Sum512(digest)
|
|
|
|
|
return NodeType(binary.BigEndian.Uint64(hash[0:8]))
|
|
|
|
@ -66,6 +59,10 @@ func ExtTypeFor[E any, T interface { *E; Extension}]() ExtType {
|
|
|
|
|
return ExtType(SerializedTypeFor[E]())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ExtTypeOf(t reflect.Type) ExtType {
|
|
|
|
|
return ExtType(SerializeType(t.Elem()))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func SignalTypeFor[S Signal]() SignalType {
|
|
|
|
|
return SignalType(SerializedTypeFor[S]())
|
|
|
|
|
}
|
|
|
|
@ -81,7 +78,7 @@ func GetFieldTag(tag string) FieldTag {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TypeStack(ctx *Context, t reflect.Type) ([]byte, error) {
|
|
|
|
|
info, registered := ctx.TypeTypes[t]
|
|
|
|
|
info, registered := ctx.Types[t]
|
|
|
|
|
if registered {
|
|
|
|
|
return binary.BigEndian.AppendUint64(nil, uint64(info.Serialized)), nil
|
|
|
|
|
} else {
|
|
|
|
@ -131,7 +128,7 @@ func UnwrapStack(ctx *Context, stack []byte) (reflect.Type, []byte, error) {
|
|
|
|
|
first_bytes, left := split(stack, 8)
|
|
|
|
|
first := SerializedType(binary.BigEndian.Uint64(first_bytes))
|
|
|
|
|
|
|
|
|
|
info, registered := ctx.TypeMap[first]
|
|
|
|
|
info, registered := ctx.TypesReverse[first]
|
|
|
|
|
if registered {
|
|
|
|
|
return info.Reflect, left, nil
|
|
|
|
|
} else {
|
|
|
|
@ -177,13 +174,13 @@ func UnwrapStack(ctx *Context, stack []byte) (reflect.Type, []byte, error) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Serialize[T any](ctx *Context, value T) ([]byte, error) {
|
|
|
|
|
return serializeValue(ctx, reflect.ValueOf(&value).Elem())
|
|
|
|
|
return SerializeValue(ctx, reflect.ValueOf(&value).Elem())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
value, left, err := DeserializeValue(ctx, data, reflect_type)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return zero, err
|
|
|
|
|
} else if len(left) != 0 {
|
|
|
|
@ -195,10 +192,10 @@ func Deserialize[T any](ctx *Context, data []byte) (T, error) {
|
|
|
|
|
return value.Interface().(T), nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func serializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
func SerializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
var serialize SerializeFn = nil
|
|
|
|
|
|
|
|
|
|
info, registered := ctx.TypeTypes[value.Type()]
|
|
|
|
|
info, registered := ctx.Types[value.Type()]
|
|
|
|
|
if registered {
|
|
|
|
|
serialize = info.Serialize
|
|
|
|
|
}
|
|
|
|
@ -248,7 +245,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
|
|
|
|
|
}
|
|
|
|
@ -265,7 +262,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
|
|
|
|
|
}
|
|
|
|
@ -279,7 +276,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
|
|
|
|
|
}
|
|
|
|
@ -293,16 +290,20 @@ func serializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
binary.BigEndian.PutUint64(len_bytes, uint64(value.Len()))
|
|
|
|
|
|
|
|
|
|
data := []byte{}
|
|
|
|
|
key := reflect.New(value.Type().Key()).Elem()
|
|
|
|
|
val := reflect.New(value.Type().Elem()).Elem()
|
|
|
|
|
iter := value.MapRange()
|
|
|
|
|
for iter.Next() {
|
|
|
|
|
k, err := serializeValue(ctx, iter.Key())
|
|
|
|
|
key.SetIterKey(iter)
|
|
|
|
|
val.SetIterValue(iter)
|
|
|
|
|
|
|
|
|
|
k, err := SerializeValue(ctx, key)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data = append(data, k...)
|
|
|
|
|
|
|
|
|
|
v, err := serializeValue(ctx, iter.Value())
|
|
|
|
|
v, err := SerializeValue(ctx, val)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -319,7 +320,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
|
|
|
|
|
}
|
|
|
|
@ -332,7 +333,7 @@ func serializeValue(ctx *Context, value reflect.Value) ([]byte, error) {
|
|
|
|
|
case reflect.Interface:
|
|
|
|
|
data, err := TypeStack(ctx, value.Elem().Type())
|
|
|
|
|
|
|
|
|
|
val_data, err := serializeValue(ctx, value.Elem())
|
|
|
|
|
val_data, err := SerializeValue(ctx, value.Elem())
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@ -352,10 +353,10 @@ 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]
|
|
|
|
|
info, registered := ctx.Types[t]
|
|
|
|
|
if registered {
|
|
|
|
|
deserialize = info.Deserialize
|
|
|
|
|
}
|
|
|
|
@ -439,7 +440,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
|
|
|
|
|
}
|
|
|
|
@ -454,7 +455,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
|
|
|
|
|
}
|
|
|
|
@ -468,7 +469,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
|
|
|
|
|
}
|
|
|
|
@ -487,12 +488,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
|
|
|
|
|
}
|
|
|
|
@ -503,7 +504,7 @@ func deserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
return value, left, nil
|
|
|
|
|
|
|
|
|
|
case reflect.Struct:
|
|
|
|
|
info, mapped := ctx.TypeTypes[t]
|
|
|
|
|
info, mapped := ctx.Types[t]
|
|
|
|
|
if mapped {
|
|
|
|
|
value := reflect.New(t).Elem()
|
|
|
|
|
|
|
|
|
@ -520,7 +521,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
|
|
|
|
|
}
|
|
|
|
@ -544,7 +545,7 @@ func deserializeValue(ctx *Context, data []byte, t reflect.Type) (reflect.Value,
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elem_val, left, err := deserializeValue(ctx, rest, elem_type)
|
|
|
|
|
elem_val, left, err := DeserializeValue(ctx, rest, elem_type)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return reflect.Value{}, nil, err
|
|
|
|
|
}
|
|
|
|
|