diff --git a/pkg/models/connection_graph.go b/pkg/models/connection_graph.go index 2147678..4ce53d2 100644 --- a/pkg/models/connection_graph.go +++ b/pkg/models/connection_graph.go @@ -1,9 +1,8 @@ package models import ( - "bytes" - "encoding/gob" "encoding/json" + "github.com/Krajiyah/ble-sdk/pkg/util" "strings" "sync" ) @@ -30,7 +29,7 @@ func NewConnectionGraphFromRaw(raw map[string]string) *ConnectionGraph { // Data will return serialized form of struct as bytes func (cg *ConnectionGraph) Data() ([]byte, error) { - return encode(cg.GetAll()) + return util.Encode(cg.GetAll()) } // Set will update the map @@ -72,10 +71,8 @@ func (cg *ConnectionGraph) String() string { // GetConnectionGraphFromBytes constructs the map from bytes func GetConnectionGraphFromBytes(data []byte) (*ConnectionGraph, error) { - buf := bytes.NewBuffer(data) - dec := gob.NewDecoder(buf) var m map[string]string - err := dec.Decode(&m) + err := util.Decode(data, &m) if err != nil { return nil, err } diff --git a/pkg/models/requests.go b/pkg/models/requests.go index b1f8530..e555fcc 100644 --- a/pkg/models/requests.go +++ b/pkg/models/requests.go @@ -1,8 +1,7 @@ package models import ( - "bytes" - "encoding/gob" + "github.com/Krajiyah/ble-sdk/pkg/util" ) // LogLevel is the enum for client to server logging levels @@ -42,56 +41,38 @@ type ForwarderRequest struct { IsWrite bool } -func encode(x interface{}) ([]byte, error) { - buf := bytes.NewBuffer([]byte{}) - enc := gob.NewEncoder(buf) - err := enc.Encode(x) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - // Data will return serialized form of struct as bytes func (c *ClientStateRequest) Data() ([]byte, error) { - return encode(c) + return util.Encode(c) } // Data will return serialized form of struct as bytes func (c *ClientLogRequest) Data() ([]byte, error) { - return encode(c) + return util.Encode(c) } // Data will return serialized form of struct as bytes func (f *ForwarderRequest) Data() ([]byte, error) { - return encode(f) -} - -func getDecoder(data []byte) *gob.Decoder { - buf := bytes.NewBuffer(data) - return gob.NewDecoder(buf) + return util.Encode(f) } // GetClientStateRequestFromBytes constructs client state request from characteristic write payload func GetClientStateRequestFromBytes(data []byte) (*ClientStateRequest, error) { - dec := getDecoder(data) var ret ClientStateRequest - err := dec.Decode(&ret) + err := util.Decode(data, &ret) return &ret, err } // GetClientLogRequestFromBytes constructs client log request from characteristic write payload func GetClientLogRequestFromBytes(data []byte) (*ClientLogRequest, error) { - dec := getDecoder(data) var ret ClientLogRequest - err := dec.Decode(&ret) + err := util.Decode(data, &ret) return &ret, err } // GetForwarderRequestFromBytes constructs forwarder request from characteristic write payload func GetForwarderRequestFromBytes(data []byte) (*ForwarderRequest, error) { - dec := getDecoder(data) var ret ForwarderRequest - err := dec.Decode(&ret) + err := util.Decode(data, &ret) return &ret, err } diff --git a/pkg/models/rssi_map.go b/pkg/models/rssi_map.go index a107c1a..07ff0b0 100644 --- a/pkg/models/rssi_map.go +++ b/pkg/models/rssi_map.go @@ -1,11 +1,11 @@ package models import ( - "bytes" - "encoding/gob" "encoding/json" "strings" "sync" + + "github.com/Krajiyah/ble-sdk/pkg/util" ) // RssiMap is type alias for rssi map (routing tables) @@ -32,7 +32,7 @@ func NewRssiMapFromRaw(raw map[string]map[string]int) *RssiMap { // Data will return serialized form of struct as bytes func (rm *RssiMap) Data() ([]byte, error) { - return encode(rm.GetAll()) + return util.Encode(rm.GetAll()) } // Set will update the map @@ -83,10 +83,8 @@ func (rm *RssiMap) String() string { // GetRssiMapFromBytes constructs client state request from characteristic write payload func GetRssiMapFromBytes(data []byte) (*RssiMap, error) { - buf := bytes.NewBuffer(data) - dec := gob.NewDecoder(buf) var m map[string]map[string]int - err := dec.Decode(&m) + err := util.Decode(data, &m) if err != nil { return nil, err } diff --git a/pkg/util/encoding.go b/pkg/util/encoding.go new file mode 100644 index 0000000..0a033a7 --- /dev/null +++ b/pkg/util/encoding.go @@ -0,0 +1,57 @@ +package util + +import ( + "bytes" + "compress/gzip" + "encoding/json" + "io" +) + +func decompress(data []byte) (resData []byte, err error) { + b := bytes.NewBuffer(data) + var r io.Reader + r, err = gzip.NewReader(b) + if err != nil { + return + } + var resB bytes.Buffer + _, err = resB.ReadFrom(r) + if err != nil { + return + } + resData = resB.Bytes() + return +} + +func compress(data []byte) (compressedData []byte, err error) { + var b bytes.Buffer + gz := gzip.NewWriter(&b) + _, err = gz.Write(data) + if err != nil { + return + } + if err = gz.Flush(); err != nil { + return + } + if err = gz.Close(); err != nil { + return + } + compressedData = b.Bytes() + return +} + +func Encode(x interface{}) ([]byte, error) { + data, err := json.Marshal(x) + if err != nil { + return nil, err + } + return compress(data) +} + +func Decode(data []byte, x interface{}) error { + data, err := decompress(data) + if err != nil { + return err + } + return json.Unmarshal(data, x) +} diff --git a/pkg/util/encoding_test.go b/pkg/util/encoding_test.go new file mode 100644 index 0000000..c45e3f4 --- /dev/null +++ b/pkg/util/encoding_test.go @@ -0,0 +1,32 @@ +package util + +import ( + "testing" + + "gotest.tools/assert" +) + +type TestObj struct { + X int + Y string + Z map[string]int +} + +func TestCompressDecompress(t *testing.T) { + expected := "Hello World!" + data, err := compress([]byte(expected)) + assert.NilError(t, err) + data2, err := decompress(data) + assert.NilError(t, err) + assert.Equal(t, expected, string(data2)) +} + +func TestEncodeDecode(t *testing.T) { + expected := TestObj{X: 1, Y: "hello", Z: map[string]int{"world": 2}} + data, err := Encode(expected) + assert.NilError(t, err) + var actual TestObj + err = Decode(data, &actual) + assert.NilError(t, err) + assert.DeepEqual(t, expected, actual) +} diff --git a/pkg/util/packet.go b/pkg/util/packet.go index a321271..24b6675 100644 --- a/pkg/util/packet.go +++ b/pkg/util/packet.go @@ -1,10 +1,8 @@ package util import ( - "bytes" "crypto/sha256" "encoding/base64" - "encoding/gob" "errors" "sync" @@ -39,13 +37,7 @@ type PacketAggregator struct { // Data will serialize BLEPacket to []byte func (p *BLEPacket) Data() ([]byte, error) { - var buf bytes.Buffer - enc := gob.NewEncoder(&buf) - err := enc.Encode(p) - if err != nil { - return nil, err - } - return buf.Bytes(), nil + return Encode(p) } // NewPacketAggregator makes new struct for packet aggregation @@ -83,10 +75,8 @@ func (pa *PacketAggregator) PopAllDataFromPackets(guid string) ([]byte, error) { // AddPacketFromPacketBytes will take the input bytes, parse to packet struct, and add to store (returns guid) func (pa *PacketAggregator) AddPacketFromPacketBytes(packetBytes []byte) (string, error) { - buf := bytes.NewBuffer(packetBytes) - dec := gob.NewDecoder(buf) var packet BLEPacket - err := dec.Decode(&packet) + err := Decode(packetBytes, &packet) if err != nil { return "", err }