/
piece-hasher.go
61 lines (49 loc) · 1.31 KB
/
piece-hasher.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package bittorrent
import (
"bytes"
"crypto/sha1"
"io"
)
type pieceHasher struct {
PieceLength int64
PieceHashes [][]byte
PieceBuffer []byte
}
func newPieceHasher(pieceLength int64) pieceHasher {
return pieceHasher{
PieceLength: pieceLength,
PieceHashes: [][]byte{},
PieceBuffer: []byte{},
}
}
type pieceHasherWrapperWriter struct {
hasher *pieceHasher
}
func (wrapper pieceHasherWrapperWriter) Write(data []byte) (int, error) {
return wrapper.hasher.Write(data)
}
func (self *pieceHasher) Writer() io.Writer {
return pieceHasherWrapperWriter{hasher: self}
}
func (self *pieceHasher) Write(data []byte) (int, error) {
written := 0
self.PieceBuffer = bytes.Join([][]byte{self.PieceBuffer, data}, []byte(""))
for int64(len(self.PieceBuffer)) >= self.PieceLength {
piece := self.PieceBuffer[:self.PieceLength]
hasher := sha1.New()
hasher.Write(piece)
written += len(piece)
self.PieceHashes = append(self.PieceHashes, hasher.Sum(nil))
self.PieceBuffer = self.PieceBuffer[self.PieceLength:]
}
return written, nil
}
func (self *pieceHasher) Pieces() []byte {
piecesData := bytes.Join(self.PieceHashes, []byte(""))
if len(self.PieceBuffer) > 0 {
hasher := sha1.New()
hasher.Write(self.PieceBuffer)
piecesData = bytes.Join([][]byte{piecesData, hasher.Sum(nil)}, []byte(""))
}
return piecesData
}