Added type conversation for unsafe

This commit is contained in:
Matthias Fulz 2019-10-22 15:14:26 +02:00
parent d4b442c25d
commit e822dd173a
3 changed files with 227 additions and 13 deletions

View File

@ -203,7 +203,6 @@ func init() {
func decRegister(e interface{}) (err error) { func decRegister(e interface{}) (err error) {
t := reflect.TypeOf(e) t := reflect.TypeOf(e)
v := reflect.ValueOf(e)
switch t.Kind() { switch t.Kind() {
case reflect.Invalid: case reflect.Invalid:
return errors.New("ssob: Invalid type") return errors.New("ssob: Invalid type")
@ -492,7 +491,7 @@ func decRegister(e interface{}) (err error) {
} }
decoderCache[t.Name()] = f decoderCache[t.Name()] = f
default: default:
return errors.New("ssob: Unknown type " + string(v.Kind())) return errors.New("ssob: Unknown type " + string(t.Name()))
} }
return nil return nil

View File

@ -373,8 +373,58 @@ func encRegisterUnsafe(e interface{}) (err error) {
return ret, nil return ret, nil
} }
unsafeEncoderCache[t.Name()] = f 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: default:
return errors.New("ssob: Unknown type " + string(v.Kind())) return errors.New("ssob: Unknown type " + string(t.Name()))
} }
return nil return nil
@ -420,16 +470,18 @@ func unsafeMarshal(e interface{}) (ret []byte, err error) {
var key string var key string
t := reflect.TypeOf(e) t := reflect.TypeOf(e)
v := reflect.ValueOf(e) v := reflect.ValueOf(e)
if t.Kind() == reflect.Ptr { switch t.Kind() {
case reflect.Ptr:
if v.IsNil() { if v.IsNil() {
return nil, errors.New("ssob: Cannot marshal nil pointer") return nil, errors.New("ssob: Cannot marshal nil pointer")
} }
p := reflect.Indirect(v) p := reflect.Indirect(v)
return unsafeMarshal(p.Interface()) return unsafeMarshal(p.Interface())
} case reflect.Bool, reflect.Int8, reflect.Int16, reflect.Int32,
if t.Kind() == reflect.Struct { reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32,
key = reflect.TypeOf(e).Name() reflect.Uint64, reflect.String, reflect.Struct:
} else { key = t.Name()
default:
key = string(t.Kind()) key = string(t.Kind())
} }

View File

@ -330,7 +330,6 @@ func init() {
func decRegisterUnsafe(e interface{}) (err error) { func decRegisterUnsafe(e interface{}) (err error) {
t := reflect.TypeOf(e) t := reflect.TypeOf(e)
v := reflect.ValueOf(e)
switch t.Kind() { switch t.Kind() {
case reflect.Invalid: case reflect.Invalid:
return errors.New("ssob: Invalid type") return errors.New("ssob: Invalid type")
@ -458,8 +457,168 @@ func decRegisterUnsafe(e interface{}) (err error) {
return pos, nil return pos, nil
} }
unsafeDecoderCache[string(t.Kind())] = f 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: default:
return errors.New("ssob: Unknown type " + string(v.Kind())) return errors.New("ssob: Unknown type " + string(t.Name()))
} }
return nil return nil
@ -511,9 +670,12 @@ func unsafeUnmarshal(e interface{}, in []byte) (n int, err error) {
p := reflect.Indirect(v) p := reflect.Indirect(v)
if p.Kind() != reflect.Ptr { 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() key = reflect.TypeOf(p.Interface()).Name()
} else { default:
key = string(p.Kind()) key = string(p.Kind())
} }
@ -524,10 +686,11 @@ func unsafeUnmarshal(e interface{}, in []byte) (n int, err error) {
if err != nil { if err != nil {
return 0, err 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)) { func RegisterUnsafeDecoder(name string, f func(e interface{}, in []byte) (n int, err error)) {