Added boolean and arrays
This commit is contained in:
parent
cfee5a1a4c
commit
45dbd7cbca
40
marshal.go
40
marshal.go
|
@ -15,6 +15,14 @@ func MarshalString(in string) (ret []byte) {
|
|||
return ret
|
||||
}
|
||||
|
||||
func MarshalBool(in bool) (ret []byte) {
|
||||
if in {
|
||||
return []byte{byte(0)}
|
||||
}
|
||||
|
||||
return []byte{byte(1)}
|
||||
}
|
||||
|
||||
func MarshalInt8(in int8) (ret []byte) {
|
||||
return []byte{byte(in)}
|
||||
}
|
||||
|
@ -85,6 +93,12 @@ var encoderCache map[string]MarshalFunc
|
|||
|
||||
func init() {
|
||||
encoderCache = make(map[string]MarshalFunc)
|
||||
RegisterEncoder("bool", func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(bool); ok {
|
||||
return MarshalBool(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type - expected bool")
|
||||
})
|
||||
RegisterEncoder("int8", func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(int8); ok {
|
||||
return MarshalInt8(i), nil
|
||||
|
@ -159,6 +173,30 @@ func encRegister(e interface{}) (err error) {
|
|||
switch t.Kind() {
|
||||
case reflect.Invalid:
|
||||
return errors.New("ssob: Invalid type")
|
||||
case reflect.Array:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
v := reflect.ValueOf(e)
|
||||
l := v.Len()
|
||||
slen := MarshalInt32(int32(l))
|
||||
blen := 4
|
||||
bs := make([][]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
bs[i], err = marshal(v.Index(i).Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blen += len(bs[i])
|
||||
}
|
||||
|
||||
ret = make([]byte, blen)
|
||||
i := copy(ret, slen)
|
||||
for c := 0; c < l; c++ {
|
||||
i += copy(ret[i:], bs[c])
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
encoderCache[string(t.Kind())] = f
|
||||
case reflect.Slice:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
v := reflect.ValueOf(e)
|
||||
|
@ -234,6 +272,8 @@ func encRegister(e interface{}) (err error) {
|
|||
|
||||
func marshalBaseType(e interface{}) (ret []byte, err error) {
|
||||
switch t := e.(type) {
|
||||
case bool:
|
||||
return encoderCache["bool"](t)
|
||||
case int8:
|
||||
return encoderCache["int8"](t)
|
||||
case uint8:
|
||||
|
|
52
unmarshal.go
52
unmarshal.go
|
@ -18,6 +18,17 @@ func UnmarshalString(in []byte) (ret string, n int, err error) {
|
|||
return string(in[4 : l+4]), int(l) + 4, nil
|
||||
}
|
||||
|
||||
func UnmarshalBool(in []byte) (ret bool, n int, err error) {
|
||||
if len(in) < 1 {
|
||||
return false, 0, errors.New("ssob: Invalid input to decode bool")
|
||||
}
|
||||
|
||||
if in[0] == byte(0) {
|
||||
return true, 1, nil
|
||||
}
|
||||
return false, 1, nil
|
||||
}
|
||||
|
||||
func UnmarshalInt8(in []byte) (ret int8, n int, err error) {
|
||||
if len(in) < 1 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode int8")
|
||||
|
@ -104,6 +115,13 @@ var decoderCache map[string]unmarshalFunc
|
|||
|
||||
func init() {
|
||||
decoderCache = make(map[string]unmarshalFunc)
|
||||
RegisterDecoder("bool", func(e interface{}, in []byte) (n int, err error) {
|
||||
if i, ok := e.(*bool); ok {
|
||||
*i, n, err = UnmarshalBool(in)
|
||||
return n, nil
|
||||
}
|
||||
return 0, errors.New("ssob: Incompatible type - expected bool")
|
||||
})
|
||||
RegisterDecoder("int8", func(e interface{}, in []byte) (n int, err error) {
|
||||
if i, ok := e.(*int8); ok {
|
||||
*i, n, err = UnmarshalInt8(in)
|
||||
|
@ -189,6 +207,38 @@ func decRegister(e interface{}) (err error) {
|
|||
switch t.Kind() {
|
||||
case reflect.Invalid:
|
||||
return errors.New("ssob: Invalid type")
|
||||
case reflect.Array:
|
||||
f := func(e interface{}, in []byte) (n int, err error) {
|
||||
t := reflect.TypeOf(e)
|
||||
v := reflect.ValueOf(e)
|
||||
pos := 0
|
||||
|
||||
if t.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
|
||||
l, r, err := UnmarshalInt32(in)
|
||||
pos += r
|
||||
if err != nil {
|
||||
return pos, err
|
||||
}
|
||||
|
||||
ti := v.Elem()
|
||||
if int(l) != ti.Len() {
|
||||
return pos, errors.New("ssob: Invalid array length. Expected " + string(l) + " got " + string(ti.Len()))
|
||||
}
|
||||
for i := 0; i < int(l); i++ {
|
||||
e := reflect.New(reflect.TypeOf(ti.Interface()).Elem())
|
||||
r, err := unmarshal(e.Interface(), in[pos:])
|
||||
pos += r
|
||||
if err != nil {
|
||||
return pos, err
|
||||
}
|
||||
ti.Index(i).Set(reflect.Indirect(e))
|
||||
}
|
||||
return pos, nil
|
||||
}
|
||||
decoderCache[string(t.Kind())] = f
|
||||
case reflect.Slice:
|
||||
f := func(e interface{}, in []byte) (n int, err error) {
|
||||
t := reflect.TypeOf(e)
|
||||
|
@ -290,6 +340,8 @@ func decRegister(e interface{}) (err error) {
|
|||
|
||||
func unmarshalBaseType(e interface{}, in []byte) (n int, err error) {
|
||||
switch t := e.(type) {
|
||||
case *bool:
|
||||
return decoderCache["bool"](t, in)
|
||||
case *int8:
|
||||
return decoderCache["int8"](t, in)
|
||||
case *uint8:
|
||||
|
|
|
@ -15,6 +15,14 @@ func UnsafeMarshalString(in string) (ret []byte) {
|
|||
return ret
|
||||
}
|
||||
|
||||
func UnsafeMarshalBool(in bool) (ret []byte) {
|
||||
if in {
|
||||
return []byte{byte(0)}
|
||||
}
|
||||
|
||||
return []byte{byte(1)}
|
||||
}
|
||||
|
||||
func UnsafeMarshalInt8(in int8) (ret []byte) {
|
||||
return []byte{byte(in)}
|
||||
}
|
||||
|
@ -195,6 +203,12 @@ var unsafeEncoderCache map[string]MarshalFunc
|
|||
|
||||
func init() {
|
||||
unsafeEncoderCache = make(map[string]MarshalFunc)
|
||||
RegisterUnsafeEncoder("bool", func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(bool); ok {
|
||||
return UnsafeMarshalBool(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type - expected bool")
|
||||
})
|
||||
RegisterUnsafeEncoder("int8", func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(int8); ok {
|
||||
return UnsafeMarshalInt8(i), nil
|
||||
|
@ -269,6 +283,30 @@ func encRegisterUnsafe(e interface{}) (err error) {
|
|||
switch t.Kind() {
|
||||
case reflect.Invalid:
|
||||
return errors.New("ssob: Invalid type")
|
||||
case reflect.Array:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
v := reflect.ValueOf(e)
|
||||
l := v.Len()
|
||||
slen := UnsafeMarshalInt32(int32(l))
|
||||
blen := 4
|
||||
bs := make([][]byte, l)
|
||||
for i := 0; i < l; i++ {
|
||||
bs[i], err = unsafeMarshal(v.Index(i).Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blen += len(bs[i])
|
||||
}
|
||||
|
||||
ret = make([]byte, blen)
|
||||
i := copy(ret, slen)
|
||||
for c := 0; c < l; c++ {
|
||||
i += copy(ret[i:], bs[c])
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
unsafeEncoderCache[string(t.Kind())] = f
|
||||
case reflect.Slice:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
v := reflect.ValueOf(e)
|
||||
|
@ -344,6 +382,8 @@ func encRegisterUnsafe(e interface{}) (err error) {
|
|||
|
||||
func unsafeMarshalBaseType(e interface{}) (ret []byte, err error) {
|
||||
switch t := e.(type) {
|
||||
case bool:
|
||||
return unsafeEncoderCache["bool"](t)
|
||||
case int8:
|
||||
return unsafeEncoderCache["int8"](t)
|
||||
case uint8:
|
||||
|
|
|
@ -19,6 +19,17 @@ func UnsafeUnmarshalString(in []byte) (ret string, n int, err error) {
|
|||
return string(in[4 : l+4]), int(l) + 4, nil
|
||||
}
|
||||
|
||||
func UnsafeUnmarshalBool(in []byte) (ret bool, n int, err error) {
|
||||
if len(in) < 1 {
|
||||
return false, 0, errors.New("ssob: Invalid input to decode bool")
|
||||
}
|
||||
|
||||
if in[0] == byte(0) {
|
||||
return true, 1, nil
|
||||
}
|
||||
return false, 1, nil
|
||||
}
|
||||
|
||||
func UnsafeUnmarshalInt8(in []byte) (ret int8, n int, err error) {
|
||||
if len(in) < 1 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode int8")
|
||||
|
@ -231,6 +242,13 @@ var unsafeDecoderCache map[string]unmarshalFunc
|
|||
|
||||
func init() {
|
||||
unsafeDecoderCache = make(map[string]unmarshalFunc)
|
||||
RegisterUnsafeDecoder("bool", func(e interface{}, in []byte) (n int, err error) {
|
||||
if i, ok := e.(*bool); ok {
|
||||
*i, n, err = UnsafeUnmarshalBool(in)
|
||||
return n, nil
|
||||
}
|
||||
return 0, errors.New("ssob: Incompatible type - expected bool")
|
||||
})
|
||||
RegisterUnsafeDecoder("int8", func(e interface{}, in []byte) (n int, err error) {
|
||||
if i, ok := e.(*int8); ok {
|
||||
*i, n, err = UnsafeUnmarshalInt8(in)
|
||||
|
@ -316,6 +334,38 @@ func decRegisterUnsafe(e interface{}) (err error) {
|
|||
switch t.Kind() {
|
||||
case reflect.Invalid:
|
||||
return errors.New("ssob: Invalid type")
|
||||
case reflect.Array:
|
||||
f := func(e interface{}, in []byte) (n int, err error) {
|
||||
t := reflect.TypeOf(e)
|
||||
v := reflect.ValueOf(e)
|
||||
pos := 0
|
||||
|
||||
if t.Kind() != reflect.Ptr || v.IsNil() {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
|
||||
l, r, err := UnsafeUnmarshalInt32(in)
|
||||
pos += r
|
||||
if err != nil {
|
||||
return pos, err
|
||||
}
|
||||
|
||||
ti := v.Elem()
|
||||
if int(l) != ti.Len() {
|
||||
return pos, errors.New("ssob: Invalid array length. Expected " + string(l) + " got " + string(ti.Len()))
|
||||
}
|
||||
for i := 0; i < int(l); i++ {
|
||||
e := reflect.New(reflect.TypeOf(ti.Interface()).Elem())
|
||||
r, err := unsafeUnmarshal(e.Interface(), in[pos:])
|
||||
pos += r
|
||||
if err != nil {
|
||||
return pos, err
|
||||
}
|
||||
ti.Index(i).Set(reflect.Indirect(e))
|
||||
}
|
||||
return pos, nil
|
||||
}
|
||||
unsafeDecoderCache[string(t.Kind())] = f
|
||||
case reflect.Slice:
|
||||
f := func(e interface{}, in []byte) (n int, err error) {
|
||||
t := reflect.TypeOf(e)
|
||||
|
@ -417,6 +467,8 @@ func decRegisterUnsafe(e interface{}) (err error) {
|
|||
|
||||
func unsafeUnmarshalBaseType(e interface{}, in []byte) (n int, err error) {
|
||||
switch t := e.(type) {
|
||||
case *bool:
|
||||
return unsafeDecoderCache["bool"](t, in)
|
||||
case *int8:
|
||||
return unsafeDecoderCache["int8"](t, in)
|
||||
case *uint8:
|
||||
|
|
Loading…
Reference in New Issue