Added possibility to use custom encoder / decoder

This commit is contained in:
Matthias Fulz 2019-10-04 17:58:17 +02:00
parent 39ca0f2303
commit 17f127cdb6
4 changed files with 62 additions and 50 deletions

View File

@ -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
}

View File

@ -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()

View File

@ -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
}

View File

@ -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
}