Added Interface handling

This commit is contained in:
Matthias Fulz 2021-10-21 11:46:02 +02:00
parent 826c46f88b
commit 35eae62602
4 changed files with 49 additions and 54 deletions

View File

@ -36,10 +36,13 @@ func (enc *Encoder) Encode(e interface{}) (err error) {
return fmt.Errorf("ssob: Cannot encode value: %w", err)
}
wb := marshalUint32(uint32(len(b)))
wb = append(wb, b...)
enc.mutex.Lock()
defer enc.mutex.Unlock()
if _, err = enc.w.Write(b); err != nil {
if _, err = enc.w.Write(wb); err != nil {
return fmt.Errorf("ssob: Cannot encode value: %w", err)
}

View File

@ -350,12 +350,7 @@ func marshalStruct(e interface{}, ntype *NType) (ret []byte, err error) {
}
func marshalInterface(e interface{}, ntype *NType) (ret []byte, err error) {
stype := getTypeById(ntype.ValType)
if stype == nil {
return ret, ErrTypeUnknown
}
return marshalCommon(e, ntype)
return marshalVal(e)
}
func marshalType(e interface{}, ntype *NType) (ret []byte, err error) {
@ -382,23 +377,20 @@ func marshalVal(e interface{}) (ret []byte, err error) {
}
// type id
bytes := marshalTypeId(n.Id)
ret = marshalTypeId(n.Id)
// nil pointer
if i == nil {
bytes = append(bytes, marshalBool(true)...)
bytes = append(bytes, marshalNil(nl)...)
ret = append(ret, marshalBool(true)...)
ret = append(ret, marshalNil(nl)...)
} else {
bytes = append(bytes, marshalBool(false)...)
ret = append(ret, marshalBool(false)...)
if tbytes, err := marshalType(i, n); err != nil {
return ret, err
} else {
bytes = append(bytes, tbytes...)
ret = append(ret, tbytes...)
}
}
ret = append(ret, marshalUint32(uint32(len(bytes)))...)
ret = append(ret, bytes...)
return ret, err
}

View File

@ -22,12 +22,12 @@ type RegisteredTypes struct {
}
const (
ST_COMMON = 0
ST_SLICE = 1
ST_ARRAY = 2
ST_STRUCT = 3
ST_MAP = 4
ST_INTERFACE = 5
ST_COMMON = 0
ST_SLICE = 1
ST_ARRAY = 2
ST_STRUCT = 3
ST_MAP = 4
//ST_MINTERFACE = 5
)
type StructField struct {
@ -66,21 +66,22 @@ const (
)
const (
ST_INVALID = 0
ST_BOOL = 1
ST_UINT8 = 2
ST_UINT16 = 3
ST_UINT32 = 4
ST_UINT64 = 5
ST_INT8 = 6
ST_INT16 = 7
ST_INT32 = 8
ST_INT64 = 9
ST_FLOAT32 = 10
ST_FLOAT64 = 11
ST_STRING = 12
ST_ERROR = 13
ST_NIL = 14
ST_INVALID = 0
ST_BOOL = 1
ST_UINT8 = 2
ST_UINT16 = 3
ST_UINT32 = 4
ST_UINT64 = 5
ST_INT8 = 6
ST_INT16 = 7
ST_INT32 = 8
ST_INT64 = 9
ST_FLOAT32 = 10
ST_FLOAT64 = 11
ST_STRING = 12
ST_ERROR = 13
ST_NIL = 14
ST_INTERFACE = 15
)
func init() {
@ -185,6 +186,13 @@ func init() {
}
cacheTypes.ntypes[ST_NIL] = nilType
cacheTypes.nnames["nil"] = nilType
interfaceType := &NType{
"interface {}", ST_INTERFACE, 0, ST_INTERFACE, ST_INTERFACE, nil,
0, func() interface{} { return new(interface{}) },
}
cacheTypes.ntypes[ST_INTERFACE] = interfaceType
cacheTypes.nnames["interface {}"] = interfaceType
}
func getTypeById(id uint32) (ret *NType) {
@ -257,16 +265,6 @@ func parseType(t reflect.Type) (ret nallocFunc, mainTypeId uint32, indirection i
valType = vt.Id
base = false
mainTypeId = ST_ARRAY
case reflect.Interface:
typ := reflect.TypeOf(nval.Interface())
if !base {
vt, err := getTypeByNameRegister(typ.Elem().String(), typ.Elem())
if err != nil {
return ret, mainTypeId, indirection, valType, base, sfields, arrayLen, err
}
valType = vt.Id
}
mainTypeId = ST_INTERFACE
case reflect.Struct:
typ := reflect.TypeOf(val.Interface())
if !base {
@ -282,6 +280,8 @@ func parseType(t reflect.Type) (ret nallocFunc, mainTypeId uint32, indirection i
sfield := new(StructField)
sfield.Name = val.Type().Field(i).Name
sfield.Tag = string(val.Type().Field(i).Tag)
slog.LOG_DEBUGFLN("ts: %v", val.Field(i).Type().String())
slog.LOG_DEBUGFLN("tt: %v", val.Field(i).Type())
vt, err := getTypeByNameRegister(val.Field(i).Type().String(), val.Field(i).Type())
if err != nil {
return ret, mainTypeId, indirection, valType, base, sfields, arrayLen, err
@ -535,13 +535,16 @@ func parseInterface(e interface{}) (rett reflect.Type, retv reflect.Value, err e
if t.Elem().Kind() == reflect.Interface {
rett = reflect.TypeOf(reflect.Indirect(reflect.ValueOf(e)).Interface())
slog.LOG_DEBUGFLN("t: %v", rett)
retv = reflect.New(rett)
retv.Elem().Set(reflect.ValueOf(reflect.Indirect(reflect.ValueOf(e)).Interface()))
slog.LOG_DEBUGFLN("rett: %v", rett)
slog.LOG_DEBUGFLN("retv: %v", retv)
return rett, retv, nil
}
slog.LOG_DEBUGFLN("t: %v", t)
slog.LOG_DEBUGFLN("v: %v", reflect.ValueOf(e))
return t, reflect.ValueOf(e), nil
}

View File

@ -5,6 +5,8 @@ import (
"fmt"
"math"
"reflect"
"gitea.olznet.de/OlzNet/slog"
)
func unmarshalBool(e []byte) (ie []byte, ret bool, err error) {
@ -380,6 +382,7 @@ func unmarshalStruct(e []byte, ntype *NType) (ie []byte, ret interface{}, err er
return ie, ret, err
}
// TODO: checks?
slog.LOG_DEBUGFLN("v: %v", reflect.TypeOf(v))
rv.Field(i).Set(getVal(v))
}
}
@ -388,13 +391,7 @@ func unmarshalStruct(e []byte, ntype *NType) (ie []byte, ret interface{}, err er
}
func unmarshalInterface(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {
ie = e
stype := getTypeById(ntype.ValType)
if stype == nil {
return ie, ret, ErrTypeUnknown
}
return unmarshalCommon(ie, ntype)
return unmarshalVal(e)
}
func unmarshalType(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) {