Added deserialize to pointer

gql_cataclysm
noah metz 2023-09-02 18:49:37 -06:00
parent 1888cf428d
commit 799b6404dd
3 changed files with 148 additions and 67 deletions

@ -84,20 +84,7 @@ var (
PerNodePolicyType = NewPolicyType("PER_NODE") PerNodePolicyType = NewPolicyType("PER_NODE")
AllNodesPolicyType = NewPolicyType("ALL_NODES") AllNodesPolicyType = NewPolicyType("ALL_NODES")
StructType = NewSerializedType("struct") ErrorType = NewSerializedType("ERROR")
SliceType = NewSerializedType("slice")
ArrayType = NewSerializedType("array")
PointerType = NewSerializedType("pointer")
MapType = NewSerializedType("map")
ErrorType = NewSerializedType("error")
ExtensionType = NewSerializedType("extension")
StringType = NewSerializedType("string")
IntType = NewSerializedType("int")
Uint8Type = NewSerializedType("uint8")
Uint32Type = NewSerializedType("uint32")
Uint64Type = NewSerializedType("uint64")
NodeKeyType = NewSerializedType("node_key")
NodeNotFoundError = errors.New("Node not found in DB") NodeNotFoundError = errors.New("Node not found in DB")
ECDH = ecdh.X25519() ECDH = ecdh.X25519()
@ -113,7 +100,7 @@ type NodeInfo struct {
} }
type TypeSerialize func(*Context,uint64,reflect.Type,*reflect.Value) (SerializedValue, error) type TypeSerialize func(*Context,uint64,reflect.Type,*reflect.Value) (SerializedValue, error)
type TypeDeserialize func(*Context,SerializedValue) (interface{}, []byte, error) type TypeDeserialize func(*Context,[]uint64,[]byte) (reflect.Type, *reflect.Value, []byte, error)
type TypeInfo struct { type TypeInfo struct {
Type reflect.Type Type reflect.Type
Serialize TypeSerialize Serialize TypeSerialize
@ -405,45 +392,64 @@ func ParseSerializedValue(ctx *Context, data []byte) (SerializedValue, error) {
type_stack[i] = binary.BigEndian.Uint64(data[type_start:type_end]) type_stack[i] = binary.BigEndian.Uint64(data[type_start:type_end])
} }
types_end := 8*(num_types + 1) types_end := 8*(num_types + 2)
return SerializedValue{ return SerializedValue{
type_stack, type_stack,
data[types_end:(types_end+data_size)], data[types_end:(types_end+data_size)],
}, nil }, nil
} }
func DeserializeValue(ctx *Context, value SerializedValue, n int) ([]interface{}, []byte, error) { func DeserializeValue(ctx *Context, type_stack []uint64, data []byte, n int) (reflect.Type, []reflect.Value, []byte, error) {
ret := make([]interface{}, n) ret := make([]reflect.Value, n)
var deserialize TypeDeserialize = nil var deserialize TypeDeserialize = nil
var reflect_type reflect.Type = nil
ctx_type := type_stack[0]
type_stack = type_stack[1:]
ctx_type := value.TypeStack[0]
type_info, exists := ctx.Types[SerializedType(ctx_type)] type_info, exists := ctx.Types[SerializedType(ctx_type)]
if exists == true { if exists == true {
deserialize = type_info.Deserialize deserialize = type_info.Deserialize
reflect_type = type_info.Type
} else { } else {
kind, exists := ctx.KindTypes[SerializedType(ctx_type)] kind, exists := ctx.KindTypes[SerializedType(ctx_type)]
if exists == false { if exists == false {
return nil, nil, fmt.Errorf("Cannot deserialize 0x%x: unknown type/kind", ctx_type) return nil, nil, nil, fmt.Errorf("Cannot deserialize 0x%x: unknown type/kind", ctx_type)
} }
kind_info := ctx.Kinds[kind] kind_info := ctx.Kinds[kind]
deserialize = kind_info.Deserialize deserialize = kind_info.Deserialize
} }
remaining_data := value.Data remaining_data := data
for i := 0; i < n; i += 1 { var value_type reflect.Type = nil
var elem interface{} = nil var err error = nil
var err error = nil if data == nil {
elem, remaining_data, err = deserialize(ctx, value) reflect_type, _, _, err = deserialize(ctx, type_stack, nil)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if len(remaining_data) == 0 { } else {
remaining_data = nil for i := 0; i < n; i += 1 {
var elem *reflect.Value
var elem_type reflect.Type = nil
elem_type, elem, remaining_data, err = deserialize(ctx, type_stack, remaining_data)
if err != nil {
return nil, nil, nil, err
}
if value_type == nil {
value_type = elem_type
}
if len(remaining_data) == 0 {
remaining_data = nil
}
if elem == nil {
return nil, nil, nil, fmt.Errorf("root deserialize returned no value")
}
ret[i] = *elem
} }
ret[i] = elem
} }
return ret, remaining_data, nil return reflect_type, ret, remaining_data, nil
} }
// Create a new Context with the base library content added // Create a new Context with the base library content added
@ -490,8 +496,40 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
append([]uint64{ctx_type}, elem.TypeStack...), append([]uint64{ctx_type}, elem.TypeStack...),
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue) (interface{}, []byte, error) { }, func(ctx *Context, type_stack []uint64, data []byte) (reflect.Type, *reflect.Value, []byte, error) {
return nil, nil, fmt.Errorf("deserialize pointer unimplemented") // TODO: figure out how to deal with the case where the pointer value is nil
// In that case need to figure out the type of the pointer to create the nil pointer, which involves continuing to recuse the type stack without parsing any data
if data == nil {
elem_type, _, _, err := DeserializeValue(ctx, type_stack, nil, 1)
if err != nil {
return nil, nil, nil, err
}
return elem_type, nil, nil, nil
} else {
if len(data) < 1 {
return nil, nil, nil, fmt.Errorf("Not enough data to deserialize pointer")
}
pointer_flags := data[0]
if pointer_flags == 0x00 {
_, elem_value, remaining_data, err := DeserializeValue(ctx, type_stack, data[1:], 1)
if err != nil {
return nil, nil, nil, err
}
pointer_value := elem_value[0].Addr()
return pointer_value.Type(), &pointer_value, remaining_data, nil
} else if pointer_flags == 0x01 {
elem_type, _, _, err := DeserializeValue(ctx, type_stack, nil, 1)
if err != nil {
return nil, nil, nil, err
}
pointer_type := reflect.PointerTo(elem_type)
pointer_value := reflect.New(pointer_type).Elem()
return pointer_type, &pointer_value, data[1:], nil
} else {
return nil, nil, nil, fmt.Errorf("unknown pointer flags: %d", pointer_flags)
}
}
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -547,8 +585,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
list_serial.Data, list_serial.Data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize struct not implemented") return nil, nil, nil, fmt.Errorf("deserialize struct not implemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -565,15 +603,16 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
if len(value.Data) < 8 { if len(data) < 8 {
return reflect.Value{}, nil, fmt.Errorf("invalid length: %d/8", len(value.Data)) return nil, nil, nil, fmt.Errorf("invalid length: %d/8", len(data))
} }
remaining_data := value.Data[8:] remaining_data := data[8:]
if len(remaining_data) == 0 { if len(remaining_data) == 0 {
remaining_data = nil remaining_data = nil
} }
return int(binary.BigEndian.Uint64(value.Data[0:8])), remaining_data, nil int_val := reflect.ValueOf(binary.BigEndian.Uint64(data[0:8]))
return int_val.Type(), &int_val, remaining_data, nil
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -589,8 +628,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize uint32 unimplemented") return nil, nil, nil, fmt.Errorf("deserialize uint32 unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -612,8 +651,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{uint64(ctx_type)}, []uint64{uint64(ctx_type)},
append(data, []byte(str)...), append(data, []byte(str)...),
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize string unimplemented") return nil, nil, nil, fmt.Errorf("deserialize string unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -654,8 +693,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
append([]uint64{ctx_type}, elem.TypeStack...), append([]uint64{ctx_type}, elem.TypeStack...),
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize array unimplemented") return nil, nil, nil, fmt.Errorf("deserialize array unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -682,8 +721,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
append([]uint64{ctx_type}, type_stack...), append([]uint64{ctx_type}, type_stack...),
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize interface unimplemented") return nil, nil, nil, fmt.Errorf("deserialize interface unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -757,8 +796,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
type_stack, type_stack,
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize map unimplemented") return nil, nil, nil, fmt.Errorf("deserialize map unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -775,8 +814,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize uint8 unimplemented") return nil, nil, nil, fmt.Errorf("deserialize uint8 unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -793,8 +832,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("deserialize uint64 unimplemented") return nil, nil, nil, fmt.Errorf("deserialize uint64 unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -837,8 +876,50 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
elem.TypeStack, elem.TypeStack,
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue)(interface{}, []byte, error){ }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("not implemented") return nil, nil, nil, fmt.Errorf("not implemented")
})
if err != nil {
return nil, err
}
err = ctx.RegisterType(reflect.TypeOf(StringError("")), ErrorType,
func(ctx *Context, ctx_type uint64, t reflect.Type, value *reflect.Value) (SerializedValue, error) {
if value == nil {
return SerializedValue{
[]uint64{ctx_type},
nil,
}, nil
}
data := make([]byte, 8)
err := value.Interface().(StringError)
str := string(err)
binary.BigEndian.PutUint64(data, uint64(len(str)))
return SerializedValue{
[]uint64{uint64(ctx_type)},
append(data, []byte(str)...),
}, nil
}, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, nil, fmt.Errorf("unimplemented")
})
err = ctx.RegisterType(reflect.TypeOf(RandID()), NewSerializedType("NodeID"),
func(ctx *Context, ctx_type uint64, t reflect.Type, value *reflect.Value) (SerializedValue, error) {
var id_ser []byte = nil
if value != nil {
var err error = nil
id_ser, err = value.Interface().(NodeID).MarshalBinary()
if err != nil {
return SerializedValue{}, err
}
}
return SerializedValue{
[]uint64{ctx_type},
id_ser,
}, nil
}, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, nil, fmt.Errorf("unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -855,8 +936,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue) (interface{}, []byte, error) { }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("unimplemented") return reflect.TypeOf(Up), nil, nil, fmt.Errorf("unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -873,8 +954,8 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) {
[]uint64{ctx_type}, []uint64{ctx_type},
data, data,
}, nil }, nil
}, func(ctx *Context, value SerializedValue) (interface{}, []byte, error) { }, func(ctx *Context, type_stack []uint64, data []byte)(reflect.Type, *reflect.Value, []byte, error){
return nil, nil, fmt.Errorf("unimplemented") return reflect.TypeOf(ReqState(0)), nil, nil, fmt.Errorf("unimplemented")
}) })
if err != nil { if err != nil {
return nil, err return nil, err

@ -661,11 +661,11 @@ func LoadNode(ctx * Context, id NodeID) (*Node, error) {
return nil, err return nil, err
} }
node_value, err := ParseSerializedValue(ctx, bytes) value, err := ParseSerializedValue(ctx, bytes)
if err != nil { if err != nil {
return nil, err return nil, err
} }
node_if, remaining, err := DeserializeValue(ctx, node_value, 1) _, node_val, remaining, err := DeserializeValue(ctx, value.TypeStack, value.Data, 1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -674,9 +674,9 @@ func LoadNode(ctx * Context, id NodeID) (*Node, error) {
return nil, fmt.Errorf("%d bytes left after desrializing *Node", len(remaining)) return nil, fmt.Errorf("%d bytes left after desrializing *Node", len(remaining))
} }
node, ok := node_if[0].(*Node) node, ok := node_val[0].Interface().(*Node)
if ok == false { if ok == false {
return nil, fmt.Errorf("Deserialized %+v when expecting *Node", reflect.TypeOf(node_if).Elem()) return nil, fmt.Errorf("Deserialized %+v when expecting *Node", reflect.TypeOf(node_val).Elem())
} }
ctx.AddNode(id, node) ctx.AddNode(id, node)

@ -64,12 +64,12 @@ func (policy *RequirementOfPolicy) ContinueAllows(ctx *Context, current PendingA
return Deny return Deny
} }
reqs_if, _, err := DeserializeValue(ctx, reqs_ser, 1) _, reqs_if, _, err := DeserializeValue(ctx, reqs_ser.TypeStack, reqs_ser.Data, 1)
if err != nil { if err != nil {
return Deny return Deny
} }
requirements, ok := reqs_if[0].(map[NodeID]ReqState) requirements, ok := reqs_if[0].Interface().(map[NodeID]ReqState)
if ok == false { if ok == false {
return Deny return Deny
} }
@ -113,12 +113,12 @@ func (policy *MemberOfPolicy) ContinueAllows(ctx *Context, current PendingACL, s
return Deny return Deny
} }
members_if, _, err := DeserializeValue(ctx, members_ser, 1) _, members_if, _, err := DeserializeValue(ctx, members_ser.TypeStack, members_ser.Data, 1)
if err != nil { if err != nil {
return Deny return Deny
} }
members, ok := members_if[0].(map[NodeID]string) members, ok := members_if[0].Interface().(map[NodeID]string)
if ok == false { if ok == false {
return Deny return Deny
} }