Added possibility to use custom encoder / decoder
This commit is contained in:
parent
39ca0f2303
commit
17f127cdb6
|
@ -40,7 +40,7 @@ func (dec *Decoder) DecodeValue(value reflect.Value) (err error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l, n, err := unmarshalInt64(lb)
|
||||
l, n, err := UnmarshalInt64(lb)
|
||||
if err != nil || n != 8 {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ func (enc *Encoder) EncodeValue(value reflect.Value) (err error) {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bb := marshalInt64(int64(len(b)))
|
||||
bb := MarshalInt64(int64(len(b)))
|
||||
bb = append(bb, b...)
|
||||
|
||||
enc.mutex.Lock()
|
||||
|
|
58
marshal.go
58
marshal.go
|
@ -3,86 +3,87 @@ package ssob
|
|||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func marshalString(in string) (ret []byte) {
|
||||
func MarshalString(in string) (ret []byte) {
|
||||
l := int64(len(in))
|
||||
b := marshalInt64(l)
|
||||
b := MarshalInt64(l)
|
||||
b = append(b, []byte(in)...)
|
||||
return b
|
||||
}
|
||||
|
||||
func marshalInt8(in int8) (ret []byte) {
|
||||
func MarshalInt8(in int8) (ret []byte) {
|
||||
return []byte{byte(in)}
|
||||
}
|
||||
|
||||
func marshalUint8(in uint8) (ret []byte) {
|
||||
func MarshalUint8(in uint8) (ret []byte) {
|
||||
return []byte{byte(in)}
|
||||
}
|
||||
|
||||
func marshalInt16(in int16) (ret []byte) {
|
||||
func MarshalInt16(in int16) (ret []byte) {
|
||||
out := make([]byte, 2)
|
||||
|
||||
binary.BigEndian.PutUint16(out, uint16(in))
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalUint16(in uint16) (ret []byte) {
|
||||
func MarshalUint16(in uint16) (ret []byte) {
|
||||
out := make([]byte, 2)
|
||||
|
||||
binary.BigEndian.PutUint16(out, in)
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalInt32(in int32) (ret []byte) {
|
||||
func MarshalInt32(in int32) (ret []byte) {
|
||||
out := make([]byte, 4)
|
||||
|
||||
binary.BigEndian.PutUint32(out, uint32(in))
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalUint32(in uint32) (ret []byte) {
|
||||
func MarshalUint32(in uint32) (ret []byte) {
|
||||
out := make([]byte, 4)
|
||||
|
||||
binary.BigEndian.PutUint32(out, in)
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalFloat32(in float32) (ret []byte) {
|
||||
func MarshalFloat32(in float32) (ret []byte) {
|
||||
out := make([]byte, 4)
|
||||
|
||||
binary.BigEndian.PutUint32(out, uint32(in))
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalInt64(in int64) (ret []byte) {
|
||||
func MarshalInt64(in int64) (ret []byte) {
|
||||
out := make([]byte, 8)
|
||||
|
||||
binary.BigEndian.PutUint64(out, uint64(in))
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalUint64(in uint64) (ret []byte) {
|
||||
func MarshalUint64(in uint64) (ret []byte) {
|
||||
out := make([]byte, 8)
|
||||
|
||||
binary.BigEndian.PutUint64(out, in)
|
||||
return out
|
||||
}
|
||||
|
||||
func marshalFloat64(in float64) (ret []byte) {
|
||||
func MarshalFloat64(in float64) (ret []byte) {
|
||||
out := make([]byte, 8)
|
||||
|
||||
binary.BigEndian.PutUint64(out, uint64(in))
|
||||
return out
|
||||
}
|
||||
|
||||
type marshalFunc func(e interface{}) (ret []byte, err error)
|
||||
type MarshalFunc func(e interface{}) (ret []byte, err error)
|
||||
|
||||
var encoderCache map[string]marshalFunc
|
||||
var encoderCache map[string]MarshalFunc
|
||||
|
||||
func init() {
|
||||
encoderCache = make(map[string]marshalFunc)
|
||||
encoderCache = make(map[string]MarshalFunc)
|
||||
encRegister(int8(0))
|
||||
encRegister(uint8(0))
|
||||
encRegister(int16(0))
|
||||
|
@ -138,7 +139,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Int8:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(int8); ok {
|
||||
return marshalInt8(i), nil
|
||||
return MarshalInt8(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected int8")
|
||||
}
|
||||
|
@ -146,7 +147,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Uint8:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(uint8); ok {
|
||||
return marshalUint8(i), nil
|
||||
return MarshalUint8(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected uint8")
|
||||
}
|
||||
|
@ -154,7 +155,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Int16:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(int16); ok {
|
||||
return marshalInt16(i), nil
|
||||
return MarshalInt16(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected int16")
|
||||
}
|
||||
|
@ -162,7 +163,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Uint16:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(uint16); ok {
|
||||
return marshalUint16(i), nil
|
||||
return MarshalUint16(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected uint16")
|
||||
}
|
||||
|
@ -170,7 +171,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Int32:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(int32); ok {
|
||||
return marshalInt32(i), nil
|
||||
return MarshalInt32(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected int32")
|
||||
}
|
||||
|
@ -178,7 +179,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Uint32:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(uint32); ok {
|
||||
return marshalUint32(i), nil
|
||||
return MarshalUint32(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected uint32")
|
||||
}
|
||||
|
@ -186,7 +187,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Float32:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(float32); ok {
|
||||
return marshalFloat32(i), nil
|
||||
return MarshalFloat32(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected float32")
|
||||
}
|
||||
|
@ -194,7 +195,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Int64:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(int64); ok {
|
||||
return marshalInt64(i), nil
|
||||
return MarshalInt64(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected int64")
|
||||
}
|
||||
|
@ -202,7 +203,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Uint64:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(uint64); ok {
|
||||
return marshalUint64(i), nil
|
||||
return MarshalUint64(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected uint64")
|
||||
}
|
||||
|
@ -210,7 +211,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.Float64:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(float64); ok {
|
||||
return marshalFloat64(i), nil
|
||||
return MarshalFloat64(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected float64")
|
||||
}
|
||||
|
@ -218,7 +219,7 @@ func encRegister(e interface{}) (err error) {
|
|||
case reflect.String:
|
||||
f := func(e interface{}) (ret []byte, err error) {
|
||||
if i, ok := e.(string); ok {
|
||||
return marshalString(i), nil
|
||||
return MarshalString(i), nil
|
||||
}
|
||||
return nil, errors.New("ssob: Incompatible type " + string(v.Kind()) + " - expected string")
|
||||
}
|
||||
|
@ -250,6 +251,7 @@ func marshal(e interface{}) (ret []byte, err error) {
|
|||
if f, ok := encoderCache[key]; ok {
|
||||
return f(e)
|
||||
} else {
|
||||
fmt.Println("Not found")
|
||||
err = encRegister(e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -258,3 +260,7 @@ func marshal(e interface{}) (ret []byte, err error) {
|
|||
|
||||
return marshal(e)
|
||||
}
|
||||
|
||||
func RegisterEncoder(name string, f MarshalFunc) {
|
||||
encoderCache[name] = f
|
||||
}
|
||||
|
|
50
unmarshal.go
50
unmarshal.go
|
@ -3,10 +3,11 @@ package ssob
|
|||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func unmarshalString(in []byte) (ret string, n int, err error) {
|
||||
func UnmarshalString(in []byte) (ret string, n int, err error) {
|
||||
if len(in) < 8 {
|
||||
return "", 0, errors.New("ssob: Invalid input to decode string")
|
||||
}
|
||||
|
@ -18,7 +19,7 @@ func unmarshalString(in []byte) (ret string, n int, err error) {
|
|||
return string(in[8 : l+8]), int(l) + 8, nil
|
||||
}
|
||||
|
||||
func unmarshalInt8(in []byte) (ret int8, n int, err error) {
|
||||
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")
|
||||
}
|
||||
|
@ -26,7 +27,7 @@ func unmarshalInt8(in []byte) (ret int8, n int, err error) {
|
|||
return int8(in[0]), 1, nil
|
||||
}
|
||||
|
||||
func unmarshalUint8(in []byte) (ret uint8, n int, err error) {
|
||||
func UnmarshalUint8(in []byte) (ret uint8, n int, err error) {
|
||||
if len(in) < 1 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode uint8")
|
||||
}
|
||||
|
@ -34,7 +35,7 @@ func unmarshalUint8(in []byte) (ret uint8, n int, err error) {
|
|||
return uint8(in[0]), 1, nil
|
||||
}
|
||||
|
||||
func unmarshalInt16(in []byte) (ret int16, n int, err error) {
|
||||
func UnmarshalInt16(in []byte) (ret int16, n int, err error) {
|
||||
if len(in) < 2 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode int16")
|
||||
}
|
||||
|
@ -42,7 +43,7 @@ func unmarshalInt16(in []byte) (ret int16, n int, err error) {
|
|||
return int16(binary.BigEndian.Uint16(in[0:2])), 2, nil
|
||||
}
|
||||
|
||||
func unmarshalUint16(in []byte) (ret uint16, n int, err error) {
|
||||
func UnmarshalUint16(in []byte) (ret uint16, n int, err error) {
|
||||
if len(in) < 2 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode uint16")
|
||||
}
|
||||
|
@ -50,7 +51,7 @@ func unmarshalUint16(in []byte) (ret uint16, n int, err error) {
|
|||
return binary.BigEndian.Uint16(in[0:1]), 2, nil
|
||||
}
|
||||
|
||||
func unmarshalInt32(in []byte) (ret int32, n int, err error) {
|
||||
func UnmarshalInt32(in []byte) (ret int32, n int, err error) {
|
||||
if len(in) < 4 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode int32")
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ func unmarshalInt32(in []byte) (ret int32, n int, err error) {
|
|||
return int32(binary.BigEndian.Uint32(in[0:4])), 4, nil
|
||||
}
|
||||
|
||||
func unmarshalUint32(in []byte) (ret uint32, n int, err error) {
|
||||
func UnmarshalUint32(in []byte) (ret uint32, n int, err error) {
|
||||
if len(in) < 4 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode uint32")
|
||||
}
|
||||
|
@ -66,7 +67,7 @@ func unmarshalUint32(in []byte) (ret uint32, n int, err error) {
|
|||
return binary.BigEndian.Uint32(in[0:4]), 4, nil
|
||||
}
|
||||
|
||||
func unmarshalFloat32(in []byte) (ret float32, n int, err error) {
|
||||
func UnmarshalFloat32(in []byte) (ret float32, n int, err error) {
|
||||
if len(in) < 4 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode float32")
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ func unmarshalFloat32(in []byte) (ret float32, n int, err error) {
|
|||
return float32(binary.BigEndian.Uint64(in[0:4])), 4, nil
|
||||
}
|
||||
|
||||
func unmarshalInt64(in []byte) (ret int64, n int, err error) {
|
||||
func UnmarshalInt64(in []byte) (ret int64, n int, err error) {
|
||||
if len(in) < 8 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode int64")
|
||||
}
|
||||
|
@ -82,7 +83,7 @@ func unmarshalInt64(in []byte) (ret int64, n int, err error) {
|
|||
return int64(binary.BigEndian.Uint64(in[0:8])), 8, nil
|
||||
}
|
||||
|
||||
func unmarshalUint64(in []byte) (ret uint64, n int, err error) {
|
||||
func UnmarshalUint64(in []byte) (ret uint64, n int, err error) {
|
||||
if len(in) < 8 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode uint64")
|
||||
}
|
||||
|
@ -90,7 +91,7 @@ func unmarshalUint64(in []byte) (ret uint64, n int, err error) {
|
|||
return binary.BigEndian.Uint64(in[0:8]), 8, nil
|
||||
}
|
||||
|
||||
func unmarshalFloat64(in []byte) (ret float64, n int, err error) {
|
||||
func UnmarshalFloat64(in []byte) (ret float64, n int, err error) {
|
||||
if len(in) < 8 {
|
||||
return 0, 0, errors.New("ssob: Invalid input to decode float64")
|
||||
}
|
||||
|
@ -154,7 +155,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalInt8(in)
|
||||
*i, n, err = UnmarshalInt8(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -169,7 +170,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalUint8(in)
|
||||
*i, n, err = UnmarshalUint8(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -184,7 +185,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalInt16(in)
|
||||
*i, n, err = UnmarshalInt16(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalUint16(in)
|
||||
*i, n, err = UnmarshalUint16(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalInt32(in)
|
||||
*i, n, err = UnmarshalInt32(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -229,7 +230,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalUint32(in)
|
||||
*i, n, err = UnmarshalUint32(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -244,7 +245,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalFloat32(in)
|
||||
*i, n, err = UnmarshalFloat32(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -259,7 +260,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalInt64(in)
|
||||
*i, n, err = UnmarshalInt64(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -274,7 +275,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalUint64(in)
|
||||
*i, n, err = UnmarshalUint64(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -289,7 +290,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalFloat64(in)
|
||||
*i, n, err = UnmarshalFloat64(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -304,7 +305,7 @@ func decRegister(e interface{}) (err error) {
|
|||
if i == nil {
|
||||
return 0, errors.New("ssob: Cannot unmarshal to nil pointer")
|
||||
}
|
||||
*i, n, err = unmarshalString(in)
|
||||
*i, n, err = UnmarshalString(in)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -339,6 +340,7 @@ func unmarshal(e interface{}, in []byte) (n int, err error) {
|
|||
if f, ok := decoderCache[key]; ok {
|
||||
return f(v.Interface(), in)
|
||||
} else {
|
||||
fmt.Println("Not found")
|
||||
err = decRegister(p.Interface())
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -348,3 +350,7 @@ func unmarshal(e interface{}, in []byte) (n int, err error) {
|
|||
|
||||
return unmarshal(e, in)
|
||||
}
|
||||
|
||||
func RegisterDecoder(name string, f func(e interface{}, in []byte) (n int, err error)) {
|
||||
decoderCache[name] = f
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue