package codecs import ( "bytes" "encoding/gob" "encoding/json" "sync" ) var bufferPool = sync.Pool{New: allocBuffer} func allocBuffer() interface{} { return &bytes.Buffer{} } func getBuffer() *bytes.Buffer { return bufferPool.Get().(*bytes.Buffer) } func releaseBuffer(v *bytes.Buffer) { v.Reset() v.Grow(0) bufferPool.Put(v) } // Serializer - generic serializer interface type Serializer interface { Encode(source interface{}) ([]byte, error) Decode(data []byte, target interface{}) error } // DefaultSerializer - returns default serializer func DefaultSerializer() Serializer { return &JSONSerializer{} } // GobSerializer - gob based serializer type GobSerializer struct{} // Encode - encodes source into bytes using Gob encoder func (s *GobSerializer) Encode(source interface{}) ([]byte, error) { buf := getBuffer() defer releaseBuffer(buf) enc := gob.NewEncoder(buf) err := enc.Encode(source) if err != nil { return nil, err } return buf.Bytes(), nil } // Decode - decodes given bytes into target struct func (s *GobSerializer) Decode(data []byte, target interface{}) error { buf := bytes.NewBuffer(data) dec := gob.NewDecoder(buf) return dec.Decode(target) } // JSONSerializer - JSON based serializer type JSONSerializer struct{} // Encode - encodes source into bytes using JSON encoder func (s *JSONSerializer) Encode(source interface{}) ([]byte, error) { buf := getBuffer() defer releaseBuffer(buf) enc := json.NewEncoder(buf) err := enc.Encode(source) if err != nil { return nil, err } return buf.Bytes(), nil } // Decode - decodes given bytes into target struct func (s *JSONSerializer) Decode(data []byte, target interface{}) error { buf := bytes.NewBuffer(data) dec := json.NewDecoder(buf) return dec.Decode(target) } // Type - shows serializer type func (s *JSONSerializer) Type() string { return "JSON" }