package metainfo
import (
- "crypto/sha1"
"errors"
"fmt"
"io"
// Sets Pieces (the block of piece hashes in the Info) by using the passed
// function to get at the torrent data.
-func (info *Info) GeneratePieces(open func(fi FileInfo) (io.ReadCloser, error)) error {
+func (info *Info) GeneratePieces(open func(fi FileInfo) (io.ReadCloser, error)) (err error) {
if info.PieceLength == 0 {
return errors.New("piece length must be non-zero")
}
pw.CloseWithError(err)
}()
defer pr.Close()
- var pieces []byte
- for {
- hasher := sha1.New()
- wn, err := io.CopyN(hasher, pr, info.PieceLength)
- if err == io.EOF {
- err = nil
- }
- if err != nil {
- return err
- }
- if wn == 0 {
- break
- }
- pieces = hasher.Sum(pieces)
- if wn < info.PieceLength {
- break
- }
- }
- info.Pieces = pieces
- return nil
+ info.Pieces, err = GeneratePieces(pr, info.PieceLength, nil)
+ return
}
func (info *Info) TotalLength() (ret int64) {
--- /dev/null
+package metainfo
+
+import (
+ "crypto/sha1"
+ "io"
+)
+
+func GeneratePieces(r io.Reader, pieceLength int64, b []byte) ([]byte, error) {
+ for {
+ h := sha1.New()
+ written, err := io.CopyN(h, r, pieceLength)
+ if written > 0 {
+ b = h.Sum(b)
+ }
+ if err == io.EOF {
+ return b, nil
+ }
+ if err != nil {
+ return b, err
+ }
+ }
+}