From e822dd173a304b14fc79b7d414b71f6e2d348423 Mon Sep 17 00:00:00 2001 From: Matthias Fulz Date: Tue, 22 Oct 2019 15:14:26 +0200 Subject: [PATCH] Added type conversation for unsafe --- unmarshal.go | 3 +- unsafe_marshal.go | 64 ++++++++++++++-- unsafe_unmarshal.go | 173 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 227 insertions(+), 13 deletions(-) diff --git a/unmarshal.go b/unmarshal.go index 206b465..813f987 100644 --- a/unmarshal.go +++ b/unmarshal.go @@ -203,7 +203,6 @@ func init() { func decRegister(e interface{}) (err error) { t := reflect.TypeOf(e) - v := reflect.ValueOf(e) switch t.Kind() { case reflect.Invalid: return errors.New("ssob: Invalid type") @@ -492,7 +491,7 @@ func decRegister(e interface{}) (err error) { } decoderCache[t.Name()] = f default: - return errors.New("ssob: Unknown type " + string(v.Kind())) + return errors.New("ssob: Unknown type " + string(t.Name())) } return nil diff --git a/unsafe_marshal.go b/unsafe_marshal.go index 9a07637..7d3447d 100644 --- a/unsafe_marshal.go +++ b/unsafe_marshal.go @@ -373,8 +373,58 @@ func encRegisterUnsafe(e interface{}) (err error) { return ret, nil } unsafeEncoderCache[t.Name()] = f + case reflect.Bool: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(bool(v.Bool())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Uint8: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Uint16: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Uint32: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Uint64: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Int8: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Int16: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Int32: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.Int64: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f + case reflect.String: + f := func(e interface{}) (ret []byte, err error) { + return unsafeMarshalBaseType(string(v.String())) + } + unsafeEncoderCache[t.Name()] = f default: - return errors.New("ssob: Unknown type " + string(v.Kind())) + return errors.New("ssob: Unknown type " + string(t.Name())) } return nil @@ -420,16 +470,18 @@ func unsafeMarshal(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 unsafeMarshal(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/unsafe_unmarshal.go b/unsafe_unmarshal.go index 7fb5519..2a8dcb0 100644 --- a/unsafe_unmarshal.go +++ b/unsafe_unmarshal.go @@ -330,7 +330,6 @@ func init() { func decRegisterUnsafe(e interface{}) (err error) { t := reflect.TypeOf(e) - v := reflect.ValueOf(e) switch t.Kind() { case reflect.Invalid: return errors.New("ssob: Invalid type") @@ -458,8 +457,168 @@ func decRegisterUnsafe(e interface{}) (err error) { return pos, nil } unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetBool(bool(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetUint(uint64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetInt(int64(i)) + + return pos, nil + } + unsafeDecoderCache[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 := unsafeUnmarshalBaseType(&i, in[pos:]) + pos += r + if err != nil { + return pos, err + } + v.Elem().SetString(i) + + return pos, nil + } + unsafeDecoderCache[t.Name()] = f default: - return errors.New("ssob: Unknown type " + string(v.Kind())) + return errors.New("ssob: Unknown type " + string(t.Name())) } return nil @@ -511,9 +670,12 @@ func unsafeUnmarshal(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()) } @@ -524,10 +686,11 @@ func unsafeUnmarshal(e interface{}, in []byte) (n int, err error) { if err != nil { return 0, err } + return unsafeUnmarshal(e, in) } } - return unsafeUnmarshal(e, in) + return unsafeUnmarshal(p, in) } func RegisterUnsafeDecoder(name string, f func(e interface{}, in []byte) (n int, err error)) {