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 }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 10701 | Brett Bates |
Submitting lost decoder Decode will take an empty map[string]string and populate it with what is found in the byte array that exists on its io.Reader Does the minimal error checking so far, will error if we have an invalid 'magic number' or incorrect length Will probably not do anything useful if we are trying to send long message, need to see how we would pass around the content of a 'p4 print' call Is up to the caller when to call, would expect the connection to be looping, on read, until we get a func=release ? Next up is a proper Msg*::Error implementation, instead of using strings |