storrent/client/piece.go
2026-01-19 21:13:01 +09:00

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
}
}
}