aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-07-06 03:43:28 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-07-06 03:43:28 +0200
commit50fba5e62484b0feec50b571f76edca45a607a38 (patch)
tree5b5b69e6ca40d8d82605939229dc28ef90621c40
parent3e493ee0ddb045133607a6461f6397f8909e83a5 (diff)
split
-rw-r--r--meta/file.go13
-rw-r--r--meta/info.go156
-rw-r--r--meta/torrent.go163
3 files changed, 170 insertions, 162 deletions
diff --git a/meta/file.go b/meta/file.go
new file mode 100644
index 0000000..2ec14cb
--- /dev/null
+++ b/meta/file.go
@@ -0,0 +1,13 @@
+package meta
+
+import "path"
+
+type File struct {
+ Length int `bencode:"length"`
+ MD5Sum []byte `bencode:"md5sum,optional"` // never seen in wildlife
+ Path []string `bencode:"path"`
+}
+
+func (f File) Name() string {
+ return path.Join(f.Path...)
+}
diff --git a/meta/info.go b/meta/info.go
new file mode 100644
index 0000000..8f76c72
--- /dev/null
+++ b/meta/info.go
@@ -0,0 +1,156 @@
+package meta
+
+import (
+ "crypto/sha1"
+ "errors"
+ "fmt"
+ "os"
+ "path"
+)
+
+var ErrNotImplemented = errors.New("not implemented")
+
+type Info struct {
+ Files []File `bencode:"files"`
+ Length int `bencode:"length"`
+ MD5Sum []byte `bencode:"md5sum,optional"` // never seen in wildlife
+ Name string `bencode:"name"`
+ PieceLength int `bencode:"piece length"`
+ Pieces []byte `bencode:"pieces"` // compact mode
+ Private bool `bencode:"private"` // BEP-0027
+ RootHash []byte `bencode:"root hash"` // BEP-0030
+}
+
+func (i Info) TotalLength() int {
+ if i.Length > 0 {
+ return i.Length
+ }
+ var l int
+ for _, f := range i.Files {
+ l += f.Length
+ }
+ return l
+}
+
+func (i Info) GetPieces() []Piece {
+ length := i.TotalLength()
+ n := length / i.PieceLength
+ last := length % i.PieceLength
+ if last > 0 {
+ n++
+ }
+ p := make([]Piece, n)
+ for k := 0; k < n; k++ {
+ p[k].Length = i.PieceLength
+ if k+1 == n {
+ p[k].Length = length
+ }
+ off := k * sha1.Size
+ copy(p[k].Sum[:], i.Pieces[off:off+sha1.Size])
+ p[k].Offset = k * i.PieceLength
+ }
+ return p
+}
+
+func (i Info) FullPath(n int) (string, error) {
+ if i.isSingleFile() {
+ return i.Name, nil
+ }
+ if n >= len(i.Files) || n < 0 {
+ return "", errors.New("out of range")
+ }
+ return path.Join(i.Name, i.Files[n].Name()), nil
+}
+
+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
+ }
+ off -= l.Length
+ }
+ return 0, off
+}
+
+/*
+ * 0 1 2 3 4 5 6 7 #piece
+ * |----|----|----|----|----|----|----|--| pieces
+ * |-|----|--|----|----------|-|----|----| files
+ * 0 1 2 3 4 5 6 7 #file
+ */
+
+func (i Info) isSingleFile() bool {
+ return len(i.Files) == 0
+}
+
+// FIXME WriteAt ...
+func (i Info) WriteAt(b []byte, off int64) (n int, err error) {
+ return 0, ErrNotImplemented
+}
+
+// FIXME ReadAt ...
+func (i Info) ReadAt(b []byte, off int64) (n int, err error) {
+ if i.isSingleFile() {
+ fd, err := os.OpenFile(i.Name, os.O_RDWR|os.O_CREATE, 0644)
+ if err != nil {
+ return 0, err
+ }
+ 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
+}
+
+// Last returns size of last truncated piece
+func (i Info) Last() int {
+ return i.TotalLength() % i.PieceLength
+}
+
+// Full returns count of full pieces
+func (i Info) Full() int {
+ return i.TotalLength() / i.PieceLength
+}
+
+func (i Info) String() string {
+ var s string
+ for n, f := range i.Files {
+ p, err := i.FullPath(n)
+ if err != nil {
+ panic(err)
+ }
+ s += fmt.Sprintf(" %s (%d)\n", p, f.Length)
+ }
+ s += fmt.Sprintf("%s (%d) ", i.Name, i.TotalLength())
+ s += fmt.Sprintf("%d × %d + %d\n", i.Full(), i.PieceLength, i.Last())
+ return s
+}
diff --git a/meta/torrent.go b/meta/torrent.go
index 03c8693..a3d169e 100644
--- a/meta/torrent.go
+++ b/meta/torrent.go
@@ -3,171 +3,10 @@ package meta
// see also: https://en.wikipedia.org/wiki/Torrent_file
import (
- "crypto/sha1"
- "errors"
"fmt"
- "os"
- "path"
"time"
)
-var ErrNotImplemented = errors.New("not implemented")
-
-type File struct {
- Length int `bencode:"length"`
- MD5Sum []byte `bencode:"md5sum,optional"` // never seen in wildlife
- Path []string `bencode:"path"`
-}
-
-func (f File) Name() string {
- return path.Join(f.Path...)
-}
-
-type Info struct {
- Files []File `bencode:"files"`
- Length int `bencode:"length"`
- MD5Sum []byte `bencode:"md5sum,optional"` // never seen in wildlife
- Name string `bencode:"name"`
- PieceLength int `bencode:"piece length"`
- Pieces []byte `bencode:"pieces"`
- Private bool `bencode:"private"` // BEP-0027
- RootHash []byte `bencode:"root hash"` // BEP-0030
-}
-
-func (i Info) TotalLength() int {
- if i.Length > 0 {
- return i.Length
- }
- var l int
- for _, f := range i.Files {
- l += f.Length
- }
- return l
-}
-
-func (i Info) GetPieces() []Piece {
- length := i.TotalLength()
- n := length / i.PieceLength
- last := length % i.PieceLength
- if last > 0 {
- n++
- }
- p := make([]Piece, n)
- for k := 0; k < n; k++ {
- p[k].Length = i.PieceLength
- if k+1 == n {
- p[k].Length = length
- }
- off := k * sha1.Size
- copy(p[k].Sum[:], i.Pieces[off:off+sha1.Size])
- p[k].Offset = k * i.PieceLength
- }
- return p
-}
-
-func (i Info) FullPath(n int) (string, error) {
- if i.isSingleFile() {
- return i.Name, nil
- }
- if n >= len(i.Files) || n < 0 {
- return "", errors.New("out of range")
- }
- return path.Join(i.Name, i.Files[n].Name()), nil
-}
-
-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
- }
- off -= l.Length
- }
- return 0, off
-}
-
-/*
- * 0 1 2 3 4 5 6 7 #piece
- * |----|----|----|----|----|----|----|--| pieces
- * |-|----|--|----|----------|-|----|----| files
- * 0 1 2 3 4 5 6 7 #file
- */
-
-// FIXME WriteAt ...
-func (i Info) WriteAt(b []byte, off int64) (n int, err error) {
- return 0, ErrNotImplemented
-}
-
-// FIXME ReadAt ...
-func (i Info) ReadAt(b []byte, off int64) (n int, err error) {
- if i.isSingleFile() {
- fd, err := os.OpenFile(i.Name, os.O_RDWR|os.O_CREATE, 0644)
- if err != nil {
- return 0, err
- }
- 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
-}
-
-func (i Info) isSingleFile() bool {
- return len(i.Files) == 0
-}
-
-// Last returns size of last truncated piece
-func (i Info) Last() int {
- return i.TotalLength() % i.PieceLength
-}
-
-// Full returns count of full pieces
-func (i Info) Full() int {
- return i.TotalLength() / i.PieceLength
-}
-
-func (i Info) String() string {
- var s string
- for n, f := range i.Files {
- p, err := i.FullPath(n)
- if err != nil {
- panic(err)
- }
- s += fmt.Sprintf(" %s (%d)\n", p, f.Length)
- }
- s += fmt.Sprintf("%s (%d) ", i.Name, i.TotalLength())
- s += fmt.Sprintf("%d × %d + %d\n", i.Full(), i.PieceLength, i.Last())
- return s
-}
-
type Nodes map[string]int // Host:Port
type Torrent struct {
@@ -181,7 +20,7 @@ type Torrent struct {
Info Info `bencode:"info"`
URLList string `bencode:"url-list,optional"`
InfoHash []byte `bencode:"-"`
- Nodes Nodes `bencode:"nodes"` // BEP-0005
+ //Nodes Nodes `bencode:"nodes"` // BEP-0005
}
func (t Torrent) String() string {