2023-07-09 14:30:30 -06:00
|
|
|
package graphvent
|
|
|
|
|
|
|
|
import (
|
2023-09-05 00:08:09 -06:00
|
|
|
"crypto/ecdh"
|
|
|
|
"encoding/binary"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"math"
|
|
|
|
"reflect"
|
|
|
|
"runtime"
|
|
|
|
"sync"
|
2023-09-12 19:00:48 -06:00
|
|
|
"github.com/google/uuid"
|
2023-09-05 00:08:09 -06:00
|
|
|
|
|
|
|
badger "github.com/dgraph-io/badger/v3"
|
2023-07-27 23:15:58 -06:00
|
|
|
)
|
|
|
|
|
2023-07-28 00:04:18 -06:00
|
|
|
var (
|
|
|
|
NodeNotFoundError = errors.New("Node not found in DB")
|
2023-08-07 20:26:02 -06:00
|
|
|
ECDH = ecdh.X25519()
|
2023-07-28 00:04:18 -06:00
|
|
|
)
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
type ExtensionInfo struct {
|
|
|
|
Type reflect.Type
|
|
|
|
Data interface{}
|
|
|
|
}
|
2023-08-01 20:55:15 -06:00
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
type NodeInfo struct {
|
|
|
|
Extensions []ExtType
|
2023-08-01 20:55:15 -06:00
|
|
|
}
|
2023-07-29 00:28:44 -06:00
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
type TypeInfo struct {
|
2023-09-06 18:29:35 -06:00
|
|
|
Reflect reflect.Type
|
|
|
|
Type SerializedType
|
2023-08-31 19:50:32 -06:00
|
|
|
Serialize TypeSerialize
|
|
|
|
Deserialize TypeDeserialize
|
2023-07-29 00:28:44 -06:00
|
|
|
}
|
|
|
|
|
2023-09-05 00:08:09 -06:00
|
|
|
type KindInfo struct {
|
2023-09-06 18:29:35 -06:00
|
|
|
Reflect reflect.Kind
|
2023-09-05 00:08:09 -06:00
|
|
|
Type SerializedType
|
|
|
|
Serialize TypeSerialize
|
|
|
|
Deserialize TypeDeserialize
|
|
|
|
}
|
|
|
|
|
2023-07-27 16:06:56 -06:00
|
|
|
// A Context stores all the data to run a graphvent process
|
2023-07-09 14:30:30 -06:00
|
|
|
type Context struct {
|
2023-07-10 22:31:43 -06:00
|
|
|
// DB is the database connection used to load and write nodes
|
2023-07-09 14:30:30 -06:00
|
|
|
DB * badger.DB
|
2023-07-27 16:06:56 -06:00
|
|
|
// Logging interface
|
2023-07-09 14:30:30 -06:00
|
|
|
Log Logger
|
2023-07-27 16:06:56 -06:00
|
|
|
// Map between database extension hashes and the registered info
|
2023-08-31 19:50:32 -06:00
|
|
|
Extensions map[ExtType]ExtensionInfo
|
|
|
|
ExtensionTypes map[reflect.Type]ExtType
|
2023-08-07 20:26:02 -06:00
|
|
|
// Map between databse policy hashes and the registered info
|
2023-08-31 19:50:32 -06:00
|
|
|
Policies map[PolicyType]reflect.Type
|
|
|
|
PolicyTypes map[reflect.Type]PolicyType
|
2023-07-29 00:28:44 -06:00
|
|
|
// Map between serialized signal hashes and the registered info
|
2023-08-31 19:50:32 -06:00
|
|
|
Signals map[SignalType]reflect.Type
|
|
|
|
SignalTypes map[reflect.Type]SignalType
|
2023-07-27 16:06:56 -06:00
|
|
|
// Map between database type hashes and the registered info
|
2023-08-31 19:50:32 -06:00
|
|
|
Nodes map[NodeType]NodeInfo
|
|
|
|
// Map between go types and registered info
|
2023-09-06 18:29:35 -06:00
|
|
|
Types map[SerializedType]*TypeInfo
|
|
|
|
TypeReflects map[reflect.Type]*TypeInfo
|
2023-08-31 19:50:32 -06:00
|
|
|
|
2023-09-06 18:29:35 -06:00
|
|
|
Kinds map[reflect.Kind]*KindInfo
|
|
|
|
KindTypes map[SerializedType]*KindInfo
|
2023-09-02 17:30:52 -06:00
|
|
|
|
2023-07-27 16:06:56 -06:00
|
|
|
// Routing map to all the nodes local to this context
|
2023-08-31 19:50:32 -06:00
|
|
|
nodeMapLock sync.RWMutex
|
|
|
|
nodeMap map[NodeID]*Node
|
2023-07-10 21:15:01 -06:00
|
|
|
}
|
|
|
|
|
2023-07-27 16:06:56 -06:00
|
|
|
// Register a NodeType to the context, with the list of extensions it requires
|
2023-07-26 00:42:12 -06:00
|
|
|
func (ctx *Context) RegisterNodeType(node_type NodeType, extensions []ExtType) error {
|
2023-08-31 19:50:32 -06:00
|
|
|
_, exists := ctx.Nodes[node_type]
|
2023-07-26 00:18:11 -06:00
|
|
|
if exists == true {
|
2023-08-31 19:50:32 -06:00
|
|
|
return fmt.Errorf("Cannot register node type %+v, type already exists in context", node_type)
|
2023-07-26 00:18:11 -06:00
|
|
|
}
|
|
|
|
|
2023-07-26 00:42:12 -06:00
|
|
|
ext_found := map[ExtType]bool{}
|
|
|
|
for _, extension := range(extensions) {
|
2023-08-31 19:50:32 -06:00
|
|
|
_, in_ctx := ctx.Extensions[extension]
|
2023-07-26 00:42:12 -06:00
|
|
|
if in_ctx == false {
|
2023-08-31 19:50:32 -06:00
|
|
|
return fmt.Errorf("Cannot register node type %+v, required extension %+v not in context", node_type, extension)
|
2023-07-26 00:42:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
_, duplicate := ext_found[extension]
|
|
|
|
if duplicate == true {
|
2023-08-31 19:50:32 -06:00
|
|
|
return fmt.Errorf("Duplicate extension %+v found in extension list", extension)
|
2023-07-26 00:42:12 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
ext_found[extension] = true
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
ctx.Nodes[node_type] = NodeInfo{
|
2023-07-26 00:42:12 -06:00
|
|
|
Extensions: extensions,
|
2023-07-26 00:18:11 -06:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
func (ctx *Context) RegisterPolicy(reflect_type reflect.Type, policy_type PolicyType) error {
|
|
|
|
_, exists := ctx.Policies[policy_type]
|
2023-07-29 00:28:44 -06:00
|
|
|
if exists == true {
|
2023-08-31 19:50:32 -06:00
|
|
|
return fmt.Errorf("Cannot register policy of type %+v, type already exists in context", policy_type)
|
2023-07-29 00:28:44 -06:00
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
ctx.Policies[policy_type] = reflect_type
|
|
|
|
ctx.PolicyTypes[reflect_type] = policy_type
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ctx *Context)RegisterSignal(reflect_type reflect.Type, signal_type SignalType) error {
|
|
|
|
_, exists := ctx.Signals[signal_type]
|
|
|
|
if exists == true {
|
|
|
|
return fmt.Errorf("Cannot register signal of type %+v, type already exists in context", signal_type)
|
2023-07-29 00:28:44 -06:00
|
|
|
}
|
2023-08-31 19:50:32 -06:00
|
|
|
|
|
|
|
ctx.Signals[signal_type] = reflect_type
|
|
|
|
ctx.SignalTypes[reflect_type] = signal_type
|
2023-07-29 00:28:44 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-10 22:31:43 -06:00
|
|
|
// Add a node to a context, returns an error if the def is invalid or already exists in the context
|
2023-08-31 19:50:32 -06:00
|
|
|
func (ctx *Context)RegisterExtension(reflect_type reflect.Type, ext_type ExtType, data interface{}) error {
|
|
|
|
_, exists := ctx.Extensions[ext_type]
|
2023-07-09 14:30:30 -06:00
|
|
|
if exists == true {
|
2023-08-31 19:50:32 -06:00
|
|
|
return fmt.Errorf("Cannot register extension of type %+v, type already exists in context", ext_type)
|
2023-07-09 14:30:30 -06:00
|
|
|
}
|
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
ctx.Log.Logf("serialize", "Registered ExtType: %+v - %+v", reflect_type, ext_type)
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
ctx.Extensions[ext_type] = ExtensionInfo{
|
|
|
|
Type: reflect_type,
|
2023-07-26 00:18:11 -06:00
|
|
|
Data: data,
|
2023-07-10 21:15:01 -06:00
|
|
|
}
|
2023-08-31 19:50:32 -06:00
|
|
|
ctx.ExtensionTypes[reflect_type] = ext_type
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-02 17:30:52 -06:00
|
|
|
func (ctx *Context)RegisterKind(kind reflect.Kind, ctx_type SerializedType, serialize TypeSerialize, deserialize TypeDeserialize) error {
|
|
|
|
_, exists := ctx.Kinds[kind]
|
|
|
|
if exists == true {
|
|
|
|
return fmt.Errorf("Cannot register kind %+v, kind already exists in context", kind)
|
|
|
|
}
|
|
|
|
_, exists = ctx.KindTypes[ctx_type]
|
|
|
|
if exists == true {
|
|
|
|
return fmt.Errorf("0x%x is already registered, cannot use for %+v", ctx_type, kind)
|
|
|
|
}
|
|
|
|
if deserialize == nil {
|
|
|
|
return fmt.Errorf("Cannot register field without deserialize function")
|
|
|
|
}
|
|
|
|
if serialize == nil {
|
|
|
|
return fmt.Errorf("Cannot register field without serialize function")
|
|
|
|
}
|
|
|
|
|
2023-09-06 18:29:35 -06:00
|
|
|
info := KindInfo{
|
|
|
|
kind,
|
2023-09-02 17:30:52 -06:00
|
|
|
ctx_type,
|
|
|
|
serialize,
|
|
|
|
deserialize,
|
|
|
|
}
|
2023-09-06 18:29:35 -06:00
|
|
|
ctx.KindTypes[ctx_type] = &info
|
|
|
|
ctx.Kinds[kind] = &info
|
2023-09-02 17:30:52 -06:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
func (ctx *Context)RegisterType(reflect_type reflect.Type, ctx_type SerializedType, serialize TypeSerialize, deserialize TypeDeserialize) error {
|
|
|
|
_, exists := ctx.Types[ctx_type]
|
|
|
|
if exists == true {
|
|
|
|
return fmt.Errorf("Cannot register field of type %+v, type already exists in context", ctx_type)
|
|
|
|
}
|
|
|
|
_, exists = ctx.TypeReflects[reflect_type]
|
|
|
|
if exists == true {
|
|
|
|
return fmt.Errorf("Cannot register field with type %+v, type already registered in context", reflect_type)
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
if serialize == nil || deserialize == nil {
|
|
|
|
return fmt.Errorf("Cannot register field without serialize/deserialize functions")
|
|
|
|
}
|
|
|
|
|
2023-09-06 18:29:35 -06:00
|
|
|
type_info := TypeInfo{
|
|
|
|
Reflect: reflect_type,
|
|
|
|
Type: ctx_type,
|
2023-08-31 19:50:32 -06:00
|
|
|
Serialize: serialize,
|
|
|
|
Deserialize: deserialize,
|
|
|
|
}
|
2023-09-06 18:29:35 -06:00
|
|
|
ctx.Types[ctx_type] = &type_info
|
|
|
|
ctx.TypeReflects[reflect_type] = &type_info
|
2023-08-31 19:50:32 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
ctx.Log.Logf("serialize", "Registered Type: %+v - %+v", reflect_type, ctx_type)
|
|
|
|
|
2023-07-09 14:30:30 -06:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-28 12:46:06 -06:00
|
|
|
func (ctx *Context) AddNode(id NodeID, node *Node) {
|
2023-08-31 19:50:32 -06:00
|
|
|
ctx.nodeMapLock.Lock()
|
|
|
|
ctx.nodeMap[id] = node
|
|
|
|
ctx.nodeMapLock.Unlock()
|
2023-07-28 12:46:06 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (ctx *Context) Node(id NodeID) (*Node, bool) {
|
2023-08-31 19:50:32 -06:00
|
|
|
ctx.nodeMapLock.RLock()
|
|
|
|
node, exists := ctx.nodeMap[id]
|
|
|
|
ctx.nodeMapLock.RUnlock()
|
2023-07-28 12:46:06 -06:00
|
|
|
return node, exists
|
|
|
|
}
|
|
|
|
|
2023-07-28 00:04:18 -06:00
|
|
|
// Get a node from the context, or load from the database if not loaded
|
2023-08-31 19:50:32 -06:00
|
|
|
func (ctx *Context) getNode(id NodeID) (*Node, error) {
|
2023-07-28 12:46:06 -06:00
|
|
|
target, exists := ctx.Node(id)
|
|
|
|
|
2023-07-27 15:49:21 -06:00
|
|
|
if exists == false {
|
2023-07-27 16:48:39 -06:00
|
|
|
var err error
|
|
|
|
target, err = LoadNode(ctx, id)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-27 15:49:21 -06:00
|
|
|
}
|
2023-07-27 16:48:39 -06:00
|
|
|
return target, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Route a Signal to dest. Currently only local context routing is supported
|
2023-08-08 14:00:17 -06:00
|
|
|
func (ctx *Context) Send(messages Messages) error {
|
2023-08-07 20:26:02 -06:00
|
|
|
for _, msg := range(messages) {
|
2023-08-15 18:23:06 -06:00
|
|
|
if msg.Dest == ZeroID {
|
|
|
|
panic("Can't send to null ID")
|
|
|
|
}
|
2023-08-31 19:50:32 -06:00
|
|
|
target, err := ctx.getNode(msg.Dest)
|
2023-08-07 20:26:02 -06:00
|
|
|
if err == nil {
|
|
|
|
select {
|
2023-08-08 14:00:17 -06:00
|
|
|
case target.MsgChan <- msg:
|
|
|
|
ctx.Log.Logf("signal", "Sent %s -> %+v", target.ID, msg)
|
2023-08-07 20:26:02 -06:00
|
|
|
default:
|
|
|
|
buf := make([]byte, 4096)
|
|
|
|
n := runtime.Stack(buf, false)
|
|
|
|
stack_str := string(buf[:n])
|
2023-08-08 14:00:17 -06:00
|
|
|
return fmt.Errorf("SIGNAL_OVERFLOW: %s - %s", msg.Dest, stack_str)
|
2023-08-07 20:26:02 -06:00
|
|
|
}
|
|
|
|
} else if errors.Is(err, NodeNotFoundError) {
|
|
|
|
// TODO: Handle finding nodes in other contexts
|
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
return err
|
2023-07-27 16:48:39 -06:00
|
|
|
}
|
2023-07-27 15:49:21 -06:00
|
|
|
}
|
2023-08-07 20:26:02 -06:00
|
|
|
return nil
|
2023-07-27 15:49:21 -06:00
|
|
|
}
|
|
|
|
|
2023-09-02 17:30:52 -06:00
|
|
|
// Create a new Context with the base library content added
|
|
|
|
func NewContext(db * badger.DB, log Logger) (*Context, error) {
|
|
|
|
ctx := &Context{
|
|
|
|
DB: db,
|
|
|
|
Log: log,
|
|
|
|
Policies: map[PolicyType]reflect.Type{},
|
|
|
|
PolicyTypes: map[reflect.Type]PolicyType{},
|
|
|
|
Extensions: map[ExtType]ExtensionInfo{},
|
|
|
|
ExtensionTypes: map[reflect.Type]ExtType{},
|
|
|
|
Signals: map[SignalType]reflect.Type{},
|
|
|
|
SignalTypes: map[reflect.Type]SignalType{},
|
|
|
|
Nodes: map[NodeType]NodeInfo{},
|
|
|
|
nodeMap: map[NodeID]*Node{},
|
2023-09-06 18:29:35 -06:00
|
|
|
Types: map[SerializedType]*TypeInfo{},
|
|
|
|
TypeReflects: map[reflect.Type]*TypeInfo{},
|
|
|
|
Kinds: map[reflect.Kind]*KindInfo{},
|
|
|
|
KindTypes: map[SerializedType]*KindInfo{},
|
2023-09-02 17:30:52 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
var err error
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Pointer, PointerType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value) (SerializedValue, error) {
|
|
|
|
var data []byte
|
|
|
|
var elem_value *reflect.Value = nil
|
|
|
|
if value == nil {
|
|
|
|
data = nil
|
|
|
|
} else if value.IsZero() {
|
|
|
|
data = []byte{0x01}
|
|
|
|
} else {
|
|
|
|
data = []byte{0x00}
|
|
|
|
ev := value.Elem()
|
|
|
|
elem_value = &ev
|
|
|
|
}
|
2023-09-05 00:46:49 -06:00
|
|
|
elem, err := SerializeValue(ctx, reflect_type.Elem(), elem_value)
|
2023-09-05 00:08:09 -06:00
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
|
|
|
if elem.Data != nil {
|
|
|
|
data = append(data, elem.Data...)
|
|
|
|
}
|
|
|
|
return SerializedValue{
|
|
|
|
append([]SerializedType{ctx_type}, elem.TypeStack...),
|
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue) (reflect.Type, *reflect.Value, SerializedValue, error) {
|
|
|
|
if value.Data == nil {
|
2023-09-05 00:46:49 -06:00
|
|
|
var elem_type reflect.Type
|
|
|
|
var err error
|
|
|
|
elem_type, _, value, err = DeserializeValue(ctx, value)
|
2023-09-02 18:49:37 -06:00
|
|
|
if err != nil {
|
2023-09-03 17:50:12 -06:00
|
|
|
return nil, nil, SerializedValue{}, err
|
2023-09-02 18:49:37 -06:00
|
|
|
}
|
2023-09-03 17:50:12 -06:00
|
|
|
return reflect.PointerTo(elem_type), nil, value, nil
|
|
|
|
} else if len(value.Data) < 1 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("Not enough data to deserialize pointer")
|
2023-09-02 18:49:37 -06:00
|
|
|
} else {
|
2023-09-03 17:50:12 -06:00
|
|
|
pointer_flags := value.Data[0]
|
|
|
|
value.Data = value.Data[1:]
|
2023-09-02 18:49:37 -06:00
|
|
|
if pointer_flags == 0x00 {
|
2023-09-06 18:29:35 -06:00
|
|
|
elem_type, elem_value, remaining_data, err := DeserializeValue(ctx, value)
|
2023-09-02 18:49:37 -06:00
|
|
|
if err != nil {
|
2023-09-03 17:50:12 -06:00
|
|
|
return nil, nil, SerializedValue{}, err
|
2023-09-02 18:49:37 -06:00
|
|
|
}
|
2023-09-06 18:29:35 -06:00
|
|
|
pointer_type := reflect.PointerTo(elem_type)
|
|
|
|
pointer_value := reflect.New(pointer_type).Elem()
|
|
|
|
pointer_value.Set(elem_value.Addr())
|
|
|
|
return pointer_type, &pointer_value, remaining_data, nil
|
2023-09-02 18:49:37 -06:00
|
|
|
} else if pointer_flags == 0x01 {
|
2023-09-05 00:08:09 -06:00
|
|
|
elem_type, _, remaining_data, err := DeserializeValue(ctx, value)
|
2023-09-02 18:49:37 -06:00
|
|
|
if err != nil {
|
2023-09-03 17:50:12 -06:00
|
|
|
return nil, nil, SerializedValue{}, err
|
2023-09-02 18:49:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
pointer_type := reflect.PointerTo(elem_type)
|
|
|
|
pointer_value := reflect.New(pointer_type).Elem()
|
2023-09-03 17:50:12 -06:00
|
|
|
return pointer_type, &pointer_value, remaining_data, nil
|
2023-09-02 18:49:37 -06:00
|
|
|
} else {
|
2023-09-03 17:50:12 -06:00
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("unknown pointer flags: %d", pointer_flags)
|
2023-09-02 18:49:37 -06:00
|
|
|
}
|
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Struct, StructType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-11 21:47:53 -06:00
|
|
|
type_stack := []SerializedType{ctx_type}
|
|
|
|
var data []byte
|
2023-09-06 18:29:35 -06:00
|
|
|
if value != nil {
|
2023-09-11 21:47:53 -06:00
|
|
|
data = make([]byte, 8)
|
2023-09-06 18:29:35 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
num_fields := uint64(0)
|
2023-09-02 17:30:52 -06:00
|
|
|
for _, field := range(reflect.VisibleFields(reflect_type)) {
|
|
|
|
gv_tag, tagged_gv := field.Tag.Lookup("gv")
|
|
|
|
if tagged_gv == false {
|
|
|
|
continue
|
|
|
|
} else if gv_tag == "" {
|
|
|
|
continue
|
2023-09-03 17:50:12 -06:00
|
|
|
} else {
|
2023-09-06 18:29:35 -06:00
|
|
|
num_fields += 1
|
2023-09-05 00:08:09 -06:00
|
|
|
field_hash := Hash(FieldNameBase, gv_tag)
|
2023-09-06 18:29:35 -06:00
|
|
|
field_hash_bytes := make([]byte, 8)
|
|
|
|
binary.BigEndian.PutUint64(field_hash_bytes, uint64(field_hash))
|
2023-09-11 21:47:53 -06:00
|
|
|
if value != nil {
|
|
|
|
field_value := value.FieldByIndex(field.Index)
|
|
|
|
field_ser, err := SerializeValue(ctx, field.Type, &field_value)
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
2023-09-11 21:47:53 -06:00
|
|
|
|
|
|
|
field_bytes, err := field_ser.MarshalBinary()
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
2023-09-11 21:47:53 -06:00
|
|
|
data = append(data, field_hash_bytes...)
|
|
|
|
data = append(data, field_bytes...)
|
2023-09-02 17:30:52 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-09-11 21:47:53 -06:00
|
|
|
|
2023-09-06 18:29:35 -06:00
|
|
|
if value != nil {
|
2023-09-11 21:47:53 -06:00
|
|
|
binary.BigEndian.PutUint64(data[0:8], num_fields)
|
2023-09-06 18:29:35 -06:00
|
|
|
}
|
2023-09-03 17:50:12 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
return SerializedValue{
|
|
|
|
type_stack,
|
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
2023-09-06 18:29:35 -06:00
|
|
|
if value.Data == nil {
|
|
|
|
return reflect.TypeOf(map[uint64]reflect.Value{}), nil, value, nil
|
|
|
|
} else {
|
|
|
|
var num_fields_data []byte
|
|
|
|
var err error
|
|
|
|
num_fields_data, value, err = value.PopData(8)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
num_fields := int(binary.BigEndian.Uint64(num_fields_data))
|
|
|
|
|
|
|
|
map_type := reflect.TypeOf(map[uint64]reflect.Value{})
|
|
|
|
map_ptr := reflect.New(map_type)
|
|
|
|
map_ptr.Elem().Set(reflect.MakeMap(map_type))
|
|
|
|
map_value := map_ptr.Elem()
|
|
|
|
if num_fields == 0 {
|
|
|
|
return map_type, &map_value, value, nil
|
|
|
|
} else {
|
2023-09-11 21:47:53 -06:00
|
|
|
tmp_data := value.Data
|
2023-09-06 18:29:35 -06:00
|
|
|
for i := 0; i < num_fields; i += 1 {
|
2023-09-11 21:47:53 -06:00
|
|
|
if len(tmp_data) < 8 {
|
|
|
|
return nil, nil, value, fmt.Errorf("Not enough data to deserialize struct field")
|
|
|
|
}
|
|
|
|
field_hash := binary.BigEndian.Uint64(tmp_data[0:8])
|
|
|
|
tmp_data = tmp_data[8:]
|
|
|
|
var field_value SerializedValue
|
|
|
|
field_value, tmp_data, err = ParseSerializedValue(tmp_data)
|
2023-09-06 18:29:35 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
field_hash_value := reflect.ValueOf(field_hash)
|
|
|
|
|
|
|
|
var elem_value *reflect.Value
|
2023-09-11 21:47:53 -06:00
|
|
|
_, elem_value, _, err = DeserializeValue(ctx, field_value)
|
2023-09-06 18:29:35 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
map_value.SetMapIndex(field_hash_value, reflect.ValueOf(*elem_value))
|
|
|
|
}
|
2023-09-11 21:47:53 -06:00
|
|
|
value.Data = tmp_data
|
|
|
|
return map_type, &map_value, value, nil
|
2023-09-06 18:29:35 -06:00
|
|
|
}
|
|
|
|
}
|
2023-09-03 17:50:12 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Bool, BoolType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-02 17:30:52 -06:00
|
|
|
var data []byte = nil
|
|
|
|
if value != nil {
|
2023-09-03 17:50:12 -06:00
|
|
|
b := value.Bool()
|
|
|
|
if b == true {
|
|
|
|
data = []byte{0x01}
|
|
|
|
} else {
|
|
|
|
data = []byte{0x00}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{ctx_type},
|
2023-09-03 17:50:12 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
if value.Data == nil {
|
|
|
|
return reflect.TypeOf(true), nil, value, nil
|
|
|
|
} else if len(value.Data) == 0 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("not enough data to deserialize bool")
|
|
|
|
} else {
|
|
|
|
b := value.Data[0]
|
|
|
|
value.Data = value.Data[1:]
|
|
|
|
var val reflect.Value
|
|
|
|
switch b {
|
|
|
|
case 0x00:
|
|
|
|
val = reflect.ValueOf(false)
|
|
|
|
case 0x01:
|
|
|
|
val = reflect.ValueOf(true)
|
|
|
|
default:
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("unknown boolean 0x%x", b)
|
|
|
|
}
|
|
|
|
return reflect.TypeOf(true), &val, value, nil
|
|
|
|
}
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Float64, Float64Type,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-03 17:50:12 -06:00
|
|
|
var data []byte = nil
|
|
|
|
if value != nil {
|
2023-09-02 17:30:52 -06:00
|
|
|
data = make([]byte, 8)
|
2023-09-03 17:50:12 -06:00
|
|
|
val := math.Float64bits(float64(value.Float()))
|
|
|
|
binary.BigEndian.PutUint64(data, val)
|
2023-08-31 19:50:32 -06:00
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{ctx_type},
|
2023-09-02 17:30:52 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
if value.Data == nil {
|
|
|
|
return reflect.TypeOf(float64(0)), nil, value, nil
|
|
|
|
} else {
|
|
|
|
if len(value.Data) < 8 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("Not enough data to deserialize float32")
|
|
|
|
}
|
|
|
|
val_int := binary.BigEndian.Uint64(value.Data[0:8])
|
|
|
|
value.Data = value.Data[8:]
|
|
|
|
val := math.Float64frombits(val_int)
|
|
|
|
|
|
|
|
float_val := reflect.ValueOf(val)
|
|
|
|
|
|
|
|
return float_val.Type(), &float_val, value, nil
|
2023-09-02 17:30:52 -06:00
|
|
|
}
|
2023-09-03 17:50:12 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Float32, Float32Type,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-03 17:50:12 -06:00
|
|
|
var data []byte = nil
|
|
|
|
if value != nil {
|
|
|
|
data = make([]byte, 4)
|
|
|
|
val := math.Float32bits(float32(value.Float()))
|
|
|
|
binary.BigEndian.PutUint32(data, val)
|
|
|
|
}
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{ctx_type},
|
2023-09-03 17:50:12 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
if value.Data == nil {
|
|
|
|
return reflect.TypeOf(float32(0)), nil, value, nil
|
|
|
|
} else {
|
|
|
|
if len(value.Data) < 4 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("Not enough data to deserialize float32")
|
|
|
|
}
|
|
|
|
val_int := binary.BigEndian.Uint32(value.Data[0:4])
|
|
|
|
value.Data = value.Data[4:]
|
|
|
|
val := math.Float32frombits(val_int)
|
|
|
|
|
|
|
|
float_value := reflect.ValueOf(val)
|
|
|
|
|
|
|
|
return float_value.Type(), &float_value, value, nil
|
2023-09-02 17:30:52 -06:00
|
|
|
}
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.String, StringType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-02 17:30:52 -06:00
|
|
|
if value == nil {
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{ctx_type},
|
2023-09-02 17:30:52 -06:00
|
|
|
nil,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
data := make([]byte, 8)
|
|
|
|
str := value.String()
|
|
|
|
binary.BigEndian.PutUint64(data, uint64(len(str)))
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{SerializedType(ctx_type)},
|
2023-09-02 17:30:52 -06:00
|
|
|
append(data, []byte(str)...),
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
if value.Data == nil {
|
|
|
|
return reflect.TypeOf(""), nil, value, nil
|
|
|
|
} else if len(value.Data) < 8 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("Not enough data to deserialize string")
|
|
|
|
} else {
|
|
|
|
str_len := binary.BigEndian.Uint64(value.Data[0:8])
|
|
|
|
value.Data = value.Data[8:]
|
|
|
|
if len(value.Data) < int(str_len) {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("Not enough data to deserialize string of length %d(%d)", str_len, len(value.Data))
|
|
|
|
}
|
|
|
|
string_bytes := value.Data[:str_len]
|
|
|
|
value.Data = value.Data[str_len:]
|
|
|
|
str_value := reflect.ValueOf(string(string_bytes))
|
|
|
|
return reflect.TypeOf(""), &str_value, value, nil
|
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Array, ArrayType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-02 17:30:52 -06:00
|
|
|
var data []byte
|
2023-09-12 16:56:01 -06:00
|
|
|
type_stack := []SerializedType{ctx_type, SerializedType(reflect_type.Len())}
|
2023-09-02 17:30:52 -06:00
|
|
|
if value == nil {
|
|
|
|
data = nil
|
2023-09-11 21:54:00 -06:00
|
|
|
} else if value.IsZero() {
|
|
|
|
return SerializedValue{}, fmt.Errorf("don't know what zero array means...")
|
2023-09-02 17:30:52 -06:00
|
|
|
} else {
|
2023-09-12 16:56:01 -06:00
|
|
|
data := []byte{}
|
2023-09-11 21:54:00 -06:00
|
|
|
var element SerializedValue
|
|
|
|
var err error
|
2023-09-02 17:30:52 -06:00
|
|
|
for i := 0; i < value.Len(); i += 1 {
|
|
|
|
val := value.Index(i)
|
2023-09-11 21:54:00 -06:00
|
|
|
element, err = SerializeValue(ctx, reflect_type.Elem(), &val)
|
2023-09-02 17:30:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
|
|
|
data = append(data, element.Data...)
|
|
|
|
}
|
2023-09-11 21:54:00 -06:00
|
|
|
return SerializedValue{
|
|
|
|
append(type_stack, element.TypeStack...),
|
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-02 17:30:52 -06:00
|
|
|
}
|
2023-09-11 21:54:00 -06:00
|
|
|
element, err := SerializeValue(ctx, reflect_type.Elem(), nil)
|
2023-09-02 17:30:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
|
|
|
return SerializedValue{
|
2023-09-11 21:54:00 -06:00
|
|
|
append(type_stack, element.TypeStack...),
|
2023-09-02 17:30:52 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
2023-09-12 16:56:01 -06:00
|
|
|
if len(value.TypeStack) < 1 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("no array size in type stack")
|
|
|
|
}
|
|
|
|
array_size := int(value.TypeStack[0])
|
|
|
|
value.TypeStack = value.TypeStack[1:]
|
2023-09-11 21:54:00 -06:00
|
|
|
if value.Data == nil {
|
|
|
|
elem_type, _, _, err := DeserializeValue(ctx, value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, SerializedValue{}, err
|
|
|
|
}
|
2023-09-12 16:56:01 -06:00
|
|
|
return reflect.ArrayOf(array_size, elem_type), nil, value, nil
|
2023-09-11 21:54:00 -06:00
|
|
|
} else {
|
2023-09-12 16:56:01 -06:00
|
|
|
if array_size == 0x00 {
|
2023-09-11 21:54:00 -06:00
|
|
|
elem_type, _, remaining, err := DeserializeValue(ctx, SerializedValue{
|
|
|
|
value.TypeStack,
|
|
|
|
nil,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, SerializedValue{}, err
|
|
|
|
}
|
2023-09-12 16:56:01 -06:00
|
|
|
array_type := reflect.ArrayOf(array_size, elem_type)
|
2023-09-11 21:54:00 -06:00
|
|
|
array_value := reflect.New(array_type).Elem()
|
|
|
|
return array_type, &array_value, SerializedValue{
|
|
|
|
remaining.TypeStack,
|
|
|
|
value.Data,
|
|
|
|
}, nil
|
|
|
|
} else {
|
|
|
|
var reflect_value *reflect.Value = nil
|
|
|
|
var reflect_type reflect.Type = nil
|
|
|
|
saved_type_stack := value.TypeStack
|
2023-09-12 16:56:01 -06:00
|
|
|
for i := 0; i < array_size; i += 1 {
|
2023-09-11 21:54:00 -06:00
|
|
|
var element_type reflect.Type
|
|
|
|
var element_value *reflect.Value
|
|
|
|
element_type, element_value, value, err = DeserializeValue(ctx, value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
if reflect_value == nil {
|
2023-09-12 16:56:01 -06:00
|
|
|
reflect_type = reflect.ArrayOf(array_size, element_type)
|
2023-09-11 21:54:00 -06:00
|
|
|
real_value := reflect.New(reflect_type).Elem()
|
|
|
|
reflect_value = &real_value
|
|
|
|
}
|
2023-09-12 16:56:01 -06:00
|
|
|
if i != (array_size - 1) {
|
2023-09-11 21:54:00 -06:00
|
|
|
value.TypeStack = saved_type_stack
|
|
|
|
}
|
|
|
|
slice_index_ptr := reflect_value.Index(i)
|
|
|
|
slice_index_ptr.Set(*element_value)
|
|
|
|
}
|
|
|
|
return reflect_type, reflect_value, value, nil
|
|
|
|
}
|
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Interface, InterfaceType, SerializeInterface, DeserializeInterface[interface{}]())
|
2023-09-02 17:30:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Map, MapType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-09-05 00:46:49 -06:00
|
|
|
var data []byte
|
|
|
|
type_stack := []SerializedType{ctx_type}
|
|
|
|
if value == nil {
|
|
|
|
data = nil
|
|
|
|
} else if value.IsZero() {
|
|
|
|
data = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
|
|
|
} else if value.Len() == 0 {
|
|
|
|
data = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
|
|
|
} else {
|
|
|
|
data = make([]byte, 8)
|
|
|
|
map_size := 0
|
|
|
|
var key_types, elem_types []SerializedType
|
|
|
|
|
|
|
|
map_iter := value.MapRange()
|
|
|
|
for map_iter.Next() {
|
|
|
|
map_size += 1
|
|
|
|
key_reflect := map_iter.Key()
|
|
|
|
elem_reflect := map_iter.Value()
|
|
|
|
|
|
|
|
key_value, err := SerializeValue(ctx, key_reflect.Type(), &key_reflect)
|
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
|
|
|
elem_value, err := SerializeValue(ctx, elem_reflect.Type(), &elem_reflect)
|
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
data = append(data, key_value.Data...)
|
|
|
|
data = append(data, elem_value.Data...)
|
|
|
|
|
|
|
|
if key_types == nil {
|
|
|
|
key_types = key_value.TypeStack
|
|
|
|
elem_types = elem_value.TypeStack
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
binary.BigEndian.PutUint64(data[0:8], uint64(map_size))
|
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
ctx.Log.Logf("serialize", "MAP_TYPES: %+v - %+v", key_types, elem_types)
|
|
|
|
|
2023-09-05 00:46:49 -06:00
|
|
|
type_stack = append(type_stack, key_types...)
|
|
|
|
type_stack = append(type_stack, elem_types...)
|
|
|
|
return SerializedValue{
|
|
|
|
type_stack,
|
|
|
|
data,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
key_value, err := SerializeValue(ctx, reflect_type.Key(), nil)
|
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, nil
|
|
|
|
}
|
|
|
|
elem_value, err := SerializeValue(ctx, reflect_type.Elem(), nil)
|
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type_stack = append(type_stack, key_value.TypeStack...)
|
|
|
|
type_stack = append(type_stack, elem_value.TypeStack...)
|
|
|
|
|
|
|
|
return SerializedValue{
|
|
|
|
type_stack,
|
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
2023-09-05 00:46:49 -06:00
|
|
|
if value.Data == nil {
|
|
|
|
var key_type, elem_type reflect.Type
|
|
|
|
var err error
|
|
|
|
key_type, _, value, err = DeserializeValue(ctx, value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
elem_type, _, value, err = DeserializeValue(ctx, value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
reflect_type := reflect.MapOf(key_type, elem_type)
|
|
|
|
return reflect_type, nil, value, nil
|
|
|
|
} else if len(value.Data) < 8 {
|
2023-09-05 01:02:41 -06:00
|
|
|
return nil, nil, value, fmt.Errorf("Not enough data to deserialize map")
|
2023-09-05 00:46:49 -06:00
|
|
|
} else {
|
2023-09-05 01:02:41 -06:00
|
|
|
var map_size_bytes []byte
|
|
|
|
var err error
|
|
|
|
map_size_bytes, value, err = value.PopData(8)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
2023-09-05 00:46:49 -06:00
|
|
|
|
2023-09-05 01:02:41 -06:00
|
|
|
map_size := binary.BigEndian.Uint64(map_size_bytes)
|
2023-09-12 19:00:48 -06:00
|
|
|
ctx.Log.Logf("serialize", "Deserializing %d elements in map", map_size)
|
2023-09-05 01:02:41 -06:00
|
|
|
|
|
|
|
if map_size == 0xFFFFFFFFFFFFFFFF {
|
|
|
|
var key_type, elem_type reflect.Type
|
|
|
|
var err error
|
|
|
|
tmp_value := SerializedValue{
|
|
|
|
value.TypeStack,
|
|
|
|
nil,
|
|
|
|
}
|
|
|
|
key_type, _, tmp_value, err = DeserializeValue(ctx, tmp_value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
elem_type, _, tmp_value, err = DeserializeValue(ctx, tmp_value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
new_value := SerializedValue{
|
|
|
|
tmp_value.TypeStack,
|
|
|
|
value.Data,
|
|
|
|
}
|
|
|
|
reflect_type := reflect.MapOf(key_type, elem_type)
|
|
|
|
reflect_value := reflect.New(reflect_type).Elem()
|
|
|
|
return reflect_type, &reflect_value, new_value, nil
|
|
|
|
} else if map_size == 0x00 {
|
|
|
|
var key_type, elem_type reflect.Type
|
|
|
|
var err error
|
|
|
|
tmp_value := SerializedValue{
|
|
|
|
value.TypeStack,
|
|
|
|
nil,
|
|
|
|
}
|
|
|
|
key_type, _, tmp_value, err = DeserializeValue(ctx, tmp_value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
elem_type, _, tmp_value, err = DeserializeValue(ctx, tmp_value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
new_value := SerializedValue{
|
|
|
|
tmp_value.TypeStack,
|
|
|
|
value.Data,
|
|
|
|
}
|
|
|
|
reflect_type := reflect.MapOf(key_type, elem_type)
|
|
|
|
reflect_value := reflect.MakeMap(reflect_type)
|
|
|
|
return reflect_type, &reflect_value, new_value, nil
|
|
|
|
} else {
|
2023-09-05 10:48:04 -06:00
|
|
|
tmp_value := value
|
|
|
|
var map_value reflect.Value
|
|
|
|
var map_type reflect.Type = nil
|
|
|
|
for i := 0; i < int(map_size); i += 1 {
|
|
|
|
tmp_value.TypeStack = value.TypeStack
|
|
|
|
var key_type, elem_type reflect.Type
|
|
|
|
var key_value, elem_value *reflect.Value
|
|
|
|
var err error
|
|
|
|
key_type, key_value, tmp_value, err = DeserializeValue(ctx, tmp_value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
elem_type, elem_value, tmp_value, err = DeserializeValue(ctx, tmp_value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
if map_type == nil {
|
|
|
|
map_type = reflect.MapOf(key_type, elem_type)
|
|
|
|
map_value = reflect.MakeMap(map_type)
|
|
|
|
}
|
|
|
|
map_value.SetMapIndex(*key_value, *elem_value)
|
|
|
|
}
|
|
|
|
return map_type, &map_value, tmp_value, nil
|
2023-09-05 01:02:41 -06:00
|
|
|
}
|
2023-09-05 00:46:49 -06:00
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Int8, Int8Type, SerializeIntN(1), DeserializeIntN[int8](1))
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Int16, Int16Type, SerializeIntN(2), DeserializeIntN[int16](2))
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Int32, Int32Type, SerializeIntN(4), DeserializeIntN[int32](4))
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Int64, Int64Type, SerializeIntN(8), DeserializeIntN[int64](8))
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Int, IntType, SerializeIntN(8), DeserializeIntN[int](8))
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Uint8, UInt8Type, SerializeUintN(1), DeserializeUintN[uint8](1))
|
2023-09-02 17:30:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Uint16, UInt16Type, SerializeUintN(2), DeserializeUintN[uint16](2))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-03 17:50:12 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Uint32, UInt32Type, SerializeUintN(4), DeserializeUintN[uint32](4))
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Uint64, UInt64Type, SerializeUintN(8), DeserializeUintN[uint64](8))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-03 17:50:12 -06:00
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Uint, UIntType, SerializeUintN(8), DeserializeUintN[uint](8))
|
2023-09-02 17:30:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-05 00:08:09 -06:00
|
|
|
err = ctx.RegisterKind(reflect.Slice, SliceType,
|
|
|
|
func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){
|
2023-08-31 22:31:29 -06:00
|
|
|
var data []byte
|
2023-09-05 00:08:09 -06:00
|
|
|
type_stack := []SerializedType{ctx_type}
|
2023-08-31 22:31:29 -06:00
|
|
|
if value == nil {
|
|
|
|
data = nil
|
|
|
|
} else if value.IsZero() {
|
|
|
|
data = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
|
|
|
} else if value.Len() == 0 {
|
|
|
|
data = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
|
|
|
} else {
|
|
|
|
data := make([]byte, 8)
|
|
|
|
binary.BigEndian.PutUint64(data, uint64(value.Len()))
|
2023-09-05 00:08:09 -06:00
|
|
|
var element SerializedValue
|
|
|
|
var err error
|
2023-08-31 22:31:29 -06:00
|
|
|
for i := 0; i < value.Len(); i += 1 {
|
|
|
|
val := value.Index(i)
|
2023-09-05 00:46:49 -06:00
|
|
|
element, err = SerializeValue(ctx, reflect_type.Elem(), &val)
|
2023-08-31 22:31:29 -06:00
|
|
|
if err != nil {
|
|
|
|
return SerializedValue{}, err
|
|
|
|
}
|
2023-09-02 17:30:52 -06:00
|
|
|
data = append(data, element.Data...)
|
2023-08-31 22:31:29 -06:00
|
|
|
}
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
append(type_stack, element.TypeStack...),
|
2023-08-31 22:31:29 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
|
|
|
}
|
2023-09-05 00:46:49 -06:00
|
|
|
element, err := SerializeValue(ctx, reflect_type.Elem(), nil)
|
2023-08-31 19:50:32 -06:00
|
|
|
if err != nil {
|
2023-08-31 22:31:29 -06:00
|
|
|
return SerializedValue{}, err
|
2023-08-31 19:50:32 -06:00
|
|
|
}
|
2023-08-31 22:31:29 -06:00
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
append(type_stack, element.TypeStack...),
|
2023-08-31 22:31:29 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
if value.Data == nil {
|
2023-09-05 00:08:09 -06:00
|
|
|
elem_type, _, _, err := DeserializeValue(ctx, value)
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, SerializedValue{}, err
|
|
|
|
}
|
|
|
|
return reflect.SliceOf(elem_type), nil, value, nil
|
|
|
|
} else if len(value.Data) < 8 {
|
|
|
|
return nil, nil, SerializedValue{}, fmt.Errorf("Not enough data to deserialize slice")
|
|
|
|
} else {
|
|
|
|
slice_length := binary.BigEndian.Uint64(value.Data[0:8])
|
|
|
|
value.Data = value.Data[8:]
|
|
|
|
if slice_length == 0xFFFFFFFFFFFFFFFF {
|
|
|
|
elem_type, _, remaining, err := DeserializeValue(ctx, SerializedValue{
|
|
|
|
value.TypeStack,
|
|
|
|
nil,
|
2023-09-05 00:08:09 -06:00
|
|
|
})
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, SerializedValue{}, err
|
|
|
|
}
|
|
|
|
reflect_type := reflect.SliceOf(elem_type)
|
|
|
|
reflect_value := reflect.New(reflect_type).Elem()
|
|
|
|
return reflect_type, &reflect_value, SerializedValue{
|
|
|
|
remaining.TypeStack,
|
|
|
|
value.Data,
|
|
|
|
}, nil
|
|
|
|
} else if slice_length == 0x00 {
|
2023-09-05 00:46:49 -06:00
|
|
|
elem_type, _, remaining, err := DeserializeValue(ctx, SerializedValue{
|
|
|
|
value.TypeStack,
|
|
|
|
nil,
|
|
|
|
})
|
2023-09-03 17:50:12 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, nil, SerializedValue{}, err
|
|
|
|
}
|
|
|
|
reflect_value := reflect.MakeSlice(reflect.SliceOf(elem_type), 0, 0)
|
|
|
|
return reflect_value.Type(), &reflect_value, SerializedValue{
|
|
|
|
remaining.TypeStack,
|
|
|
|
value.Data,
|
|
|
|
}, nil
|
|
|
|
} else {
|
2023-09-05 00:08:09 -06:00
|
|
|
var reflect_value *reflect.Value = nil
|
|
|
|
var reflect_type reflect.Type = nil
|
|
|
|
saved_type_stack := value.TypeStack
|
2023-09-03 17:50:12 -06:00
|
|
|
for i := 0; i < int(slice_length); i += 1 {
|
2023-09-05 00:08:09 -06:00
|
|
|
var element_type reflect.Type
|
|
|
|
var element_value *reflect.Value
|
|
|
|
element_type, element_value, value, err = DeserializeValue(ctx, value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, value, err
|
|
|
|
}
|
|
|
|
if reflect_value == nil {
|
|
|
|
reflect_type = reflect.SliceOf(element_type)
|
|
|
|
real_value := reflect.MakeSlice(reflect_type, int(slice_length), int(slice_length))
|
|
|
|
reflect_value = &real_value
|
|
|
|
}
|
|
|
|
if i != (int(slice_length) - 1) {
|
|
|
|
value.TypeStack = saved_type_stack
|
|
|
|
}
|
|
|
|
slice_index_ptr := reflect_value.Index(i)
|
|
|
|
slice_index_ptr.Set(*element_value)
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
2023-09-05 00:08:09 -06:00
|
|
|
return reflect_type, reflect_value, value, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}
|
|
|
|
}
|
2023-09-02 18:49:37 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-11 21:47:53 -06:00
|
|
|
// TODO: move functions for string serialize/deserialize out of RegisterKind
|
|
|
|
/*
|
2023-09-06 18:29:35 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(StringError("")), ErrorType, nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-11 21:47:53 -06:00
|
|
|
*/
|
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(ExtType(0)), ExtTypeSerialized, SerializeUintN(8), DeserializeUintN[ExtType](8))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ctx.RegisterType(reflect.TypeOf(NodeType(0)), NodeTypeSerialized, SerializeUintN(8), DeserializeUintN[NodeType](8))
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(PolicyType(0)), PolicyTypeSerialized, SerializeUintN(8), DeserializeUintN[PolicyType](8))
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 16:56:01 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(RandID()), NodeIDType, SerializeArray, DeserializeArray[NodeID](ctx))
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(uuid.New()), UUIDType, SerializeArray, DeserializeArray[uuid.UUID](ctx))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ctx.RegisterType(reflect.TypeOf(PendingACL{}), PendingACLType, SerializeStruct[PendingACL](ctx), DeserializeStruct[PendingACL](ctx))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ctx.RegisterType(reflect.TypeOf(PendingSignal{}), PendingSignalType, SerializeStruct[PendingSignal](ctx), DeserializeStruct[PendingSignal](ctx))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 16:56:01 -06:00
|
|
|
// TODO: Make registering interfaces cleaner
|
|
|
|
var extension Extension = nil
|
2023-09-12 19:00:48 -06:00
|
|
|
err = ctx.RegisterType(reflect.ValueOf(&extension).Type().Elem(), ExtSerialized, SerializeInterface, DeserializeInterface[Extension]())
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var policy Policy = nil
|
|
|
|
err = ctx.RegisterType(reflect.ValueOf(&policy).Type().Elem(), PolicySerialized, SerializeInterface, DeserializeInterface[Policy]())
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 16:56:01 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(ListenerExt{}), SerializedType(ListenerExtType), SerializeStruct[ListenerExt](ctx), DeserializeStruct[ListenerExt](ctx))
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 16:56:01 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(GroupExt{}), SerializedType(GroupExtType), SerializeStruct[GroupExt](ctx), DeserializeStruct[GroupExt](ctx))
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 16:56:01 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(GQLExt{}), SerializedType(GQLExtType), SerializeStruct[GQLExt](ctx), DeserializeStruct[GQLExt](ctx))
|
2023-09-11 21:47:53 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-02 18:49:37 -06:00
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(QueuedSignal{}), QueuedSignalType, SerializeStruct[QueuedSignal](ctx), DeserializeStruct[QueuedSignal](ctx))
|
2023-09-02 17:30:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-09-12 19:00:48 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(AllNodesPolicy{}), SerializedType(AllNodesPolicyType), SerializeStruct[AllNodesPolicy](ctx), DeserializeStruct[AllNodesPolicy](ctx))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ctx.RegisterType(reflect.TypeOf(Node{}), NodeStructType, SerializeStruct[Node](ctx), DeserializeStruct[Node](ctx))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-09-12 16:56:01 -06:00
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(Up), SignalDirectionType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, t reflect.Type, value *reflect.Value) (SerializedValue, error) {
|
2023-09-02 17:30:52 -06:00
|
|
|
var data []byte = nil
|
|
|
|
if value != nil {
|
|
|
|
val := value.Interface().(SignalDirection)
|
|
|
|
data = []byte{byte(val)}
|
2023-08-31 22:31:29 -06:00
|
|
|
}
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{ctx_type},
|
2023-08-31 22:31:29 -06:00
|
|
|
data,
|
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
return reflect.TypeOf(Up), nil, SerializedValue{}, fmt.Errorf("unimplemented")
|
2023-09-02 17:30:52 -06:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-08-31 19:50:32 -06:00
|
|
|
|
2023-09-05 00:53:58 -06:00
|
|
|
err = ctx.RegisterType(reflect.TypeOf(ReqState(0)), ReqStateType,
|
2023-09-05 00:08:09 -06:00
|
|
|
func(ctx *Context, ctx_type SerializedType, t reflect.Type, value *reflect.Value) (SerializedValue, error) {
|
2023-09-02 17:30:52 -06:00
|
|
|
var data []byte = nil
|
|
|
|
if value != nil {
|
|
|
|
val := value.Interface().(ReqState)
|
|
|
|
data = []byte{byte(val)}
|
2023-08-31 22:31:29 -06:00
|
|
|
}
|
|
|
|
return SerializedValue{
|
2023-09-05 00:08:09 -06:00
|
|
|
[]SerializedType{ctx_type},
|
2023-09-02 17:30:52 -06:00
|
|
|
data,
|
2023-08-31 22:31:29 -06:00
|
|
|
}, nil
|
2023-09-03 17:50:12 -06:00
|
|
|
}, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){
|
|
|
|
return reflect.TypeOf(ReqState(0)), nil, SerializedValue{}, fmt.Errorf("unimplemented")
|
2023-09-02 17:30:52 -06:00
|
|
|
})
|
2023-08-31 19:50:32 -06:00
|
|
|
if err != nil {
|
2023-09-02 17:30:52 -06:00
|
|
|
return nil, err
|
2023-07-09 14:30:30 -06:00
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterExtension(reflect.TypeOf((*LockableExt)(nil)), LockableExtType, nil)
|
2023-07-26 00:18:11 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterExtension(reflect.TypeOf((*ListenerExt)(nil)), ListenerExtType, nil)
|
2023-07-26 11:56:10 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterExtension(reflect.TypeOf((*GroupExt)(nil)), GroupExtType, nil)
|
2023-07-26 00:18:11 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
gql_ctx := NewGQLExtContext()
|
|
|
|
err = ctx.RegisterExtension(reflect.TypeOf((*GQLExt)(nil)), GQLExtType, gql_ctx)
|
2023-07-26 00:18:11 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterSignal(reflect.TypeOf((*StopSignal)(nil)), StopSignalType)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ctx.RegisterSignal(reflect.TypeOf((*CreateSignal)(nil)), CreateSignalType)
|
2023-07-25 09:51:55 -06:00
|
|
|
if err != nil {
|
2023-07-25 21:43:15 -06:00
|
|
|
return nil, err
|
2023-07-25 09:51:55 -06:00
|
|
|
}
|
2023-07-10 21:15:01 -06:00
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterSignal(reflect.TypeOf((*StartSignal)(nil)), StartSignalType)
|
2023-08-01 20:55:15 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-29 00:28:44 -06:00
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterSignal(reflect.TypeOf((*ReadSignal)(nil)), ReadSignalType)
|
2023-08-06 12:47:47 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-31 19:50:32 -06:00
|
|
|
err = ctx.RegisterSignal(reflect.TypeOf((*ReadResultSignal)(nil)), ReadResultSignalType)
|
2023-08-06 12:47:47 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
err = ctx.RegisterNodeType(GQLNodeType, []ExtType{GroupExtType, GQLExtType})
|
2023-07-26 23:57:50 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
schema, err := BuildSchema(gql_ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
gql_ctx.Schema = schema
|
|
|
|
|
2023-07-25 21:43:15 -06:00
|
|
|
return ctx, nil
|
2023-07-09 14:30:30 -06:00
|
|
|
}
|