16 MaxLength Integer // TODO: Should this include the length header or not?
19 // io.EOF is returned if the source terminates cleanly on a message boundary.
20 func (d *Decoder) Decode(msg *Message) (err error) {
22 err = binary.Read(d.R, binary.BigEndian, &length)
25 err = fmt.Errorf("error reading message length: %s", err)
29 if length > d.MaxLength {
30 return errors.New("message too long")
37 r := &io.LimitedReader{d.R, int64(length)}
38 // Check that all of r was utilized.
44 err = fmt.Errorf("%d bytes unused in message type %d", r.N, msg.Type)
52 msg.Type = MessageType(c)
54 case Choke, Unchoke, Interested, NotInterested, HaveAll, HaveNone:
57 err = msg.Index.Read(r)
58 case Request, Cancel, Reject:
59 for _, data := range []*Integer{&msg.Index, &msg.Begin, &msg.Length} {
66 b := make([]byte, length-1)
67 _, err = io.ReadFull(r, b)
68 msg.Bitfield = unmarshalBitfield(b)
70 for _, pi := range []*Integer{&msg.Index, &msg.Begin} {
79 //msg.Piece, err = ioutil.ReadAll(r)
80 b := *d.Pool.Get().(*[]byte)
81 n, err := io.ReadFull(r, b)
83 if err != io.ErrUnexpectedEOF || n != int(length-9) {
90 msg.ExtendedID, err = readByte(r)
94 msg.ExtendedPayload, err = ioutil.ReadAll(r)
96 err = binary.Read(r, binary.BigEndian, &msg.Port)
98 err = fmt.Errorf("unknown message type %#v", c)
103 func readByte(r io.Reader) (b byte, err error) {
105 n, err := r.Read(arr[:])
117 func unmarshalBitfield(b []byte) (bf []bool) {
118 for _, c := range b {
119 for i := 7; i >= 0; i-- {
120 bf = append(bf, (c>>uint(i))&1 == 1)