diff --git a/decoder.go b/decoder.go index 6f77f03..e8eb078 100644 --- a/decoder.go +++ b/decoder.go @@ -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 } diff --git a/encoder.go b/encoder.go index bd39c04..31c0e9d 100644 --- a/encoder.go +++ b/encoder.go @@ -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() diff --git a/marshal.go b/marshal.go index 560d369..69602b0 100644 --- a/marshal.go +++ b/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 +} diff --git a/unmarshal.go b/unmarshal.go index 8c87c4f..41ebb93 100644 --- a/unmarshal.go +++ b/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 +}