From 50fba5e62484b0feec50b571f76edca45a607a38 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Wed, 6 Jul 2016 03:43:28 +0200 Subject: split --- meta/torrent.go | 163 +------------------------------------------------------- 1 file changed, 1 insertion(+), 162 deletions(-) (limited to 'meta/torrent.go') 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 { -- cgit v1.2.3