package rpc import ( "bufio" "bytes" "errors" "fmt" "io" "sync" ) type Decoder struct { mutex sync.Mutex r io.Reader buf bytes.Buffer } func NewDecoder(r io.Reader) *Decoder { if _, ok := r.(io.ByteReader); !ok { r = bufio.NewReader(r) } return &Decoder{ r: r, } } func (dec *Decoder) Decode(vs Vars) error { h := make([]byte, 5) n, err := dec.r.Read(h) if n != 5 || err != nil { return errors.New(fmt.Sprintf( "Did not retrieve 5 bytes for the msg header, got %d bytes for %+v", n, h)) } size, err := decodeHeader(h) if err != nil { return err } buf := make([]byte, size) n, err = dec.r.Read(buf) if n != size { return errors.New("MsgRpc::Wrong Byte length read") } vs.UnmarshalBinary(buf) return nil } func decodeHeader(h []byte) (l int, err error) { if h[0] != (h[1] ^ h[2] ^ h[3] ^ h[4]) { return -1, errors.New("MsgRpc::NotP4::MagicNumber") } l = int(h[1])*0x1 + int(h[2])*0x100 + int(h[3])*0x10000 + int(h[4])*0x1000000 // Lengths < 11 are not enough for a func variable... bzzzz... if l < 11 || l >= 0x1fffffff { return -1, errors.New(fmt.Sprintf("MsgRpc::NotP4 %d", l)) } return l, nil }