+func (t *Torrent) Metainfo() metainfo.MetaInfo {
+ t.cl.rLock()
+ defer t.cl.rUnlock()
+ return t.newMetaInfo()
+}
+
+func (t *Torrent) addReader(r *reader) {
+ t.cl.lock()
+ defer t.cl.unlock()
+ if t.readers == nil {
+ t.readers = make(map[*reader]struct{})
+ }
+ t.readers[r] = struct{}{}
+ r.posChanged()
+}
+
+func (t *Torrent) deleteReader(r *reader) {
+ delete(t.readers, r)
+ t.readersChanged()
+}
+
+// Raise the priorities of pieces in the range [begin, end) to at least Normal
+// priority. Piece indexes are not the same as bytes. Requires that the info
+// has been obtained, see Torrent.Info and Torrent.GotInfo.
+func (t *Torrent) DownloadPieces(begin, end pieceIndex) {
+ t.cl.lock()
+ t.downloadPiecesLocked(begin, end)
+ t.cl.unlock()
+}
+
+func (t *Torrent) downloadPiecesLocked(begin, end pieceIndex) {
+ for i := begin; i < end; i++ {
+ if t.pieces[i].priority.Raise(PiecePriorityNormal) {
+ t.updatePiecePriority(i, "Torrent.DownloadPieces")
+ }
+ }
+}
+
+func (t *Torrent) CancelPieces(begin, end pieceIndex) {
+ t.cl.lock()
+ t.cancelPiecesLocked(begin, end, "Torrent.CancelPieces")
+ t.cl.unlock()
+}
+
+func (t *Torrent) cancelPiecesLocked(begin, end pieceIndex, reason string) {
+ for i := begin; i < end; i++ {
+ p := &t.pieces[i]
+ if p.priority == PiecePriorityNone {
+ continue
+ }
+ p.priority = PiecePriorityNone
+ t.updatePiecePriority(i, reason)
+ }
+}
+
+func (t *Torrent) initFiles() {
+ var offset int64
+ t.files = new([]*File)
+ for _, fi := range t.info.UpvertedFiles() {
+ *t.files = append(*t.files, &File{
+ t,
+ strings.Join(append([]string{t.info.BestName()}, fi.BestPath()...), "/"),
+ offset,
+ fi.Length,
+ fi,
+ fi.DisplayPath(t.info),
+ PiecePriorityNone,
+ })
+ offset += fi.Length
+ }
+}
+
+// Returns handles to the files in the torrent. This requires that the Info is
+// available first.
+func (t *Torrent) Files() []*File {
+ return *t.files
+}
+
+func (t *Torrent) AddPeers(pp []PeerInfo) (n int) {
+ t.cl.lock()
+ defer t.cl.unlock()
+ n = t.addPeers(pp)
+ return
+}
+
+// Marks the entire torrent for download. Requires the info first, see
+// GotInfo. Sets piece priorities for historical reasons.
+func (t *Torrent) DownloadAll() {
+ t.DownloadPieces(0, t.numPieces())
+}
+
+func (t *Torrent) String() string {
+ s := t.name()
+ if s == "" {
+ return t.infoHash.HexString()
+ } else {
+ return strconv.Quote(s)
+ }
+}
+
+func (t *Torrent) AddTrackers(announceList [][]string) {
+ t.cl.lock()
+ defer t.cl.unlock()
+ t.addTrackers(announceList)
+}
+
+func (t *Torrent) Piece(i pieceIndex) *Piece {
+ return t.piece(i)
+}
+
+func (t *Torrent) PeerConns() []*PeerConn {
+ t.cl.rLock()
+ defer t.cl.rUnlock()
+ ret := make([]*PeerConn, 0, len(t.conns))
+ for c := range t.conns {
+ ret = append(ret, c)
+ }
+ return ret