70 lines
1.1 KiB
Go
70 lines
1.1 KiB
Go
package client
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
|
|
"storrent/bt"
|
|
)
|
|
|
|
type piece struct {
|
|
hash [20]byte
|
|
size int64
|
|
data []byte
|
|
have []bool
|
|
reqs []bool
|
|
reqPeer []*bt.Peer
|
|
done bool
|
|
}
|
|
|
|
func (p *piece) put(begin int, data []byte) bool {
|
|
if p.done {
|
|
return false
|
|
}
|
|
block := begin / bt.BlockSize
|
|
if block >= len(p.have) || p.have[block] {
|
|
return false
|
|
}
|
|
copy(p.data[begin:], data)
|
|
p.have[block] = true
|
|
for _, got := range p.have {
|
|
if !got {
|
|
return false
|
|
}
|
|
}
|
|
if sha1.Sum(p.data) != p.hash {
|
|
for i := range p.have {
|
|
p.have[i] = false
|
|
p.reqs[i] = false
|
|
}
|
|
return false
|
|
}
|
|
p.done = true
|
|
return true
|
|
}
|
|
|
|
func (p *piece) next(peer *bt.Peer) (begin, length int64, ok bool) {
|
|
for i := range p.have {
|
|
if p.have[i] || p.reqs[i] {
|
|
continue
|
|
}
|
|
p.reqs[i] = true
|
|
p.reqPeer[i] = peer
|
|
begin = int64(i) * bt.BlockSize
|
|
length = bt.BlockSize
|
|
if begin+length > p.size {
|
|
length = p.size - begin
|
|
}
|
|
return begin, length, true
|
|
}
|
|
return 0, 0, false
|
|
}
|
|
|
|
func (p *piece) resetPeer(peer *bt.Peer) {
|
|
for i := range p.reqs {
|
|
if p.reqs[i] && p.reqPeer[i] == peer {
|
|
p.reqs[i] = false
|
|
p.reqPeer[i] = nil
|
|
}
|
|
}
|
|
}
|