From: Sebastian Harl Date: Sun, 21 Sep 2014 04:48:32 +0000 (-0700) Subject: proto: Added functions to unmarshal a raw message body. X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=d325942441f0cf0490d5dd1823cc9e379f6e6182;p=sysdb%2Fgo.git proto: Added functions to unmarshal a raw message body. --- diff --git a/proto/proto.go b/proto/proto.go index 7f53f3d..91e2112 100644 --- a/proto/proto.go +++ b/proto/proto.go @@ -30,6 +30,8 @@ package proto import ( "encoding/binary" + "encoding/json" + "fmt" "io" ) @@ -81,6 +83,18 @@ const ( ConnectionExpr = Status(100) ) +// The DataType describes the type of data in a ConnectionData message. +type DataType int + +const ( + // A HostList can be unmarshaled to []sysdb.Host. + HostList DataType = iota + // A Host can be unmarshaled to sysdb.Host. + Host + // A Timeseries can be unmarshaled to sysdb.Timeseries. + Timeseries +) + // A Message represents a raw message of the SysDB front-end protocol. type Message struct { Type Status @@ -130,4 +144,36 @@ func Write(w io.Writer, m *Message) error { return nil } +// DataType determines the type of data in a ConnectionData message. +func (m Message) DataType() (DataType, error) { + if m.Type != ConnectionData { + return 0, fmt.Errorf("message is not of type DATA") + } + + typ := nbo.Uint32(m.Raw[:4]) + switch Status(typ) { + case ConnectionList, ConnectionLookup: + return HostList, nil + case ConnectionFetch: + return Host, nil + case ConnectionTimeseries: + return Timeseries, nil + } + return 0, fmt.Errorf("unknown DATA type %d", typ) +} + +// Unmarshal parses the raw body of m and stores the result in the value +// pointed to by v which has to match the type of the message and its data. +func Unmarshal(m *Message, v interface{}) error { + if m.Type != ConnectionData { + return fmt.Errorf("unmarshaling message of type %d not supported", m.Type) + } + if len(m.Raw) == 0 { // empty command + return nil + } else if len(m.Raw) < 4 { + return fmt.Errorf("DATA message body too short") + } + return json.Unmarshal(m.Raw[4:], v) +} + // vim: set tw=78 sw=4 sw=4 noexpandtab :