18 func (i *Integer) Read(r io.Reader) error {
19 return binary.Read(r, binary.BigEndian, i)
23 Protocol = "\x13BitTorrent protocol"
27 Choke MessageType = iota
38 HandshakeExtendedID = 0
40 RequestMetadataExtensionMsgType = 0
41 DataMetadataExtensionMsgType = 1
42 RejectMetadataExtensionMsgType = 2
48 Index, Begin, Length Integer
52 ExtendedPayload []byte
55 func (msg Message) MarshalBinary() (data []byte, err error) {
56 buf := &bytes.Buffer{}
58 err = buf.WriteByte(byte(msg.Type))
63 case Choke, Unchoke, Interested, NotInterested:
65 err = binary.Write(buf, binary.BigEndian, msg.Index)
67 for _, i := range []Integer{msg.Index, msg.Begin, msg.Length} {
68 err = binary.Write(buf, binary.BigEndian, i)
74 _, err = buf.Write(marshalBitfield(msg.Bitfield))
76 for _, i := range []Integer{msg.Index, msg.Begin} {
77 err = binary.Write(buf, binary.BigEndian, i)
82 n, err := buf.Write(msg.Piece)
86 if n != len(msg.Piece) {
90 err = buf.WriteByte(msg.ExtendedID)
94 _, err = buf.Write(msg.ExtendedPayload)
96 err = fmt.Errorf("unknown message type: %v", msg.Type)
99 data = make([]byte, 4+buf.Len())
100 binary.BigEndian.PutUint32(data, uint32(buf.Len()))
101 if buf.Len() != copy(data[4:], buf.Bytes()) {
107 type Decoder struct {
109 MaxLength Integer // TODO: Should this include the length header or not?
112 func (d *Decoder) Decode(msg *Message) (err error) {
114 err = binary.Read(d.R, binary.BigEndian, &length)
118 if length > d.MaxLength {
119 return errors.New("message too long")
125 msg.Keepalive = false
126 b := make([]byte, length)
127 _, err = io.ReadFull(d.R, b)
129 err = io.ErrUnexpectedEOF
134 r := bytes.NewReader(b)
135 // Check that all of r was utilized.
141 err = fmt.Errorf("%d bytes unused in message type %d", r.Len(), msg.Type)
144 msg.Keepalive = false
145 c, err := r.ReadByte()
149 msg.Type = MessageType(c)
151 case Choke, Unchoke, Interested, NotInterested:
154 err = msg.Index.Read(r)
155 case Request, Cancel:
156 for _, data := range []*Integer{&msg.Index, &msg.Begin, &msg.Length} {
163 b := make([]byte, length-1)
164 _, err = io.ReadFull(r, b)
165 msg.Bitfield = unmarshalBitfield(b)
167 for _, pi := range []*Integer{&msg.Index, &msg.Begin} {
176 msg.Piece, err = ioutil.ReadAll(r)
178 msg.ExtendedID, err = r.ReadByte()
182 msg.ExtendedPayload, err = ioutil.ReadAll(r)
184 err = fmt.Errorf("unknown message type %#v", c)
191 func (b Bytes) MarshalBinary() ([]byte, error) {
195 func unmarshalBitfield(b []byte) (bf []bool) {
196 for _, c := range b {
197 for i := 7; i >= 0; i-- {
198 bf = append(bf, (c>>uint(i))&1 == 1)
204 func marshalBitfield(bf []bool) (b []byte) {
205 b = make([]byte, (len(bf)+7)/8)
206 for i, have := range bf {
211 c |= 1 << uint(7-i%8)