aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-07-12 20:05:13 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-07-12 20:05:13 +0200
commite1e897cd7c27d7c598de52be83e3b4764a5c7861 (patch)
treeb3be95e59d668bb31f7c9711590fb87c94aa4a93
parenta362f6ae3cb7cf0c9b1aadd5c121726dfe71331b (diff)
ReadAt
-rw-r--r--cmd/btcheck/main.go43
-rw-r--r--meta/info.go21
2 files changed, 58 insertions, 6 deletions
diff --git a/cmd/btcheck/main.go b/cmd/btcheck/main.go
index 38dd16d..f7c6bee 100644
--- a/cmd/btcheck/main.go
+++ b/cmd/btcheck/main.go
@@ -1,3 +1,44 @@
package main
-func main() {}
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+
+ "dim13.org/btget/bencode"
+ "dim13.org/btget/meta"
+)
+
+func Open(fname string) (meta.Torrent, error) {
+ var tor meta.Torrent
+ body, err := ioutil.ReadFile(fname)
+ if err != nil {
+ return meta.Torrent{}, err
+ }
+ err = bencode.Unmarshal(body, &tor)
+ if err != nil {
+ return meta.Torrent{}, err
+ }
+ return tor, nil
+}
+
+func main() {
+ if len(os.Args) != 2 {
+ log.Fatal("usage: ", os.Args[0], " <torrent>")
+ }
+ tor, err := Open(os.Args[1])
+ if err != nil {
+ log.Fatal(err)
+ }
+ p := tor.Info.GetPieces()
+ buf := make([]byte, tor.Info.PieceLength)
+ for i := 0; i < tor.Info.NPieces(); i++ {
+ off := tor.Info.Offset(i)
+ n, err := tor.Info.ReadAt(buf, off)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(i, off, n, p[i].Check(buf[:n]))
+ }
+}
diff --git a/meta/info.go b/meta/info.go
index d4b19bc..4b3d28a 100644
--- a/meta/info.go
+++ b/meta/info.go
@@ -21,6 +21,15 @@ type Info struct {
RootHash []byte `bencode:"root hash"` // BEP-0030
}
+// NPieces returns number of all pieces
+func (i Info) NPieces() int {
+ full, last := i.Full(), i.Last()
+ if last > 0 {
+ return full + 1
+ }
+ return full
+}
+
// Full returns count of full pieces
func (i Info) Full() int {
return int(i.TotalLength() / int64(i.PieceLength))
@@ -121,6 +130,9 @@ func (i Info) WriteAt(b []byte, off int64) (n int, err error) {
// FIXME ReadAt ...
func (i Info) ReadAt(b []byte, off int64) (n int, err error) {
+ if off >= i.TotalLength() {
+ return 0, nil
+ }
n, foff := i.findFirstFile(off)
fd, err := i.Open(n)
@@ -131,18 +143,17 @@ func (i Info) ReadAt(b []byte, off int64) (n int, err error) {
flen := i.FileLength(n)
- // does it fit?
- if int64(len(b))+foff <= flen {
+ // does it fit? read ahead
+ if int64(len(b))+foff < flen {
return fd.ReadAt(b, foff)
}
- end := flen + foff
-
+ end := flen - foff
done, err := fd.ReadAt(b[:end], foff)
if err != nil {
return done, err
}
- next, err := i.ReadAt(b[end:], end)
+ next, err := i.ReadAt(b[end:], off+end)
return done + next, err
}