diff --git a/context.go b/context.go index 40f8693..07d8213 100644 --- a/context.go +++ b/context.go @@ -569,39 +569,90 @@ func NewContext(db * badger.DB, log Logger) (*Context, error) { err = ctx.RegisterKind(reflect.Array, ArrayType, func(ctx *Context, ctx_type SerializedType, reflect_type reflect.Type, value *reflect.Value)(SerializedValue, error){ var data []byte + type_stack := []SerializedType{ctx_type} if value == nil { data = nil + } else if value.IsZero() { + return SerializedValue{}, fmt.Errorf("don't know what zero array means...") } 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())) - - var type_stack []SerializedType = nil + var element SerializedValue + var err error for i := 0; i < value.Len(); i += 1 { val := value.Index(i) - element, err := SerializeValue(ctx, reflect_type.Elem(), &val) + element, err = SerializeValue(ctx, reflect_type.Elem(), &val) if err != nil { return SerializedValue{}, err } - if type_stack == nil { - type_stack = append([]SerializedType{ctx_type}, element.TypeStack...) - } data = append(data, element.Data...) } + return SerializedValue{ + append(type_stack, element.TypeStack...), + data, + }, nil } - - elem, err := SerializeValue(ctx, reflect_type.Elem(), nil) + element, err := SerializeValue(ctx, reflect_type.Elem(), nil) if err != nil { return SerializedValue{}, err } - return SerializedValue{ - append([]SerializedType{ctx_type}, elem.TypeStack...), + append(type_stack, element.TypeStack...), data, }, nil }, func(ctx *Context, value SerializedValue)(reflect.Type, *reflect.Value, SerializedValue, error){ - return nil, nil, SerializedValue{}, fmt.Errorf("deserialize array unimplemented") + if value.Data == nil { + elem_type, _, _, err := DeserializeValue(ctx, value) + 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 == 0x00 { + elem_type, _, remaining, err := DeserializeValue(ctx, SerializedValue{ + value.TypeStack, + nil, + }) + if err != nil { + return nil, nil, SerializedValue{}, err + } + array_type := reflect.ArrayOf(0, elem_type) + 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 + for i := 0; i < int(slice_length); i += 1 { + 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.ArrayOf(int(slice_length), element_type) + real_value := reflect.New(reflect_type).Elem() + 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) + } + return reflect_type, reflect_value, value, nil + } + } }) if err != nil { return nil, err