From f4c84c435f4aeea86a24879765a9499dfa415d2b Mon Sep 17 00:00:00 2001 From: Matthias Fulz Date: Tue, 22 Oct 2019 13:44:08 +0200 Subject: [PATCH] Added possibility to use typecasting values (a.e.: type XY int64) --- marshal.go | 64 ++++++++++++++++++-- unmarshal.go | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 223 insertions(+), 8 deletions(-) diff --git a/marshal.go b/marshal.go index bf0af1d..90f5b3c 100644 --- a/marshal.go +++ b/marshal.go @@ -263,8 +263,58 @@ func encRegister(e interface{}) (err error) { return ret, nil } encoderCache[t.Name()] = f + case reflect.Bool: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(bool(v.Bool())) + } + encoderCache[t.Name()] = f + case reflect.Uint8: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(uint8(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Uint16: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(uint16(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Uint32: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(uint32(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Uint64: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(uint64(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Int8: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(int8(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Int16: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(int16(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Int32: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(int32(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.Int64: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(int64(v.Uint())) + } + encoderCache[t.Name()] = f + case reflect.String: + f := func(e interface{}) (ret []byte, err error) { + return marshalBaseType(string(v.String())) + } + encoderCache[t.Name()] = f default: - return errors.New("ssob: Unknown type " + string(v.Kind())) + return errors.New("ssob: Unknown type " + string(t.Name())) } return nil @@ -310,16 +360,18 @@ func marshal(e interface{}) (ret []byte, err error) { var key string t := reflect.TypeOf(e) v := reflect.ValueOf(e) - if t.Kind() == reflect.Ptr { + switch t.Kind() { + case reflect.Ptr: if v.IsNil() { return nil, errors.New("ssob: Cannot marshal nil pointer") } p := reflect.Indirect(v) return marshal(p.Interface()) - } - if t.Kind() == reflect.Struct { - key = reflect.TypeOf(e).Name() - } else { + case reflect.Bool, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64, reflect.String, reflect.Struct: + key = t.Name() + default: key = string(t.Kind()) } diff --git a/unmarshal.go b/unmarshal.go index 5321d38..b7f91c0 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -331,6 +331,166 @@ func decRegister(e interface{}) (err error) { return pos, nil } decoderCache[string(t.Kind())] = f + case reflect.Bool: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := bool(false) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetBool(bool(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Uint8: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := uint8(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Uint16: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := uint16(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Uint32: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := uint32(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Uint64: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := uint64(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Int8: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := int8(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Int16: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := int16(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Int32: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := int32(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.Int64: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := int64(0) + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + decoderCache[t.Name()] = f + case reflect.String: + f := func(e interface{}, in []byte) (n int, err error) { + v := reflect.ValueOf(e) + i := string("") + pos := 0 + + r, err := unmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetString(i) + + return pos, nil + } + decoderCache[t.Name()] = f default: return errors.New("ssob: Unknown type " + string(v.Kind())) } @@ -384,9 +544,12 @@ func unmarshal(e interface{}, in []byte) (n int, err error) { p := reflect.Indirect(v) if p.Kind() != reflect.Ptr { - if p.Kind() == reflect.Struct { + switch p.Kind() { + case reflect.Bool, reflect.Int8, reflect.Int16, reflect.Int32, + reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, + reflect.Uint64, reflect.String, reflect.Struct: key = reflect.TypeOf(p.Interface()).Name() - } else { + default: key = string(p.Kind()) }