12 Index, Begin, Length Integer
15 ExtendedID ExtensionNumber
16 ExtendedPayload []byte
20 func MakeCancelMessage(piece, offset, length Integer) Message {
29 func (msg Message) RequestSpec() (ret RequestSpec) {
34 if msg.Type == Piece {
35 return Integer(len(msg.Piece))
43 func (msg Message) MustMarshalBinary() []byte {
44 b, err := msg.MarshalBinary()
51 func (msg Message) MarshalBinary() (data []byte, err error) {
52 buf := &bytes.Buffer{}
54 err = buf.WriteByte(byte(msg.Type))
59 case Choke, Unchoke, Interested, NotInterested, HaveAll, HaveNone:
61 err = binary.Write(buf, binary.BigEndian, msg.Index)
62 case Request, Cancel, Reject:
63 for _, i := range []Integer{msg.Index, msg.Begin, msg.Length} {
64 err = binary.Write(buf, binary.BigEndian, i)
70 _, err = buf.Write(marshalBitfield(msg.Bitfield))
72 for _, i := range []Integer{msg.Index, msg.Begin} {
73 err = binary.Write(buf, binary.BigEndian, i)
78 n, err := buf.Write(msg.Piece)
82 if n != len(msg.Piece) {
86 err = buf.WriteByte(byte(msg.ExtendedID))
90 _, err = buf.Write(msg.ExtendedPayload)
92 err = binary.Write(buf, binary.BigEndian, msg.Port)
94 err = fmt.Errorf("unknown message type: %v", msg.Type)
97 data = make([]byte, 4+buf.Len())
98 binary.BigEndian.PutUint32(data, uint32(buf.Len()))
99 if buf.Len() != copy(data[4:], buf.Bytes()) {
105 func marshalBitfield(bf []bool) (b []byte) {
106 b = make([]byte, (len(bf)+7)/8)
107 for i, have := range bf {
112 c |= 1 << uint(7-i%8)