From ad55cd39c9ca982b8cbc40712885d3ad8a5bea52 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 18 Jul 2016 13:10:27 +0200 Subject: Unmarshal Pieces --- cmd/btcheck/main.go | 11 ++++------- meta/info.go | 20 +------------------- meta/piece.go | 49 ++++++++++++++++++------------------------------- meta/torrent_test.go | 8 ++++---- 4 files changed, 27 insertions(+), 61 deletions(-) diff --git a/cmd/btcheck/main.go b/cmd/btcheck/main.go index 0bbd91d..2fc1b1c 100644 --- a/cmd/btcheck/main.go +++ b/cmd/btcheck/main.go @@ -19,17 +19,14 @@ func main() { log.Fatal(err) } buf := make([]byte, tor.Info.PieceLength) - pieces := tor.Info.GetPieces() - for i, p := range pieces { - n, err := tor.Info.ReadAt(buf, p.Offset) + for i, p := range tor.Info.Pieces { + off := tor.Info.PieceLength * i + n, err := tor.Info.ReadAt(buf, int64(off)) if err != nil { log.Fatal(err) } - fmt.Println(i, p.Offset, n, p.Check(buf[:n])) - pieces[i] = p + fmt.Printf("%d %d %d %x %v\n", i, off, n, p, p.Check(buf[:n])) } - fmt.Println("good pieces:", pieces.Good()) - fmt.Println("bit field:", pieces.BitField()) id, _ := peer.NewID() req := tracker.Request{ diff --git a/meta/info.go b/meta/info.go index a537b46..51378ed 100644 --- a/meta/info.go +++ b/meta/info.go @@ -16,7 +16,7 @@ type Info struct { MD5Sum []byte `bencode:"md5sum,optional"` // never seen in wildlife Name string `bencode:"name"` PieceLength int `bencode:"piece length"` - Pieces []byte `bencode:"pieces"` // compact mode + Pieces Pieces `bencode:"pieces"` Private bool `bencode:"private"` // BEP-0027 RootHash []byte `bencode:"root hash"` // BEP-0030 Raw []byte `bencode:"-"` @@ -62,24 +62,6 @@ func (i Info) fileLength(n int) int64 { return i.Files[n].Length } -func (i Info) GetPieces() Pieces { - n, last := i.Full(), i.Last() - if last > 0 { - n++ - } - p := make(Pieces, n) - for k := 0; k < n; k++ { - p[k].Length = i.PieceLength - if k+1 == n { - p[k].Length = last - } - off := k * sha1.Size - copy(p[k].Sum[:], i.Pieces[off:off+sha1.Size]) - p[k].Offset = int64(k) * int64(i.PieceLength) - } - return p -} - // Open N-th file and allocate required path on demand func (i Info) Open(n int) (*os.File, error) { p := i.Name diff --git a/meta/piece.go b/meta/piece.go index 247f848..ee39d36 100644 --- a/meta/piece.go +++ b/meta/piece.go @@ -4,23 +4,30 @@ import ( "crypto/sha1" "fmt" - "dim13.org/btget/bitfield" + "dim13.org/btget/bencode" ) type Pieces []Piece -type Piece struct { - Offset int64 - Length int - Sum [sha1.Size]byte - Ok bool +func (p *Pieces) UnmarshalBencode(b []byte) (int, error) { + var tmp []byte + n, err := bencode.Unmarshal(b, &tmp) + if err != nil { + return 0, err + } + count := len(tmp) / sha1.Size + *p = make(Pieces, count) + for i := 0; i < count; i++ { + off := i * sha1.Size + copy((*p)[i][:], tmp[off:off+sha1.Size]) + } + return n, nil } -func (p *Piece) Check(b []byte) bool { - if !p.Ok { - p.Ok = sha1.Sum(b) == p.Sum - } - return p.Ok +type Piece [sha1.Size]byte + +func (p Piece) Check(b []byte) bool { + return sha1.Sum(b) == p } type Percent float64 @@ -28,23 +35,3 @@ type Percent float64 func (p Percent) String() string { return fmt.Sprintf("%6.2f%%", p) } - -func (p Pieces) Good() Percent { - var good int - for _, v := range p { - if v.Ok { - good++ - } - } - return Percent(good) * 100.0 / Percent(len(p)) -} - -func (p Pieces) BitField() bitfield.BitField { - bf := bitfield.New(len(p)) - for i, v := range p { - if v.Ok { - bf.Set(i) - } - } - return bf -} diff --git a/meta/torrent_test.go b/meta/torrent_test.go index d8706e0..78d6c77 100644 --- a/meta/torrent_test.go +++ b/meta/torrent_test.go @@ -24,9 +24,9 @@ func TestPieces(t *testing.T) { if err != nil { t.Error(err) } - for i, p := range tor.Info.GetPieces() { - n, off := tor.Info.findFirstFile(p.Offset) - t.Log(i, n, off) + for i, p := range tor.Info.Pieces { + n, off := tor.Info.findFirstFile(int64(tor.Info.PieceLength * i)) + t.Log(i, n, off, p) } } @@ -35,7 +35,7 @@ func TestPieces2(t *testing.T) { if err != nil { t.Error(err) } - for i, p := range tor.Info.GetPieces() { + for i, p := range tor.Info.Pieces { t.Logf("%d %x\n", i, p) } } -- cgit v1.2.3