aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meta/torrent.go33
-rw-r--r--meta/torrent_test.go22
2 files changed, 50 insertions, 5 deletions
diff --git a/meta/torrent.go b/meta/torrent.go
index 140b992..63ac390 100644
--- a/meta/torrent.go
+++ b/meta/torrent.go
@@ -100,8 +100,11 @@ func (i Info) FullPath(n int) (string, error) {
// piece-to-file mapping:
// piece # -> [ { file #, off, len }, ... ]
-func (i Info) FileOffset(piece int) (int, int) {
- off := i.PieceLength * piece
+func (i Info) Offset(piece int) int {
+ return i.PieceLength * piece
+}
+
+func (i Info) FindFile(off int) (int, int) {
for n, l := range i.Files {
if l.Length > off {
return n, off
@@ -132,7 +135,31 @@ func (i Info) ReadAt(b []byte, off int64) (n int, err error) {
defer fd.Close()
return fd.ReadAt(b, int64(i.PieceLength)*off)
} else {
-
+ n, off := i.FindFile(int(off))
+ start := off
+ end := i.PieceLength
+ for k := n; k < len(i.Files); k++ {
+ f := i.Files[n]
+ p, err := i.FullPath(k)
+ if err != nil {
+ return 0, err
+ }
+ fd, err := os.OpenFile(p, os.O_RDWR|os.O_CREATE, 0644)
+ if err != nil {
+ return 0, err
+ }
+ defer fd.Close()
+ if end > f.Length {
+ end = f.Length
+ }
+ fd.ReadAt(b[start:end], int64(off))
+ start = end
+ end = i.PieceLength
+ off += f.Length
+ if start == end {
+ return cap(b), nil
+ }
+ }
}
return 0, ErrNotImplemented
}
diff --git a/meta/torrent_test.go b/meta/torrent_test.go
index b2443af..c3e960c 100644
--- a/meta/torrent_test.go
+++ b/meta/torrent_test.go
@@ -33,8 +33,9 @@ func TestPieces(t *testing.T) {
t.Error(err)
}
for i := 0; i < tor.Info.NPieces(); i++ {
- n, off := tor.Info.FileOffset(i)
- t.Log(n, off)
+ off := i * tor.Info.PieceLength
+ n, foff := tor.Info.FindFile(off)
+ t.Log(off, n, foff)
}
}
@@ -47,3 +48,20 @@ func TestPieces2(t *testing.T) {
t.Logf("%d %x\n", i, p)
}
}
+
+func TestReadAt(t *testing.T) {
+ t.Skip()
+ tor, err := Open("../examples/" + tors["bsd"])
+ if err != nil {
+ t.Error(err)
+ }
+ buf := make([]byte, tor.Info.PieceLength)
+ n, err := tor.Info.ReadAt(buf, 0)
+ if err != nil {
+ t.Log(err)
+ }
+ if n != len(buf) {
+ t.Error("expected", len(buf), "got", n)
+ }
+ //t.Logf("% x\n", buf)
+}