1
0
mirror of https://github.com/veggiedefender/torrent-client.git synced 2025-11-06 17:39:54 +02:00

Separate bitfield into its own package

This commit is contained in:
Jesse
2019-12-29 20:24:06 -05:00
parent 353d112e4d
commit 3b7eb1da70
5 changed files with 66 additions and 56 deletions

18
bitfield/bitfield.go Normal file
View File

@@ -0,0 +1,18 @@
package bitfield
// A Bitfield represents the pieces that a peer has
type Bitfield []byte
// HasPiece tells if a bitfield has a particular index set
func (bf Bitfield) HasPiece(index int) bool {
byteIndex := index / 8
offset := index % 8
return bf[byteIndex]>>(7-offset)&1 != 0
}
// SetPiece sets a bit in the bitfield
func (bf Bitfield) SetPiece(index int) {
byteIndex := index / 8
offset := index % 8
bf[byteIndex] |= 1 << (7 - offset)
}

44
bitfield/bitfield_test.go Normal file
View File

@@ -0,0 +1,44 @@
package bitfield
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestHasPiece(t *testing.T) {
bf := Bitfield{0b01010100, 0b01010100}
outputs := []bool{false, true, false, true, false, true, false, false, false, true, false, true, false, true, false, false}
for i := 0; i < len(outputs); i++ {
assert.Equal(t, outputs[i], bf.HasPiece(i))
}
}
func TestSetPiece(t *testing.T) {
tests := []struct {
input Bitfield
index int
outpt Bitfield
}{
{
input: Bitfield{0b01010100, 0b01010100},
index: 4,
outpt: Bitfield{0b01011100, 0b01010100},
},
{
input: Bitfield{0b01010100, 0b01010100},
index: 9,
outpt: Bitfield{0b01010100, 0b01010100},
},
{
input: Bitfield{0b01010100, 0b01010100},
index: 15,
outpt: Bitfield{0b01010100, 0b01010101},
},
}
for _, test := range tests {
bf := test.input
bf.SetPiece(test.index)
assert.Equal(t, test.outpt, bf)
}
}

View File

@@ -30,9 +30,6 @@ type Message struct {
Payload []byte
}
// A Bitfield represents the pieces that a peer has
type Bitfield []byte
// FormatRequest creates a REQUEST message
func FormatRequest(index, begin, length int) *Message {
payload := make([]byte, 12)
@@ -164,17 +161,3 @@ func (m *Message) String() string {
}
return fmt.Sprintf("%s [%d]", m.name(), len(m.Payload))
}
// HasPiece tells if a bitfield has a particular index set
func (bf Bitfield) HasPiece(index int) bool {
byteIndex := index / 8
offset := index % 8
return bf[byteIndex]>>(7-offset)&1 != 0
}
// SetPiece sets a bit in the bitfield
func (bf Bitfield) SetPiece(index int) {
byteIndex := index / 8
offset := index % 8
bf[byteIndex] |= 1 << (7 - offset)
}

View File

@@ -263,40 +263,3 @@ func TestString(t *testing.T) {
assert.Equal(t, test.output, s)
}
}
func TestHasPiece(t *testing.T) {
bf := Bitfield{0b01010100, 0b01010100}
outputs := []bool{false, true, false, true, false, true, false, false, false, true, false, true, false, true, false, false}
for i := 0; i < len(outputs); i++ {
assert.Equal(t, outputs[i], bf.HasPiece(i))
}
}
func TestSetPiece(t *testing.T) {
tests := []struct {
input Bitfield
index int
outpt Bitfield
}{
{
input: Bitfield{0b01010100, 0b01010100},
index: 4,
outpt: Bitfield{0b01011100, 0b01010100},
},
{
input: Bitfield{0b01010100, 0b01010100},
index: 9,
outpt: Bitfield{0b01010100, 0b01010100},
},
{
input: Bitfield{0b01010100, 0b01010100},
index: 15,
outpt: Bitfield{0b01010100, 0b01010101},
},
}
for _, test := range tests {
bf := test.input
bf.SetPiece(test.index)
assert.Equal(t, test.outpt, bf)
}
}

View File

@@ -7,6 +7,8 @@ import (
"strconv"
"time"
"github.com/veggiedefender/torrent-client/bitfield"
"github.com/veggiedefender/torrent-client/message"
"github.com/veggiedefender/torrent-client/handshake"
@@ -18,7 +20,7 @@ type client struct {
peerID [20]byte
conn net.Conn
reader *bufio.Reader
bitfield message.Bitfield
bitfield bitfield.Bitfield
choked bool
}
@@ -39,7 +41,7 @@ func completeHandshake(conn net.Conn, r *bufio.Reader, infohash, peerID [20]byte
return res, nil
}
func recvBitfield(conn net.Conn, r *bufio.Reader) (message.Bitfield, error) {
func recvBitfield(conn net.Conn, r *bufio.Reader) (bitfield.Bitfield, error) {
conn.SetDeadline(time.Now().Local().Add(5 * time.Second))
defer conn.SetDeadline(time.Time{}) // Disable the deadline