// using encoding/binary // using struc package proto package proto import ( import ( "bytes" "github.com/lunixbochs/struc" "encoding/binary" "io" "io" ) ) type Reply struct { type Reply struct { Length int `struc:"uint32,sizeof=Data"` Length uint32 Fixed []byte `struc:"[32]byte"` Data []byte Data []byte Serial uint16 Serial int `struc:"uint16"` } } func (r *Reply) WriteTo(w io.Writer) error { func (r *Reply) WriteTo(w io.Writer) error { if len(r.Data) < 32 { return struc.Pack(w, r) r.Data = append(r.Data, bytes.Repeat([]byte{0}, 32-len(r.Data))...) } } r.Length = uint32(len(r.Data)) - 32 func ReadReply(r io.Reader) (*Reply, error) { err := binary.Write(w, binary.BigEndian, &r.Length) reply := &Reply{} if err != nil { err := struc.Unpack(r, reply) return err return reply, err } } err = binary.Write(w, binary.BigEndian, &r.Data) if err != nil { return err } err = binary.Write(w, binary.BigEndian, &r.Serial) if err != nil { return err } _, err = w.Write(r.Data) return err } func ReadReply(r io.Reader) (*Reply, error) { reply := &Reply{} err := binary.Read(r, binary.BigEndian, &reply.Length) if err != nil { return nil, err } reply.Data = make([]byte, reply.Length+32) _, err = r.Read(reply.Data) if err != nil { return nil, err } return reply, nil }