1package codec 2 3import ( 4 "github.com/gogo/protobuf/proto" 5 "github.com/golang/snappy" 6) 7 8// Codec allows KV clients to serialise and deserialise values. 9type Codec interface { 10 Decode([]byte) (interface{}, error) 11 Encode(interface{}) ([]byte, error) 12 13 // CodecID is a short identifier to communicate what codec should be used to decode the value. 14 // Once in use, this should be stable to avoid confusing other clients. 15 CodecID() string 16} 17 18// Proto is a Codec for proto/snappy 19type Proto struct { 20 id string 21 factory func() proto.Message 22} 23 24func NewProtoCodec(id string, factory func() proto.Message) Proto { 25 return Proto{id: id, factory: factory} 26} 27 28func (p Proto) CodecID() string { 29 return p.id 30} 31 32// Decode implements Codec 33func (p Proto) Decode(bytes []byte) (interface{}, error) { 34 out := p.factory() 35 bytes, err := snappy.Decode(nil, bytes) 36 if err != nil { 37 return nil, err 38 } 39 if err := proto.Unmarshal(bytes, out); err != nil { 40 return nil, err 41 } 42 return out, nil 43} 44 45// Encode implements Codec 46func (p Proto) Encode(msg interface{}) ([]byte, error) { 47 bytes, err := proto.Marshal(msg.(proto.Message)) 48 if err != nil { 49 return nil, err 50 } 51 return snappy.Encode(nil, bytes), nil 52} 53 54// String is a code for strings. 55type String struct{} 56 57func (String) CodecID() string { 58 return "string" 59} 60 61// Decode implements Codec. 62func (String) Decode(bytes []byte) (interface{}, error) { 63 return string(bytes), nil 64} 65 66// Encode implements Codec. 67func (String) Encode(msg interface{}) ([]byte, error) { 68 return []byte(msg.(string)), nil 69} 70