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) return fmt.Errorf("ssob: Cannot encode value: %w", err)
} }
wb := marshalUint32(uint32(len(b)))
wb = append(wb, b...)
enc.mutex.Lock() enc.mutex.Lock()
defer enc.mutex.Unlock() 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) 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) { func marshalInterface(e interface{}, ntype *NType) (ret []byte, err error) {
stype := getTypeById(ntype.ValType) return marshalVal(e)
if stype == nil {
return ret, ErrTypeUnknown
}
return marshalCommon(e, ntype)
} }
func marshalType(e interface{}, ntype *NType) (ret []byte, err error) { func marshalType(e interface{}, ntype *NType) (ret []byte, err error) {
@ -382,23 +377,20 @@ func marshalVal(e interface{}) (ret []byte, err error) {
} }
// type id // type id
bytes := marshalTypeId(n.Id) ret = marshalTypeId(n.Id)
// nil pointer // nil pointer
if i == nil { if i == nil {
bytes = append(bytes, marshalBool(true)...) ret = append(ret, marshalBool(true)...)
bytes = append(bytes, marshalNil(nl)...) ret = append(ret, marshalNil(nl)...)
} else { } else {
bytes = append(bytes, marshalBool(false)...) ret = append(ret, marshalBool(false)...)
if tbytes, err := marshalType(i, n); err != nil { if tbytes, err := marshalType(i, n); err != nil {
return ret, err return ret, err
} else { } else {
bytes = append(bytes, tbytes...) ret = append(ret, tbytes...)
} }
} }
ret = append(ret, marshalUint32(uint32(len(bytes)))...)
ret = append(ret, bytes...)
return ret, err return ret, err
} }

View File

@ -27,7 +27,7 @@ const (
ST_ARRAY = 2 ST_ARRAY = 2
ST_STRUCT = 3 ST_STRUCT = 3
ST_MAP = 4 ST_MAP = 4
ST_INTERFACE = 5 //ST_MINTERFACE = 5
) )
type StructField struct { type StructField struct {
@ -81,6 +81,7 @@ const (
ST_STRING = 12 ST_STRING = 12
ST_ERROR = 13 ST_ERROR = 13
ST_NIL = 14 ST_NIL = 14
ST_INTERFACE = 15
) )
func init() { func init() {
@ -185,6 +186,13 @@ func init() {
} }
cacheTypes.ntypes[ST_NIL] = nilType cacheTypes.ntypes[ST_NIL] = nilType
cacheTypes.nnames["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) { func getTypeById(id uint32) (ret *NType) {
@ -257,16 +265,6 @@ func parseType(t reflect.Type) (ret nallocFunc, mainTypeId uint32, indirection i
valType = vt.Id valType = vt.Id
base = false base = false
mainTypeId = ST_ARRAY 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: case reflect.Struct:
typ := reflect.TypeOf(val.Interface()) typ := reflect.TypeOf(val.Interface())
if !base { if !base {
@ -282,6 +280,8 @@ func parseType(t reflect.Type) (ret nallocFunc, mainTypeId uint32, indirection i
sfield := new(StructField) sfield := new(StructField)
sfield.Name = val.Type().Field(i).Name sfield.Name = val.Type().Field(i).Name
sfield.Tag = string(val.Type().Field(i).Tag) 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()) vt, err := getTypeByNameRegister(val.Field(i).Type().String(), val.Field(i).Type())
if err != nil { if err != nil {
return ret, mainTypeId, indirection, valType, base, sfields, arrayLen, err 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 { if t.Elem().Kind() == reflect.Interface {
rett = reflect.TypeOf(reflect.Indirect(reflect.ValueOf(e)).Interface()) rett = reflect.TypeOf(reflect.Indirect(reflect.ValueOf(e)).Interface())
slog.LOG_DEBUGFLN("t: %v", rett)
retv = reflect.New(rett) retv = reflect.New(rett)
retv.Elem().Set(reflect.ValueOf(reflect.Indirect(reflect.ValueOf(e)).Interface())) 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 return rett, retv, nil
} }
slog.LOG_DEBUGFLN("t: %v", t)
slog.LOG_DEBUGFLN("v: %v", reflect.ValueOf(e))
return t, reflect.ValueOf(e), nil return t, reflect.ValueOf(e), nil
} }

View File

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