From 826c46f88b48974eb852788e3b143751133e2743 Mon Sep 17 00:00:00 2001 From: Matthias Fulz Date: Wed, 8 Sep 2021 13:27:39 +0200 Subject: [PATCH] Bugfix for pointer --- encoder.go | 10 ++++++++-- types.go | 38 +++++++++++++++++++++++++++++++++++++- unmarshal.go | 3 +++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/encoder.go b/encoder.go index 8a72375..54faaf8 100644 --- a/encoder.go +++ b/encoder.go @@ -20,13 +20,19 @@ func NewEncoder(w io.Writer) *Encoder { } func (enc *Encoder) Encode(e interface{}) (err error) { - RegisterType(e) + _, v, err := parseInterface(e) + if err != nil { + return err + } + if err = RegisterType(v.Interface()); err != nil { + return err + } for _, t := range cacheTypes.ntypes { slog.LOG_DEBUGFLN("t: %v", t) } var b []byte - if b, err = marshalVal(e); err != nil { + if b, err = marshalVal(v.Interface()); err != nil { return fmt.Errorf("ssob: Cannot encode value: %w", err) } diff --git a/types.go b/types.go index 4cc4cfe..95f550d 100644 --- a/types.go +++ b/types.go @@ -4,6 +4,8 @@ import ( "fmt" "io" "reflect" + + "gitea.olznet.de/OlzNet/slog" ) type allocatorFunc func(vals ...interface{}) interface{} @@ -514,8 +516,42 @@ func valueIsNil(v reflect.Value) (ret bool) { return ret } -func RegisterType(e interface{}) (err error) { +func traverseValuePtr(v reflect.Value) (ret reflect.Value) { + ret = v + if !ret.IsValid() || ret.Kind() != reflect.Ptr { + return ret + } else { + ret = reflect.Indirect(ret) + return traverseValuePtr(ret) + } +} + +func parseInterface(e interface{}) (rett reflect.Type, retv reflect.Value, err error) { t := reflect.TypeOf(e) + + if t == nil || t.Kind() != reflect.Ptr { + return nil, reflect.ValueOf(e), ErrTypeInvalid + } + + 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())) + return rett, retv, nil + } + + return t, reflect.ValueOf(e), nil +} + +func RegisterType(e interface{}) (err error) { + //t := reflect.TypeOf(e) + t, _, err := parseInterface(e) + if err != nil { + return err + } + if t == nil || t.Kind() != reflect.Ptr { return fmt.Errorf("ssob: Interface is not a valid address: %w", ErrTypeInvalid) } diff --git a/unmarshal.go b/unmarshal.go index 40c357c..c331969 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -304,6 +304,7 @@ func unmarshalCommon(e []byte, ntype *NType) (ie []byte, ret interface{}, err er func unmarshalSlice(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) { ret = ntype.alloc() rv := getVal(ret) + rv = traverseValuePtr(rv) ie, l, err := unmarshalUint32(e) if err != nil { return ie, ret, err @@ -331,6 +332,7 @@ func unmarshalSlice(e []byte, ntype *NType) (ie []byte, ret interface{}, err err func unmarshalArray(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) { ret = ntype.alloc() rv := getVal(ret) + rv = traverseValuePtr(rv) stype := getTypeById(ntype.ValType) if stype == nil { @@ -354,6 +356,7 @@ func unmarshalArray(e []byte, ntype *NType) (ie []byte, ret interface{}, err err func unmarshalStruct(e []byte, ntype *NType) (ie []byte, ret interface{}, err error) { ret = ntype.alloc() rv := getVal(ret) + rv = traverseValuePtr(rv) ie = e stype := getTypeById(ntype.ValType)