]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Merge Torrent and torrent types
authorMatt Joiner <anacrolix@gmail.com>
Sun, 3 Apr 2016 08:40:43 +0000 (18:40 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 3 Apr 2016 08:40:43 +0000 (18:40 +1000)
16 files changed:
client.go
client_test.go
cmd/magnet-metainfo/main.go
cmd/torrent-pick/main.go
cmd/torrent/main.go
connection.go
example_test.go
file.go
fs/torrentfs.go
fs/torrentfs_test.go
piece.go
reader.go
t.go
torrent.go
torrent_test.go
worst_conns.go

index 9145a477598487a72f54d5209a3bcbf5c4ea3f6e..c03da7264411aeaaf06a533a7d64ee9c947b6918 100644 (file)
--- a/client.go
+++ b/client.go
@@ -114,7 +114,7 @@ const (
 )
 
 // Currently doesn't really queue, but should in the future.
-func (cl *Client) queuePieceCheck(t *torrent, pieceIndex int) {
+func (cl *Client) queuePieceCheck(t *Torrent, pieceIndex int) {
        piece := &t.pieces[pieceIndex]
        if piece.QueuedForHash {
                return
@@ -126,7 +126,7 @@ func (cl *Client) queuePieceCheck(t *torrent, pieceIndex int) {
 
 // Queue a piece check if one isn't already queued, and the piece has never
 // been checked before.
-func (cl *Client) queueFirstHash(t *torrent, piece int) {
+func (cl *Client) queueFirstHash(t *Torrent, piece int) {
        p := &t.pieces[piece]
        if p.EverHashed || p.Hashing || p.QueuedForHash || t.pieceComplete(piece) {
                return
@@ -158,7 +158,7 @@ type Client struct {
        event  sync.Cond
        closed missinggo.Event
 
-       torrents map[metainfo.InfoHash]*torrent
+       torrents map[metainfo.InfoHash]*Torrent
 }
 
 func (me *Client) IPBlockList() iplist.Ranger {
@@ -204,7 +204,7 @@ func (me hashSorter) Swap(a, b int) {
        me.Hashes[a], me.Hashes[b] = me.Hashes[b], me.Hashes[a]
 }
 
-func (cl *Client) sortedTorrents() (ret []*torrent) {
+func (cl *Client) sortedTorrents() (ret []*Torrent) {
        var hs hashSorter
        for ih := range cl.torrents {
                hs.Hashes = append(hs.Hashes, ih)
@@ -379,7 +379,7 @@ func NewClient(cfg *Config) (cl *Client, err error) {
                config:            *cfg,
                defaultStorage:    cfg.DefaultStorage,
                dopplegangerAddrs: make(map[string]struct{}),
-               torrents:          make(map[metainfo.InfoHash]*torrent),
+               torrents:          make(map[metainfo.InfoHash]*Torrent),
        }
        missinggo.CopyExact(&cl.extensionBytes, defaultExtensionBytes)
        cl.event.L = &cl.mu
@@ -576,18 +576,14 @@ func (cl *Client) incomingConnection(nc net.Conn, utp bool) {
 }
 
 // Returns a handle to the given torrent, if it's present in the client.
-func (cl *Client) Torrent(ih metainfo.InfoHash) (Torrent, ok bool) {
+func (cl *Client) Torrent(ih metainfo.InfoHash) (t *Torrent, ok bool) {
        cl.mu.Lock()
        defer cl.mu.Unlock()
-       t, ok := cl.torrents[ih]
-       if !ok {
-               return
-       }
-       T = Torrent{cl, t}
+       t, ok = cl.torrents[ih]
        return
 }
 
-func (me *Client) torrent(ih metainfo.InfoHash) *torrent {
+func (me *Client) torrent(ih metainfo.InfoHash) *Torrent {
        return me.torrents[ih]
 }
 
@@ -596,7 +592,7 @@ type dialResult struct {
        UTP  bool
 }
 
-func doDial(dial func(addr string, t *torrent) (net.Conn, error), ch chan dialResult, utp bool, addr string, t *torrent) {
+func doDial(dial func(addr string, t *Torrent) (net.Conn, error), ch chan dialResult, utp bool, addr string, t *Torrent) {
        conn, err := dial(addr, t)
        if err != nil {
                if conn != nil {
@@ -628,7 +624,7 @@ func (me *Client) dopplegangerAddr(addr string) bool {
 
 // Start the process of connecting to the given peer for the given torrent if
 // appropriate.
-func (me *Client) initiateConn(peer Peer, t *torrent) {
+func (me *Client) initiateConn(peer Peer, t *Torrent) {
        if peer.Id == me.peerID {
                return
        }
@@ -645,14 +641,14 @@ func (me *Client) initiateConn(peer Peer, t *torrent) {
        go me.outgoingConnection(t, addr, peer.Source)
 }
 
-func (me *Client) dialTimeout(t *torrent) time.Duration {
+func (me *Client) dialTimeout(t *Torrent) time.Duration {
        me.mu.Lock()
        pendingPeers := len(t.peers)
        me.mu.Unlock()
        return reducedDialTimeout(nominalDialTimeout, me.halfOpenLimit, pendingPeers)
 }
 
-func (me *Client) dialTCP(addr string, t *torrent) (c net.Conn, err error) {
+func (me *Client) dialTCP(addr string, t *Torrent) (c net.Conn, err error) {
        c, err = net.DialTimeout("tcp", addr, me.dialTimeout(t))
        if err == nil {
                c.(*net.TCPConn).SetLinger(0)
@@ -660,12 +656,12 @@ func (me *Client) dialTCP(addr string, t *torrent) (c net.Conn, err error) {
        return
 }
 
-func (me *Client) dialUTP(addr string, t *torrent) (c net.Conn, err error) {
+func (me *Client) dialUTP(addr string, t *Torrent) (c net.Conn, err error) {
        return me.utpSock.DialTimeout(addr, me.dialTimeout(t))
 }
 
 // Returns a connection over UTP or TCP, whichever is first to connect.
-func (me *Client) dialFirst(addr string, t *torrent) (conn net.Conn, utp bool) {
+func (me *Client) dialFirst(addr string, t *Torrent) (conn net.Conn, utp bool) {
        // Initiate connections via TCP and UTP simultaneously. Use the first one
        // that succeeds.
        left := 0
@@ -703,7 +699,7 @@ func (me *Client) dialFirst(addr string, t *torrent) (conn net.Conn, utp bool) {
        return
 }
 
-func (me *Client) noLongerHalfOpen(t *torrent, addr string) {
+func (me *Client) noLongerHalfOpen(t *Torrent, addr string) {
        if _, ok := t.halfOpen[addr]; !ok {
                panic("invariant broken")
        }
@@ -713,7 +709,7 @@ func (me *Client) noLongerHalfOpen(t *torrent, addr string) {
 
 // Performs initiator handshakes and returns a connection. Returns nil
 // *connection if no connection for valid reasons.
-func (me *Client) handshakesConnection(nc net.Conn, t *torrent, encrypted, utp bool) (c *connection, err error) {
+func (me *Client) handshakesConnection(nc net.Conn, t *Torrent, encrypted, utp bool) (c *connection, err error) {
        c = newConnection()
        c.conn = nc
        c.rw = nc
@@ -732,7 +728,7 @@ func (me *Client) handshakesConnection(nc net.Conn, t *torrent, encrypted, utp b
 
 // Returns nil connection and nil error if no connection could be established
 // for valid reasons.
-func (me *Client) establishOutgoingConn(t *torrent, addr string) (c *connection, err error) {
+func (me *Client) establishOutgoingConn(t *Torrent, addr string) (c *connection, err error) {
        nc, utp := me.dialFirst(addr, t)
        if nc == nil {
                return
@@ -769,7 +765,7 @@ func (me *Client) establishOutgoingConn(t *torrent, addr string) (c *connection,
 
 // Called to dial out and run a connection. The addr we're given is already
 // considered half-open.
-func (me *Client) outgoingConnection(t *torrent, addr string, ps peerSource) {
+func (me *Client) outgoingConnection(t *Torrent, addr string, ps peerSource) {
        c, err := me.establishOutgoingConn(t, addr)
        me.mu.Lock()
        defer me.mu.Unlock()
@@ -981,22 +977,22 @@ func (cl *Client) receiveSkeys() (ret [][]byte) {
        return
 }
 
-func (me *Client) initiateHandshakes(c *connection, t *torrent) (ok bool, err error) {
+func (me *Client) initiateHandshakes(c *connection, t *Torrent) (ok bool, err error) {
        if c.encrypted {
-               c.rw, err = mse.InitiateHandshake(c.rw, t.InfoHash[:], nil)
+               c.rw, err = mse.InitiateHandshake(c.rw, t.infoHash[:], nil)
                if err != nil {
                        return
                }
        }
-       ih, ok, err := me.connBTHandshake(c, &t.InfoHash)
-       if ih != t.InfoHash {
+       ih, ok, err := me.connBTHandshake(c, &t.infoHash)
+       if ih != t.infoHash {
                ok = false
        }
        return
 }
 
 // Do encryption and bittorrent handshakes as receiver.
-func (cl *Client) receiveHandshakes(c *connection) (t *torrent, err error) {
+func (cl *Client) receiveHandshakes(c *connection) (t *Torrent, err error) {
        cl.mu.Lock()
        skeys := cl.receiveSkeys()
        cl.mu.Unlock()
@@ -1036,7 +1032,7 @@ func (cl *Client) connBTHandshake(c *connection, ih *metainfo.InfoHash) (ret met
        return
 }
 
-func (cl *Client) runInitiatedHandshookConn(c *connection, t *torrent) (err error) {
+func (cl *Client) runInitiatedHandshookConn(c *connection, t *Torrent) (err error) {
        if c.PeerID == cl.peerID {
                // Only if we initiated the connection is the remote address a
                // listen addr for a doppleganger.
@@ -1069,7 +1065,7 @@ func (cl *Client) runReceivedConn(c *connection) (err error) {
        return cl.runHandshookConn(c, t)
 }
 
-func (cl *Client) runHandshookConn(c *connection, t *torrent) (err error) {
+func (cl *Client) runHandshookConn(c *connection, t *Torrent) (err error) {
        c.conn.SetWriteDeadline(time.Time{})
        c.rw = readWriter{
                deadlineReader{c.conn, c.rw},
@@ -1090,7 +1086,7 @@ func (cl *Client) runHandshookConn(c *connection, t *torrent) (err error) {
        return
 }
 
-func (me *Client) sendInitialMessages(conn *connection, torrent *torrent) {
+func (me *Client) sendInitialMessages(conn *connection, torrent *Torrent) {
        if conn.PeerExtensionBytes.SupportsExtended() && me.extensionBytes.SupportsExtended() {
                conn.Post(pp.Message{
                        Type:       pp.Extended,
@@ -1148,11 +1144,11 @@ func (me *Client) sendInitialMessages(conn *connection, torrent *torrent) {
        }
 }
 
-func (me *Client) peerUnchoked(torrent *torrent, conn *connection) {
+func (me *Client) peerUnchoked(torrent *Torrent, conn *connection) {
        conn.updateRequests()
 }
 
-func (cl *Client) connCancel(t *torrent, cn *connection, r request) (ok bool) {
+func (cl *Client) connCancel(t *Torrent, cn *connection, r request) (ok bool) {
        ok = cn.Cancel(r)
        if ok {
                postedCancels.Add(1)
@@ -1160,7 +1156,7 @@ func (cl *Client) connCancel(t *torrent, cn *connection, r request) (ok bool) {
        return
 }
 
-func (cl *Client) connDeleteRequest(t *torrent, cn *connection, r request) bool {
+func (cl *Client) connDeleteRequest(t *Torrent, cn *connection, r request) bool {
        if !cn.RequestPending(r) {
                return false
        }
@@ -1168,7 +1164,7 @@ func (cl *Client) connDeleteRequest(t *torrent, cn *connection, r request) bool
        return true
 }
 
-func (cl *Client) requestPendingMetadata(t *torrent, c *connection) {
+func (cl *Client) requestPendingMetadata(t *Torrent, c *connection) {
        if t.haveInfo() {
                return
        }
@@ -1188,12 +1184,12 @@ func (cl *Client) requestPendingMetadata(t *torrent, c *connection) {
        }
 }
 
-func (cl *Client) completedMetadata(t *torrent) {
+func (cl *Client) completedMetadata(t *Torrent) {
        h := sha1.New()
        h.Write(t.metadataBytes)
        var ih metainfo.InfoHash
        missinggo.CopyExact(&ih, h.Sum(nil))
-       if ih != t.InfoHash {
+       if ih != t.infoHash {
                log.Print("bad metadata")
                t.invalidateMetadata()
                return
@@ -1219,7 +1215,7 @@ func (cl *Client) completedMetadata(t *torrent) {
 }
 
 // Process incoming ut_metadata message.
-func (cl *Client) gotMetadataExtensionMsg(payload []byte, t *torrent, c *connection) (err error) {
+func (cl *Client) gotMetadataExtensionMsg(payload []byte, t *Torrent, c *connection) (err error) {
        var d map[string]int
        err = bencode.Unmarshal(payload, &d)
        if err != nil {
@@ -1268,7 +1264,7 @@ func (cl *Client) gotMetadataExtensionMsg(payload []byte, t *torrent, c *connect
        return
 }
 
-func (me *Client) upload(t *torrent, c *connection) {
+func (me *Client) upload(t *Torrent, c *connection) {
        if me.config.NoUpload {
                return
        }
@@ -1305,7 +1301,7 @@ another:
        c.Choke()
 }
 
-func (me *Client) sendChunk(t *torrent, c *connection, r request) error {
+func (me *Client) sendChunk(t *Torrent, c *connection, r request) error {
        // Count the chunk being sent, even if it isn't.
        b := make([]byte, r.Length)
        p := t.info.Piece(int(r.Index))
@@ -1330,7 +1326,7 @@ func (me *Client) sendChunk(t *torrent, c *connection, r request) error {
 
 // Processes incoming bittorrent messages. The client lock is held upon entry
 // and exit.
-func (me *Client) connectionLoop(t *torrent, c *connection) error {
+func (me *Client) connectionLoop(t *Torrent, c *connection) error {
        decoder := pp.Decoder{
                R:         bufio.NewReader(c.rw),
                MaxLength: 256 * 1024,
@@ -1532,7 +1528,7 @@ func (me *Client) connectionLoop(t *torrent, c *connection) error {
 }
 
 // Returns true if connection is removed from torrent.Conns.
-func (me *Client) deleteConnection(t *torrent, c *connection) bool {
+func (me *Client) deleteConnection(t *Torrent, c *connection) bool {
        for i0, _c := range t.conns {
                if _c != c {
                        continue
@@ -1547,7 +1543,7 @@ func (me *Client) deleteConnection(t *torrent, c *connection) bool {
        return false
 }
 
-func (me *Client) dropConnection(t *torrent, c *connection) {
+func (me *Client) dropConnection(t *Torrent, c *connection) {
        me.event.Broadcast()
        c.Close()
        if me.deleteConnection(t, c) {
@@ -1556,7 +1552,7 @@ func (me *Client) dropConnection(t *torrent, c *connection) {
 }
 
 // Returns true if the connection is added.
-func (me *Client) addConnection(t *torrent, c *connection) bool {
+func (me *Client) addConnection(t *Torrent, c *connection) bool {
        if me.closed.IsSet() {
                return false
        }
@@ -1594,7 +1590,7 @@ func (me *Client) addConnection(t *torrent, c *connection) bool {
        return true
 }
 
-func (t *torrent) readerPieces() (ret bitmap.Bitmap) {
+func (t *Torrent) readerPieces() (ret bitmap.Bitmap) {
        t.forReaderOffsetPieces(func(begin, end int) bool {
                ret.AddRange(begin, end)
                return true
@@ -1602,7 +1598,7 @@ func (t *torrent) readerPieces() (ret bitmap.Bitmap) {
        return
 }
 
-func (t *torrent) needData() bool {
+func (t *Torrent) needData() bool {
        if !t.haveInfo() {
                return true
        }
@@ -1614,7 +1610,7 @@ func (t *torrent) needData() bool {
        })
 }
 
-func (cl *Client) usefulConn(t *torrent, c *connection) bool {
+func (cl *Client) usefulConn(t *Torrent, c *connection) bool {
        if c.closed.IsSet() {
                return false
        }
@@ -1627,7 +1623,7 @@ func (cl *Client) usefulConn(t *torrent, c *connection) bool {
        return t.connHasWantedPieces(c)
 }
 
-func (me *Client) wantConns(t *torrent) bool {
+func (me *Client) wantConns(t *Torrent) bool {
        if !me.seeding(t) && !t.needData() {
                return false
        }
@@ -1637,7 +1633,7 @@ func (me *Client) wantConns(t *torrent) bool {
        return t.worstBadConn(me) != nil
 }
 
-func (me *Client) openNewConns(t *torrent) {
+func (me *Client) openNewConns(t *Torrent) {
        select {
        case <-t.ceasingNetworking:
                return
@@ -1663,7 +1659,7 @@ func (me *Client) openNewConns(t *torrent) {
        t.wantPeers.Broadcast()
 }
 
-func (me *Client) addPeers(t *torrent, peers []Peer) {
+func (me *Client) addPeers(t *Torrent, peers []Peer) {
        for _, p := range peers {
                if me.dopplegangerAddr(net.JoinHostPort(
                        p.IP.String(),
@@ -1686,8 +1682,8 @@ func (cl *Client) cachedMetaInfoFilename(ih metainfo.InfoHash) string {
        return filepath.Join(cl.configDir(), "torrents", ih.HexString()+".torrent")
 }
 
-func (cl *Client) saveTorrentFile(t *torrent) error {
-       path := cl.cachedMetaInfoFilename(t.InfoHash)
+func (cl *Client) saveTorrentFile(t *Torrent) error {
+       path := cl.cachedMetaInfoFilename(t.infoHash)
        os.MkdirAll(filepath.Dir(path), 0777)
        f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
        if err != nil {
@@ -1695,23 +1691,23 @@ func (cl *Client) saveTorrentFile(t *torrent) error {
        }
        defer f.Close()
        e := bencode.NewEncoder(f)
-       err = e.Encode(t.MetaInfo())
+       err = e.Encode(t.metainfo())
        if err != nil {
                return fmt.Errorf("error marshalling metainfo: %s", err)
        }
-       mi, err := cl.torrentCacheMetaInfo(t.InfoHash)
+       mi, err := cl.torrentCacheMetaInfo(t.infoHash)
        if err != nil {
                // For example, a script kiddy makes us load too many files, and we're
                // able to save the torrent, but not load it again to check it.
                return nil
        }
-       if !bytes.Equal(mi.Info.Hash.Bytes(), t.InfoHash[:]) {
-               log.Fatalf("%x != %x", mi.Info.Hash, t.InfoHash[:])
+       if !bytes.Equal(mi.Info.Hash.Bytes(), t.infoHash[:]) {
+               log.Fatalf("%x != %x", mi.Info.Hash, t.infoHash[:])
        }
        return nil
 }
 
-func (cl *Client) setMetaData(t *torrent, md *metainfo.Info, bytes []byte) (err error) {
+func (cl *Client) setMetaData(t *Torrent, md *metainfo.Info, bytes []byte) (err error) {
        err = t.setMetadata(md, bytes)
        if err != nil {
                return
@@ -1729,9 +1725,9 @@ func (cl *Client) setMetaData(t *torrent, md *metainfo.Info, bytes []byte) (err
 // Prepare a Torrent without any attachment to a Client. That means we can
 // initialize fields all fields that don't require the Client without locking
 // it.
-func newTorrent(ih metainfo.InfoHash) (t *torrent) {
-       t = &torrent{
-               InfoHash:  ih,
+func newTorrent(ih metainfo.InfoHash) (t *Torrent) {
+       t = &Torrent{
+               infoHash:  ih,
                chunkSize: defaultChunkSize,
                peers:     make(map[peersKey]Peer),
 
@@ -1783,7 +1779,7 @@ nextURL:
        return tier
 }
 
-func (t *torrent) addTrackers(announceList [][]string) {
+func (t *Torrent) addTrackers(announceList [][]string) {
        newTrackers := copyTrackers(t.trackers)
        for tierIndex, tier := range announceList {
                if tierIndex < len(newTrackers) {
@@ -1797,7 +1793,7 @@ func (t *torrent) addTrackers(announceList [][]string) {
 }
 
 // Don't call this before the info is available.
-func (t *torrent) bytesCompleted() int64 {
+func (t *Torrent) bytesCompleted() int64 {
        if !t.haveInfo() {
                return 0
        }
@@ -1814,7 +1810,7 @@ type Handle interface {
 
 // Returns handles to the files in the torrent. This requires the metainfo is
 // available first.
-func (t Torrent) Files() (ret []File) {
+func (t *Torrent) Files() (ret []File) {
        t.cl.mu.Lock()
        info := t.Info()
        t.cl.mu.Unlock()
@@ -1835,20 +1831,20 @@ func (t Torrent) Files() (ret []File) {
        return
 }
 
-func (t Torrent) AddPeers(pp []Peer) error {
+func (t *Torrent) AddPeers(pp []Peer) error {
        cl := t.cl
        cl.mu.Lock()
        defer cl.mu.Unlock()
-       cl.addPeers(t.torrent, pp)
+       cl.addPeers(t, pp)
        return nil
 }
 
 // Marks the entire torrent for download. Requires the info first, see
 // GotInfo.
-func (t Torrent) DownloadAll() {
+func (t *Torrent) DownloadAll() {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       t.torrent.pendPieceRange(0, t.torrent.numPieces())
+       t.pendPieceRange(0, t.numPieces())
 }
 
 // Returns nil metainfo if it isn't in the cache. Checks that the retrieved
@@ -1926,8 +1922,7 @@ func TorrentSpecFromMetaInfo(mi *metainfo.MetaInfo) (spec *TorrentSpec) {
 // trackers will be merged with the existing ones. If the Info isn't yet
 // known, it will be set. The display name is replaced if the new spec
 // provides one. Returns new if the torrent wasn't already in the client.
-func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (T Torrent, new bool, err error) {
-       T.cl = cl
+func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (t *Torrent, new bool, err error) {
        cl.mu.Lock()
        defer cl.mu.Unlock()
 
@@ -1979,16 +1974,15 @@ func (cl *Client) AddTorrentSpec(spec *TorrentSpec) (T Torrent, new bool, err er
        t.addTrackers(spec.Trackers)
 
        cl.torrents[spec.InfoHash] = t
-       T.torrent = t
 
        // From this point onwards, we can consider the torrent a part of the
        // client.
        if new {
                if !cl.config.DisableTrackers {
-                       go cl.announceTorrentTrackers(T.torrent)
+                       go cl.announceTorrentTrackers(t)
                }
                if cl.dHT != nil {
-                       go cl.announceTorrentDHT(T.torrent, true)
+                       go cl.announceTorrentDHT(t, true)
                }
        }
        return
@@ -2009,7 +2003,7 @@ func (me *Client) dropTorrent(infoHash metainfo.InfoHash) (err error) {
 }
 
 // Returns true when peers are required, or false if the torrent is closing.
-func (cl *Client) waitWantPeers(t *torrent) bool {
+func (cl *Client) waitWantPeers(t *Torrent) bool {
        cl.mu.Lock()
        defer cl.mu.Unlock()
        for {
@@ -2030,7 +2024,7 @@ func (cl *Client) waitWantPeers(t *torrent) bool {
 }
 
 // Returns whether the client should make effort to seed the torrent.
-func (cl *Client) seeding(t *torrent) bool {
+func (cl *Client) seeding(t *Torrent) bool {
        if cl.config.NoUpload {
                return false
        }
@@ -2043,10 +2037,10 @@ func (cl *Client) seeding(t *torrent) bool {
        return true
 }
 
-func (cl *Client) announceTorrentDHT(t *torrent, impliedPort bool) {
+func (cl *Client) announceTorrentDHT(t *Torrent, impliedPort bool) {
        for cl.waitWantPeers(t) {
                // log.Printf("getting peers for %q from DHT", t)
-               ps, err := cl.dHT.Announce(string(t.InfoHash[:]), cl.incomingPeerPort(), impliedPort)
+               ps, err := cl.dHT.Announce(string(t.infoHash[:]), cl.incomingPeerPort(), impliedPort)
                if err != nil {
                        log.Printf("error getting peers from dht: %s", err)
                        return
@@ -2113,7 +2107,7 @@ func (cl *Client) trackerBlockedUnlocked(trRawURL string) (blocked bool, err err
        return
 }
 
-func (cl *Client) announceTorrentSingleTracker(tr string, req *tracker.AnnounceRequest, t *torrent) error {
+func (cl *Client) announceTorrentSingleTracker(tr string, req *tracker.AnnounceRequest, t *Torrent) error {
        blocked, err := cl.trackerBlockedUnlocked(tr)
        if err != nil {
                return fmt.Errorf("error determining if tracker blocked: %s", err)
@@ -2142,7 +2136,7 @@ func (cl *Client) announceTorrentSingleTracker(tr string, req *tracker.AnnounceR
        return nil
 }
 
-func (cl *Client) announceTorrentTrackersFastStart(req *tracker.AnnounceRequest, trackers []trackerTier, t *torrent) (atLeastOne bool) {
+func (cl *Client) announceTorrentTrackersFastStart(req *tracker.AnnounceRequest, trackers []trackerTier, t *Torrent) (atLeastOne bool) {
        oks := make(chan bool)
        outstanding := 0
        for _, tier := range trackers {
@@ -2165,13 +2159,13 @@ func (cl *Client) announceTorrentTrackersFastStart(req *tracker.AnnounceRequest,
 }
 
 // Announce torrent to its trackers.
-func (cl *Client) announceTorrentTrackers(t *torrent) {
+func (cl *Client) announceTorrentTrackers(t *Torrent) {
        req := tracker.AnnounceRequest{
                Event:    tracker.Started,
                NumWant:  -1,
                Port:     uint16(cl.incomingPeerPort()),
                PeerId:   cl.peerID,
-               InfoHash: t.InfoHash,
+               InfoHash: t.infoHash,
        }
        if !cl.waitWantPeers(t) {
                return
@@ -2243,7 +2237,7 @@ func (me *Client) WaitAll() bool {
 }
 
 // Handle a received chunk from a peer.
-func (me *Client) downloadedChunk(t *torrent, c *connection, msg *pp.Message) {
+func (me *Client) downloadedChunk(t *Torrent, c *connection, msg *pp.Message) {
        chunksReceived.Add(1)
 
        req := newRequest(msg.Index, msg.Begin, pp.Integer(len(msg.Piece)))
@@ -2315,7 +2309,7 @@ func (me *Client) downloadedChunk(t *torrent, c *connection, msg *pp.Message) {
 
 // Return the connections that touched a piece, and clear the entry while
 // doing it.
-func (me *Client) reapPieceTouches(t *torrent, piece int) (ret []*connection) {
+func (me *Client) reapPieceTouches(t *Torrent, piece int) (ret []*connection) {
        for _, c := range t.conns {
                if _, ok := c.peerTouchedPieces[piece]; ok {
                        ret = append(ret, c)
@@ -2325,7 +2319,7 @@ func (me *Client) reapPieceTouches(t *torrent, piece int) (ret []*connection) {
        return
 }
 
-func (me *Client) pieceHashed(t *torrent, piece int, correct bool) {
+func (me *Client) pieceHashed(t *Torrent, piece int, correct bool) {
        p := &t.pieces[piece]
        if p.EverHashed {
                // Don't score the first time a piece is hashed, it could be an
@@ -2354,7 +2348,7 @@ func (me *Client) pieceHashed(t *torrent, piece int, correct bool) {
        me.pieceChanged(t, int(piece))
 }
 
-func (me *Client) onCompletedPiece(t *torrent, piece int) {
+func (me *Client) onCompletedPiece(t *Torrent, piece int) {
        t.pendingPieces.Remove(piece)
        t.pendAllChunkSpecs(piece)
        for _, conn := range t.conns {
@@ -2370,7 +2364,7 @@ func (me *Client) onCompletedPiece(t *torrent, piece int) {
        }
 }
 
-func (me *Client) onFailedPiece(t *torrent, piece int) {
+func (me *Client) onFailedPiece(t *Torrent, piece int) {
        if t.pieceAllDirty(piece) {
                t.pendAllChunkSpecs(piece)
        }
@@ -2385,7 +2379,7 @@ func (me *Client) onFailedPiece(t *torrent, piece int) {
        }
 }
 
-func (me *Client) pieceChanged(t *torrent, piece int) {
+func (me *Client) pieceChanged(t *Torrent, piece int) {
        correct := t.pieceComplete(piece)
        defer me.event.Broadcast()
        if correct {
@@ -2399,7 +2393,7 @@ func (me *Client) pieceChanged(t *torrent, piece int) {
        t.publishPieceChange(piece)
 }
 
-func (cl *Client) verifyPiece(t *torrent, piece int) {
+func (cl *Client) verifyPiece(t *Torrent, piece int) {
        cl.mu.Lock()
        defer cl.mu.Unlock()
        p := &t.pieces[piece]
@@ -2427,16 +2421,16 @@ func (cl *Client) verifyPiece(t *torrent, piece int) {
 }
 
 // Returns handles to all the torrents loaded in the Client.
-func (me *Client) Torrents() (ret []Torrent) {
+func (me *Client) Torrents() (ret []*Torrent) {
        me.mu.Lock()
        for _, t := range me.torrents {
-               ret = append(ret, Torrent{me, t})
+               ret = append(ret, t)
        }
        me.mu.Unlock()
        return
 }
 
-func (me *Client) AddMagnet(uri string) (T Torrent, err error) {
+func (me *Client) AddMagnet(uri string) (T *Torrent, err error) {
        spec, err := TorrentSpecFromMagnetURI(uri)
        if err != nil {
                return
@@ -2445,7 +2439,7 @@ func (me *Client) AddMagnet(uri string) (T Torrent, err error) {
        return
 }
 
-func (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T Torrent, err error) {
+func (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T *Torrent, err error) {
        T, _, err = me.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
        var ss []string
        missinggo.CastSlice(&ss, mi.Nodes)
@@ -2453,7 +2447,7 @@ func (me *Client) AddTorrent(mi *metainfo.MetaInfo) (T Torrent, err error) {
        return
 }
 
-func (me *Client) AddTorrentFromFile(filename string) (T Torrent, err error) {
+func (me *Client) AddTorrentFromFile(filename string) (T *Torrent, err error) {
        mi, err := metainfo.LoadFromFile(filename)
        if err != nil {
                return
index 350a100d86e487fa5b790c5ed86c85bcf08a24d1..108357d6653a92d7bbdc41a219231d4fba2ffb9f 100644 (file)
@@ -455,8 +455,8 @@ func TestMergingTrackersByAddingSpecs(t *testing.T) {
        if new {
                t.FailNow()
        }
-       assert.EqualValues(t, T.torrent.trackers[0][0], "http://a")
-       assert.EqualValues(t, T.torrent.trackers[1][0], "udp://b")
+       assert.EqualValues(t, T.trackers[0][0], "http://a")
+       assert.EqualValues(t, T.trackers[1][0], "udp://b")
 }
 
 type badStorage struct{}
@@ -787,7 +787,7 @@ func TestAddMetainfoWithNodes(t *testing.T) {
        assert.EqualValues(t, cl.DHT().NumNodes(), 0)
        tt, err := cl.AddTorrentFromFile("metainfo/testdata/issue_65a.torrent")
        require.NoError(t, err)
-       assert.Len(t, tt.torrent.trackers, 5)
+       assert.Len(t, tt.trackers, 5)
        assert.EqualValues(t, 6, cl.DHT().NumNodes())
 }
 
@@ -897,7 +897,7 @@ func TestPeerInvalidHave(t *testing.T) {
        assert.True(t, _new)
        defer tt.Drop()
        cn := &connection{
-               t: tt.torrent,
+               t: tt,
        }
        assert.NoError(t, cn.peerSentHave(0))
        assert.Error(t, cn.peerSentHave(1))
index 878fc7db9404c81445c57325b9a2ce16bde88982..8bad76fd6db40388910e4df3d32fea5d52d99cb7 100644 (file)
@@ -27,7 +27,7 @@ func main() {
                go func() {
                        defer wg.Done()
                        <-t.GotInfo()
-                       mi := t.MetaInfo()
+                       mi := t.Metainfo()
                        t.Drop()
                        f, err := os.Create(mi.Info.Name + ".torrent")
                        if err != nil {
index 5389e3841e358eaf2e0ed43ae12421fc06bb49af..e8a25ad2278f977c96508bece61a3b2fbe7ebf1a 100644 (file)
@@ -135,7 +135,7 @@ func main() {
 
        done := make(chan struct{})
        for _, arg := range posArgs {
-               t := func() torrent.Torrent {
+               t := func() *torrent.Torrent {
                        if strings.HasPrefix(arg, "magnet:") {
                                t, err := client.AddMagnet(arg)
                                if err != nil {
index bf8dc0b06d23cab14c6a38342e5a55b410d89733..72406c960f9c66736899ab24646631fd2f1d5880 100644 (file)
@@ -36,7 +36,7 @@ func resolvedPeerAddrs(ss []string) (ret []torrent.Peer, err error) {
        return
 }
 
-func torrentBar(t torrent.Torrent) {
+func torrentBar(t *torrent.Torrent) {
        bar := uiprogress.AddBar(1)
        bar.AppendCompleted()
        bar.AppendFunc(func(*uiprogress.Bar) (ret string) {
@@ -69,7 +69,7 @@ func torrentBar(t torrent.Torrent) {
 
 func addTorrents(client *torrent.Client) {
        for _, arg := range opts.Torrent {
-               t := func() torrent.Torrent {
+               t := func() *torrent.Torrent {
                        if strings.HasPrefix(arg, "magnet:") {
                                t, err := client.AddMagnet(arg)
                                if err != nil {
index 51db22481db8da38816dd7b43ddb9fa8900dd356..aab97f563d2a1e9ede3bebaf7ec5e33b74c9a150 100644 (file)
@@ -35,7 +35,7 @@ const (
 
 // Maintains the state of a connection with a peer.
 type connection struct {
-       t         *torrent
+       t         *Torrent
        conn      net.Conn
        rw        io.ReadWriter // The real slim shady
        encrypted bool
@@ -188,7 +188,7 @@ func (cn *connection) String() string {
        return buf.String()
 }
 
-func (cn *connection) WriteStatus(w io.Writer, t *torrent) {
+func (cn *connection) WriteStatus(w io.Writer, t *Torrent) {
        // \t isn't preserved in <pre> blocks?
        fmt.Fprintf(w, "%+q: %s-%s\n", cn.PeerID, cn.localAddr(), cn.remoteAddr())
        fmt.Fprintf(w, "    last msg: %s, connected: %s, last useful chunk: %s\n",
index 8a4377af3b7836f6219482c8325ba211dfbddc7d..5c58e4d93a59d91cfa351904e99e31a9c4ee662c 100644 (file)
@@ -20,7 +20,7 @@ func Example() {
 
 func Example_fileReader() {
        var (
-               t torrent.Torrent
+               t *torrent.Torrent
                f torrent.File
        )
        r := t.NewReader()
diff --git a/file.go b/file.go
index 7c8a79bb97e7db06296abc58ec087fab2540a18b..f57cd7af8a35b8491040fbd51e3e4fba88d611b1 100644 (file)
--- a/file.go
+++ b/file.go
@@ -8,14 +8,14 @@ import (
 
 // Provides access to regions of torrent data that correspond to its files.
 type File struct {
-       t      Torrent
+       t      *Torrent
        path   string
        offset int64
        length int64
        fi     metainfo.FileInfo
 }
 
-func (f *File) Torrent() Torrent {
+func (f *File) Torrent() *Torrent {
        return f.t
 }
 
@@ -54,7 +54,7 @@ type FilePieceState struct {
 
 // Returns the state of pieces in this file.
 func (f *File) State() (ret []FilePieceState) {
-       pieceSize := int64(f.t.torrent.usualPieceSize())
+       pieceSize := int64(f.t.usualPieceSize())
        off := f.offset % pieceSize
        remaining := f.length
        for i := int(f.offset / pieceSize); ; i++ {
@@ -66,7 +66,7 @@ func (f *File) State() (ret []FilePieceState) {
                        len1 = remaining
                }
                f.t.cl.mu.RLock()
-               ps := f.t.torrent.pieceState(i)
+               ps := f.t.pieceState(i)
                f.t.cl.mu.RUnlock()
                ret = append(ret, FilePieceState{len1, ps})
                off = 0
@@ -77,13 +77,13 @@ func (f *File) State() (ret []FilePieceState) {
 
 // Requests that all pieces containing data in the file be downloaded.
 func (f *File) Download() {
-       f.t.DownloadPieces(f.t.torrent.byteRegionPieces(f.offset, f.length))
+       f.t.DownloadPieces(f.t.byteRegionPieces(f.offset, f.length))
 }
 
 // Requests that torrent pieces containing bytes in the given region of the
 // file be downloaded.
 func (f *File) PrioritizeRegion(off, len int64) {
-       f.t.DownloadPieces(f.t.torrent.byteRegionPieces(f.offset+off, len))
+       f.t.DownloadPieces(f.t.byteRegionPieces(f.offset+off, len))
 }
 
 func byteRegionExclusivePieces(off, size, pieceSize int64) (begin, end int) {
@@ -93,7 +93,7 @@ func byteRegionExclusivePieces(off, size, pieceSize int64) (begin, end int) {
 }
 
 func (f *File) exclusivePieces() (begin, end int) {
-       return byteRegionExclusivePieces(f.offset, f.length, int64(f.t.torrent.usualPieceSize()))
+       return byteRegionExclusivePieces(f.offset, f.length, int64(f.t.usualPieceSize()))
 }
 
 func (f *File) Cancel() {
index abca5c8fe1afd76120c94db94023e208a6c6a6ea..40650dd011b114dda114dddd747e40996f9fd67e 100644 (file)
@@ -51,7 +51,7 @@ type node struct {
        path     string
        metadata *metainfo.InfoEx
        FS       *TorrentFS
-       t        torrent.Torrent
+       t        *torrent.Torrent
 }
 
 type fileNode struct {
@@ -70,7 +70,7 @@ func (n *node) fsPath() string {
        return "/" + n.metadata.Name + "/" + n.path
 }
 
-func blockingRead(ctx context.Context, fs *TorrentFS, t torrent.Torrent, off int64, p []byte) (n int, err error) {
+func blockingRead(ctx context.Context, fs *TorrentFS, t *torrent.Torrent, off int64, p []byte) (n int, err error) {
        fs.mu.Lock()
        fs.blockedReads++
        fs.event.Broadcast()
@@ -106,7 +106,7 @@ func blockingRead(ctx context.Context, fs *TorrentFS, t torrent.Torrent, off int
        return
 }
 
-func readFull(ctx context.Context, fs *TorrentFS, t torrent.Torrent, off int64, p []byte) (n int, err error) {
+func readFull(ctx context.Context, fs *TorrentFS, t *torrent.Torrent, off int64, p []byte) (n int, err error) {
        for len(p) != 0 {
                var nn int
                nn, err = blockingRead(ctx, fs, t, off, p)
index 62191c6f6c6395afefa9294df3720992ac3b11f5..cca219925184a38e60c53bde93ab2e2f95c6df8b 100644 (file)
@@ -84,9 +84,7 @@ func newGreetingLayout() (tl testLayout, err error) {
 // operations blocked inside the filesystem code.
 func TestUnmountWedged(t *testing.T) {
        layout, err := newGreetingLayout()
-       if err != nil {
-               t.Fatal(err)
-       }
+       require.NoError(t, err)
        defer func() {
                err := layout.Destroy()
                if err != nil {
@@ -103,11 +101,10 @@ func TestUnmountWedged(t *testing.T) {
 
                NoDefaultBlocklist: true,
        })
-       if err != nil {
-               t.Fatal(err)
-       }
+       require.NoError(t, err)
        defer client.Close()
-       client.AddTorrent(layout.Metainfo)
+       _, err = client.AddTorrent(layout.Metainfo)
+       require.NoError(t, err)
        fs := New(client)
        fuseConn, err := fuse.Mount(layout.MountDir)
        if err != nil {
index f5112f807518fadfd9223d8e0ab7299e46b16047..015ffb2fe510d30f6ddcaf83da7b110f6a8522f8 100644 (file)
--- a/piece.go
+++ b/piece.go
@@ -31,7 +31,7 @@ const (
 type piece struct {
        // The completed piece SHA1 hash, from the metainfo "pieces" field.
        Hash  pieceSum
-       t     *torrent
+       t     *Torrent
        index int
        // Chunks we've written to since the last check. The chunk offset and
        // length can be determined by the request chunkSize in use.
index a8897ba3b94879813ea2ba12ace4a9be7e0bcbbc..46e41dff06b40e4d53a54d8b34eb8ff613f3fb6a 100644 (file)
--- a/reader.go
+++ b/reader.go
@@ -47,27 +47,27 @@ func (r *Reader) readable(off int64) (ret bool) {
        if r.torrentClosed() {
                return true
        }
-       req, ok := r.t.torrent.offsetRequest(off)
+       req, ok := r.t.offsetRequest(off)
        if !ok {
                panic(off)
        }
        if r.responsive {
-               return r.t.torrent.haveChunk(req)
+               return r.t.haveChunk(req)
        }
-       return r.t.torrent.pieceComplete(int(req.Index))
+       return r.t.pieceComplete(int(req.Index))
 }
 
 // How many bytes are available to read. Max is the most we could require.
 func (r *Reader) available(off, max int64) (ret int64) {
        for max > 0 {
-               req, ok := r.t.torrent.offsetRequest(off)
+               req, ok := r.t.offsetRequest(off)
                if !ok {
                        break
                }
-               if !r.t.torrent.haveChunk(req) {
+               if !r.t.haveChunk(req) {
                        break
                }
-               len1 := int64(req.Length) - (off - r.t.torrent.requestOffset(req))
+               len1 := int64(req.Length) - (off - r.t.requestOffset(req))
                max -= len1
                ret += len1
                off += len1
@@ -80,7 +80,7 @@ func (r *Reader) available(off, max int64) (ret int64) {
 }
 
 func (r *Reader) tickleClient() {
-       r.t.torrent.readersChanged()
+       r.t.readersChanged()
 }
 
 func (r *Reader) waitReadable(off int64) {
@@ -108,7 +108,7 @@ func (r *Reader) Read(b []byte) (n int, err error) {
                r.pos += int64(n1)
                r.mu.Unlock()
        }
-       if r.pos >= r.t.torrent.length {
+       if r.pos >= r.t.length {
                err = io.EOF
        } else if err == io.EOF {
                err = io.ErrUnexpectedEOF
@@ -118,7 +118,7 @@ func (r *Reader) Read(b []byte) (n int, err error) {
 
 // Safe to call with or without client lock.
 func (r *Reader) torrentClosed() bool {
-       return r.t.torrent.isClosed()
+       return r.t.isClosed()
 }
 
 // Wait until some data should be available to read. Tickles the client if it
@@ -134,7 +134,7 @@ func (r *Reader) waitAvailable(pos, wanted int64) (avail int64) {
 
 // Performs at most one successful read to torrent storage.
 func (r *Reader) readOnceAt(b []byte, pos int64) (n int, err error) {
-       if pos >= r.t.torrent.length {
+       if pos >= r.t.length {
                err = io.EOF
                return
        }
@@ -151,15 +151,15 @@ func (r *Reader) readOnceAt(b []byte, pos int64) (n int, err error) {
                ip := r.t.Info().Piece(pi)
                po := pos % ip.Length()
                missinggo.LimitLen(&b1, ip.Length()-po)
-               n, err = r.t.torrent.readAt(b1, pos)
+               n, err = r.t.readAt(b1, pos)
                if n != 0 {
                        err = nil
                        return
                }
                // log.Printf("%s: error reading from torrent storage pos=%d: %s", r.t, pos, err)
                r.t.cl.mu.Lock()
-               r.t.torrent.updateAllPieceCompletions()
-               r.t.torrent.updatePiecePriorities()
+               r.t.updateAllPieceCompletions()
+               r.t.updatePiecePriorities()
                r.t.cl.mu.Unlock()
        }
 }
@@ -173,7 +173,7 @@ func (r *Reader) Close() error {
 func (r *Reader) posChanged() {
        r.t.cl.mu.Lock()
        defer r.t.cl.mu.Unlock()
-       r.t.torrent.readersChanged()
+       r.t.readersChanged()
 }
 
 func (r *Reader) Seek(off int64, whence int) (ret int64, err error) {
@@ -187,7 +187,7 @@ func (r *Reader) Seek(off int64, whence int) (ret int64, err error) {
        case os.SEEK_CUR:
                r.pos += off
        case os.SEEK_END:
-               r.pos = r.t.torrent.info.TotalLength() + off
+               r.pos = r.t.info.TotalLength() + off
        default:
                err = errors.New("bad whence")
        }
diff --git a/t.go b/t.go
index 7cd28ab65ce738e6083e8a2403b74cd1549be071..fffdb858f249f70327459435e26e30c1b20c2150 100644 (file)
--- a/t.go
+++ b/t.go
@@ -6,38 +6,29 @@ import (
        "github.com/anacrolix/torrent/metainfo"
 )
 
-// This file contains Torrent, until I decide where the private, lower-case
-// "torrent" type belongs. That type is currently mostly in torrent.go.
-
-// The public handle to a live torrent within a Client.
-type Torrent struct {
-       cl      *Client
-       torrent *torrent
-}
-
 // The torrent's infohash. This is fixed and cannot change. It uniquely
 // identifies a torrent.
-func (t Torrent) InfoHash() metainfo.InfoHash {
-       return t.torrent.InfoHash
+func (t *Torrent) InfoHash() metainfo.InfoHash {
+       return t.infoHash
 }
 
 // Closed when the info (.Info()) for the torrent has become available. Using
 // features of Torrent that require the info before it is available will have
 // undefined behaviour.
-func (t Torrent) GotInfo() <-chan struct{} {
-       return t.torrent.gotMetainfo
+func (t *Torrent) GotInfo() <-chan struct{} {
+       return t.gotMetainfo
 }
 
 // Returns the metainfo info dictionary, or nil if it's not yet available.
-func (t Torrent) Info() *metainfo.InfoEx {
-       return t.torrent.info
+func (t *Torrent) Info() *metainfo.InfoEx {
+       return t.info
 }
 
 // Returns a Reader bound to the torrent's data. All read calls block until
 // the data requested is actually available.
-func (t Torrent) NewReader() (ret *Reader) {
+func (t *Torrent) NewReader() (ret *Reader) {
        ret = &Reader{
-               t:         &t,
+               t:         t,
                readahead: 5 * 1024 * 1024,
        }
        t.addReader(ret)
@@ -47,72 +38,72 @@ func (t Torrent) NewReader() (ret *Reader) {
 // Returns the state of pieces of the torrent. They are grouped into runs of
 // same state. The sum of the state run lengths is the number of pieces
 // in the torrent.
-func (t Torrent) PieceStateRuns() []PieceStateRun {
+func (t *Torrent) PieceStateRuns() []PieceStateRun {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       return t.torrent.pieceStateRuns()
+       return t.pieceStateRuns()
 }
 
-func (t Torrent) PieceState(piece int) PieceState {
+func (t *Torrent) PieceState(piece int) PieceState {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       return t.torrent.pieceState(piece)
+       return t.pieceState(piece)
 }
 
 // The number of pieces in the torrent. This requires that the info has been
 // obtained first.
-func (t Torrent) NumPieces() int {
-       return t.torrent.numPieces()
+func (t *Torrent) NumPieces() int {
+       return t.numPieces()
 }
 
 // Drop the torrent from the client, and close it.
-func (t Torrent) Drop() {
+func (t *Torrent) Drop() {
        t.cl.mu.Lock()
-       t.cl.dropTorrent(t.torrent.InfoHash)
+       t.cl.dropTorrent(t.infoHash)
        t.cl.mu.Unlock()
 }
 
 // Number of bytes of the entire torrent we have completed.
-func (t Torrent) BytesCompleted() int64 {
+func (t *Torrent) BytesCompleted() int64 {
        t.cl.mu.RLock()
        defer t.cl.mu.RUnlock()
-       return t.torrent.bytesCompleted()
+       return t.bytesCompleted()
 }
 
 // The subscription emits as (int) the index of pieces as their state changes.
 // A state change is when the PieceState for a piece alters in value.
-func (t Torrent) SubscribePieceStateChanges() *pubsub.Subscription {
-       return t.torrent.pieceStateChanges.Subscribe()
+func (t *Torrent) SubscribePieceStateChanges() *pubsub.Subscription {
+       return t.pieceStateChanges.Subscribe()
 }
 
 // Returns true if the torrent is currently being seeded. This occurs when the
 // client is willing to upload without wanting anything in return.
-func (t Torrent) Seeding() bool {
+func (t *Torrent) Seeding() bool {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       return t.cl.seeding(t.torrent)
+       return t.cl.seeding(t)
 }
 
 // Clobbers the torrent display name. The display name is used as the torrent
 // name if the metainfo is not available.
-func (t Torrent) SetDisplayName(dn string) {
+func (t *Torrent) SetDisplayName(dn string) {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       t.torrent.setDisplayName(dn)
+       t.setDisplayName(dn)
 }
 
 // The current working name for the torrent. Either the name in the info dict,
 // or a display name given such as by the dn value in a magnet link, or "".
-func (t Torrent) Name() string {
+func (t *Torrent) Name() string {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       return t.torrent.Name()
+       return t.name()
 }
 
-func (t Torrent) Length() int64 {
+func (t *Torrent) Length() int64 {
        select {
        case <-t.GotInfo():
-               return t.torrent.length
+               return t.length
        default:
                return -1
        }
@@ -120,41 +111,37 @@ func (t Torrent) Length() int64 {
 
 // Returns a run-time generated metainfo for the torrent that includes the
 // info bytes and announce-list as currently known to the client.
-func (t Torrent) MetaInfo() *metainfo.MetaInfo {
+func (t *Torrent) Metainfo() *metainfo.MetaInfo {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       return t.torrent.MetaInfo()
+       return t.metainfo()
 }
 
-func (t Torrent) addReader(r *Reader) {
+func (t *Torrent) addReader(r *Reader) {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       if t.torrent.readers == nil {
-               t.torrent.readers = make(map[*Reader]struct{})
+       if t.readers == nil {
+               t.readers = make(map[*Reader]struct{})
        }
-       t.torrent.readers[r] = struct{}{}
-       t.torrent.readersChanged()
+       t.readers[r] = struct{}{}
+       t.readersChanged()
 }
 
-func (t Torrent) deleteReader(r *Reader) {
+func (t *Torrent) deleteReader(r *Reader) {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       delete(t.torrent.readers, r)
-       t.torrent.readersChanged()
+       delete(t.readers, r)
+       t.readersChanged()
 }
 
-func (t Torrent) DownloadPieces(begin, end int) {
+func (t *Torrent) DownloadPieces(begin, end int) {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       t.torrent.pendPieceRange(begin, end)
+       t.pendPieceRange(begin, end)
 }
 
-func (t Torrent) CancelPieces(begin, end int) {
+func (t *Torrent) CancelPieces(begin, end int) {
        t.cl.mu.Lock()
        defer t.cl.mu.Unlock()
-       t.torrent.unpendPieceRange(begin, end)
-}
-
-func (t Torrent) String() string {
-       return t.torrent.String()
+       t.unpendPieceRange(begin, end)
 }
index 3fd2e63c6c54b1f0c71e325744fa765a79a3280e..790be4d5c870af336fd473ec73d4b19fabaf4721 100644 (file)
@@ -26,7 +26,7 @@ import (
        "github.com/anacrolix/torrent/storage"
 )
 
-func (t *torrent) chunkIndexSpec(chunkIndex, piece int) chunkSpec {
+func (t *Torrent) chunkIndexSpec(chunkIndex, piece int) chunkSpec {
        return chunkIndexSpec(chunkIndex, t.pieceLength(piece), t.chunkSize)
 }
 
@@ -36,7 +36,7 @@ type peersKey struct {
 }
 
 // Maintains state of torrent within a Client.
-type torrent struct {
+type Torrent struct {
        cl *Client
 
        closing chan struct{}
@@ -45,7 +45,7 @@ type torrent struct {
        // announcing, and communicating with peers.
        ceasingNetworking chan struct{}
 
-       InfoHash metainfo.InfoHash
+       infoHash metainfo.InfoHash
        pieces   []piece
        // Values are the piece indices that changed.
        pieceStateChanges *pubsub.PubSub
@@ -101,19 +101,19 @@ var (
        pieceInclinationsPut    = expvar.NewInt("pieceInclinationsPut")
 )
 
-func (t *torrent) setDisplayName(dn string) {
+func (t *Torrent) setDisplayName(dn string) {
        t.displayName = dn
 }
 
-func (t *torrent) pieceComplete(piece int) bool {
+func (t *Torrent) pieceComplete(piece int) bool {
        return t.completedPieces.Get(piece)
 }
 
-func (t *torrent) pieceCompleteUncached(piece int) bool {
+func (t *Torrent) pieceCompleteUncached(piece int) bool {
        return t.pieces[piece].Storage().GetIsComplete()
 }
 
-func (t *torrent) numConnsUnchoked() (num int) {
+func (t *Torrent) numConnsUnchoked() (num int) {
        for _, c := range t.conns {
                if !c.PeerChoked {
                        num++
@@ -123,7 +123,7 @@ func (t *torrent) numConnsUnchoked() (num int) {
 }
 
 // There's a connection to that address already.
-func (t *torrent) addrActive(addr string) bool {
+func (t *Torrent) addrActive(addr string) bool {
        if _, ok := t.halfOpen[addr]; ok {
                return true
        }
@@ -135,7 +135,7 @@ func (t *torrent) addrActive(addr string) bool {
        return false
 }
 
-func (t *torrent) worstConns(cl *Client) (wcs *worstConns) {
+func (t *Torrent) worstConns(cl *Client) (wcs *worstConns) {
        wcs = &worstConns{
                c:  make([]*connection, 0, len(t.conns)),
                t:  t,
@@ -149,7 +149,7 @@ func (t *torrent) worstConns(cl *Client) (wcs *worstConns) {
        return
 }
 
-func (t *torrent) ceaseNetworking() {
+func (t *Torrent) ceaseNetworking() {
        select {
        case <-t.ceasingNetworking:
                return
@@ -161,7 +161,7 @@ func (t *torrent) ceaseNetworking() {
        }
 }
 
-func (t *torrent) addPeer(p Peer, cl *Client) {
+func (t *Torrent) addPeer(p Peer, cl *Client) {
        cl.openNewConns(t)
        if len(t.peers) >= torrentPeersHighWater {
                return
@@ -176,13 +176,13 @@ func (t *torrent) addPeer(p Peer, cl *Client) {
 
 }
 
-func (t *torrent) invalidateMetadata() {
+func (t *Torrent) invalidateMetadata() {
        t.metadataBytes = nil
        t.metadataCompletedChunks = nil
        t.info = nil
 }
 
-func (t *torrent) saveMetadataPiece(index int, data []byte) {
+func (t *Torrent) saveMetadataPiece(index int, data []byte) {
        if t.haveInfo() {
                return
        }
@@ -194,11 +194,11 @@ func (t *torrent) saveMetadataPiece(index int, data []byte) {
        t.metadataCompletedChunks[index] = true
 }
 
-func (t *torrent) metadataPieceCount() int {
+func (t *Torrent) metadataPieceCount() int {
        return (len(t.metadataBytes) + (1 << 14) - 1) / (1 << 14)
 }
 
-func (t *torrent) haveMetadataPiece(piece int) bool {
+func (t *Torrent) haveMetadataPiece(piece int) bool {
        if t.haveInfo() {
                return (1<<14)*piece < len(t.metadataBytes)
        } else {
@@ -206,11 +206,11 @@ func (t *torrent) haveMetadataPiece(piece int) bool {
        }
 }
 
-func (t *torrent) metadataSizeKnown() bool {
+func (t *Torrent) metadataSizeKnown() bool {
        return t.metadataBytes != nil
 }
 
-func (t *torrent) metadataSize() int {
+func (t *Torrent) metadataSize() int {
        return len(t.metadataBytes)
 }
 
@@ -222,7 +222,7 @@ func infoPieceHashes(info *metainfo.Info) (ret []string) {
 }
 
 // Called when metadata for a torrent becomes available.
-func (t *torrent) setMetadata(md *metainfo.Info, infoBytes []byte) (err error) {
+func (t *Torrent) setMetadata(md *metainfo.Info, infoBytes []byte) (err error) {
        err = validateInfo(md)
        if err != nil {
                err = fmt.Errorf("bad info: %s", err)
@@ -231,7 +231,7 @@ func (t *torrent) setMetadata(md *metainfo.Info, infoBytes []byte) (err error) {
        t.info = &metainfo.InfoEx{
                Info:  *md,
                Bytes: infoBytes,
-               Hash:  &t.InfoHash,
+               Hash:  &t.infoHash,
        }
        t.storage, err = t.storageOpener.OpenTorrent(t.info)
        if err != nil {
@@ -270,11 +270,11 @@ func (t *torrent) setMetadata(md *metainfo.Info, infoBytes []byte) (err error) {
        return
 }
 
-func (t *torrent) verifyPiece(piece int) {
+func (t *Torrent) verifyPiece(piece int) {
        t.cl.verifyPiece(t, piece)
 }
 
-func (t *torrent) haveAllMetadataPieces() bool {
+func (t *Torrent) haveAllMetadataPieces() bool {
        if t.haveInfo() {
                return true
        }
@@ -289,7 +289,7 @@ func (t *torrent) haveAllMetadataPieces() bool {
        return true
 }
 
-func (t *torrent) setMetadataSize(bytes int64, cl *Client) {
+func (t *Torrent) setMetadataSize(bytes int64, cl *Client) {
        if t.haveInfo() {
                // We already know the correct metadata size.
                return
@@ -311,14 +311,14 @@ func (t *torrent) setMetadataSize(bytes int64, cl *Client) {
 
 // The current working name for the torrent. Either the name in the info dict,
 // or a display name given such as by the dn value in a magnet link, or "".
-func (t *torrent) Name() string {
+func (t *Torrent) name() string {
        if t.haveInfo() {
                return t.info.Name
        }
        return t.displayName
 }
 
-func (t *torrent) pieceState(index int) (ret PieceState) {
+func (t *Torrent) pieceState(index int) (ret PieceState) {
        p := &t.pieces[index]
        ret.Priority = t.piecePriority(index)
        if t.pieceComplete(index) {
@@ -333,11 +333,11 @@ func (t *torrent) pieceState(index int) (ret PieceState) {
        return
 }
 
-func (t *torrent) metadataPieceSize(piece int) int {
+func (t *Torrent) metadataPieceSize(piece int) int {
        return metadataPieceSize(len(t.metadataBytes), piece)
 }
 
-func (t *torrent) newMetadataExtensionMessage(c *connection, msgType int, piece int, data []byte) pp.Message {
+func (t *Torrent) newMetadataExtensionMessage(c *connection, msgType int, piece int, data []byte) pp.Message {
        d := map[string]int{
                "msg_type": msgType,
                "piece":    piece,
@@ -356,7 +356,7 @@ func (t *torrent) newMetadataExtensionMessage(c *connection, msgType int, piece
        }
 }
 
-func (t *torrent) pieceStateRuns() (ret []PieceStateRun) {
+func (t *Torrent) pieceStateRuns() (ret []PieceStateRun) {
        rle := missinggo.NewRunLengthEncoder(func(el interface{}, count uint64) {
                ret = append(ret, PieceStateRun{
                        PieceState: el.(PieceState),
@@ -399,8 +399,8 @@ func pieceStateRunStatusChars(psr PieceStateRun) (ret string) {
        return
 }
 
-func (t *torrent) writeStatus(w io.Writer, cl *Client) {
-       fmt.Fprintf(w, "Infohash: %x\n", t.InfoHash)
+func (t *Torrent) writeStatus(w io.Writer, cl *Client) {
+       fmt.Fprintf(w, "Infohash: %x\n", t.infoHash)
        fmt.Fprintf(w, "Metadata length: %d\n", t.metadataSize())
        if !t.haveInfo() {
                fmt.Fprintf(w, "Metadata have: ")
@@ -458,27 +458,27 @@ func (t *torrent) writeStatus(w io.Writer, cl *Client) {
        }
 }
 
-func (t *torrent) String() string {
+func (t *Torrent) String() string {
        s := t.Name()
        if s == "" {
-               s = fmt.Sprintf("%x", t.InfoHash)
+               s = fmt.Sprintf("%x", t.infoHash)
        }
        return s
 }
 
-func (t *torrent) haveInfo() bool {
+func (t *Torrent) haveInfo() bool {
        return t.info != nil
 }
 
 // TODO: Include URIs that weren't converted to tracker clients.
-func (t *torrent) announceList() (al [][]string) {
+func (t *Torrent) announceList() (al [][]string) {
        missinggo.CastSlice(&al, t.trackers)
        return
 }
 
 // Returns a run-time generated MetaInfo that includes the info bytes and
 // announce-list as currently known to the client.
-func (t *torrent) MetaInfo() *metainfo.MetaInfo {
+func (t *Torrent) metainfo() *metainfo.MetaInfo {
        if t.metadataBytes == nil {
                panic("info bytes not set")
        }
@@ -491,7 +491,7 @@ func (t *torrent) MetaInfo() *metainfo.MetaInfo {
        }
 }
 
-func (t *torrent) bytesLeft() (left int64) {
+func (t *Torrent) bytesLeft() (left int64) {
        for i := 0; i < t.numPieces(); i++ {
                left += int64(t.pieces[i].bytesLeft())
        }
@@ -499,7 +499,7 @@ func (t *torrent) bytesLeft() (left int64) {
 }
 
 // Bytes left to give in tracker announces.
-func (t *torrent) bytesLeftAnnounce() uint64 {
+func (t *Torrent) bytesLeftAnnounce() uint64 {
        if t.haveInfo() {
                return uint64(t.bytesLeft())
        } else {
@@ -507,7 +507,7 @@ func (t *torrent) bytesLeftAnnounce() uint64 {
        }
 }
 
-func (t *torrent) piecePartiallyDownloaded(piece int) bool {
+func (t *Torrent) piecePartiallyDownloaded(piece int) bool {
        if t.pieceComplete(piece) {
                return false
        }
@@ -521,24 +521,24 @@ func numChunksForPiece(chunkSize int, pieceSize int) int {
        return (pieceSize + chunkSize - 1) / chunkSize
 }
 
-func (t *torrent) usualPieceSize() int {
+func (t *Torrent) usualPieceSize() int {
        return int(t.info.PieceLength)
 }
 
-func (t *torrent) lastPieceSize() int {
+func (t *Torrent) lastPieceSize() int {
        return int(t.pieceLength(t.numPieces() - 1))
 }
 
-func (t *torrent) numPieces() int {
+func (t *Torrent) numPieces() int {
        return t.info.NumPieces()
 }
 
-func (t *torrent) numPiecesCompleted() (num int) {
+func (t *Torrent) numPiecesCompleted() (num int) {
        return t.completedPieces.Len()
 }
 
 // Safe to call with or without client lock.
-func (t *torrent) isClosed() bool {
+func (t *Torrent) isClosed() bool {
        select {
        case <-t.closing:
                return true
@@ -547,7 +547,7 @@ func (t *torrent) isClosed() bool {
        }
 }
 
-func (t *torrent) close() (err error) {
+func (t *Torrent) close() (err error) {
        if t.isClosed() {
                return
        }
@@ -563,17 +563,17 @@ func (t *torrent) close() (err error) {
        return
 }
 
-func (t *torrent) requestOffset(r request) int64 {
+func (t *Torrent) requestOffset(r request) int64 {
        return torrentRequestOffset(t.length, int64(t.usualPieceSize()), r)
 }
 
 // Return the request that would include the given offset into the torrent
 // data. Returns !ok if there is no such request.
-func (t *torrent) offsetRequest(off int64) (req request, ok bool) {
+func (t *Torrent) offsetRequest(off int64) (req request, ok bool) {
        return torrentOffsetRequest(t.length, t.info.PieceLength, int64(t.chunkSize), off)
 }
 
-func (t *torrent) writeChunk(piece int, begin int64, data []byte) (err error) {
+func (t *Torrent) writeChunk(piece int, begin int64, data []byte) (err error) {
        tr := perf.NewTimer()
 
        n, err := t.pieces[piece].Storage().WriteAt(data, begin)
@@ -586,7 +586,7 @@ func (t *torrent) writeChunk(piece int, begin int64, data []byte) (err error) {
        return
 }
 
-func (t *torrent) bitfield() (bf []bool) {
+func (t *Torrent) bitfield() (bf []bool) {
        bf = make([]bool, t.numPieces())
        t.completedPieces.IterTyped(func(piece int) (again bool) {
                bf[piece] = true
@@ -595,7 +595,7 @@ func (t *torrent) bitfield() (bf []bool) {
        return
 }
 
-func (t *torrent) validOutgoingRequest(r request) bool {
+func (t *Torrent) validOutgoingRequest(r request) bool {
        if r.Index >= pp.Integer(t.info.NumPieces()) {
                return false
        }
@@ -612,7 +612,7 @@ func (t *torrent) validOutgoingRequest(r request) bool {
        return r.Length == t.chunkSize || r.Begin+r.Length == pieceLength
 }
 
-func (t *torrent) pieceChunks(piece int) (css []chunkSpec) {
+func (t *Torrent) pieceChunks(piece int) (css []chunkSpec) {
        css = make([]chunkSpec, 0, (t.pieceLength(piece)+t.chunkSize-1)/t.chunkSize)
        var cs chunkSpec
        for left := t.pieceLength(piece); left != 0; left -= cs.Length {
@@ -626,11 +626,11 @@ func (t *torrent) pieceChunks(piece int) (css []chunkSpec) {
        return
 }
 
-func (t *torrent) pieceNumChunks(piece int) int {
+func (t *Torrent) pieceNumChunks(piece int) int {
        return int((t.pieceLength(piece) + t.chunkSize - 1) / t.chunkSize)
 }
 
-func (t *torrent) pendAllChunkSpecs(pieceIndex int) {
+func (t *Torrent) pendAllChunkSpecs(pieceIndex int) {
        t.pieces[pieceIndex].DirtyChunks.Clear()
 }
 
@@ -643,7 +643,7 @@ type Peer struct {
        SupportsEncryption bool
 }
 
-func (t *torrent) pieceLength(piece int) (len_ pp.Integer) {
+func (t *Torrent) pieceLength(piece int) (len_ pp.Integer) {
        if piece < 0 || piece >= t.info.NumPieces() {
                return
        }
@@ -656,7 +656,7 @@ func (t *torrent) pieceLength(piece int) (len_ pp.Integer) {
        return
 }
 
-func (t *torrent) hashPiece(piece int) (ret pieceSum) {
+func (t *Torrent) hashPiece(piece int) (ret pieceSum) {
        hash := pieceHash.New()
        p := &t.pieces[piece]
        p.waitNoPendingWrites()
@@ -673,14 +673,14 @@ func (t *torrent) hashPiece(piece int) (ret pieceSum) {
        return
 }
 
-func (t *torrent) haveAllPieces() bool {
+func (t *Torrent) haveAllPieces() bool {
        if !t.haveInfo() {
                return false
        }
        return t.completedPieces.Len() == t.numPieces()
 }
 
-func (me *torrent) haveAnyPieces() bool {
+func (me *Torrent) haveAnyPieces() bool {
        for i := range me.pieces {
                if me.pieceComplete(i) {
                        return true
@@ -689,11 +689,11 @@ func (me *torrent) haveAnyPieces() bool {
        return false
 }
 
-func (t *torrent) havePiece(index int) bool {
+func (t *Torrent) havePiece(index int) bool {
        return t.haveInfo() && t.pieceComplete(index)
 }
 
-func (t *torrent) haveChunk(r request) (ret bool) {
+func (t *Torrent) haveChunk(r request) (ret bool) {
        // defer func() {
        //      log.Println("have chunk", r, ret)
        // }()
@@ -712,7 +712,7 @@ func chunkIndex(cs chunkSpec, chunkSize pp.Integer) int {
 }
 
 // TODO: This should probably be called wantPiece.
-func (t *torrent) wantChunk(r request) bool {
+func (t *Torrent) wantChunk(r request) bool {
        if !t.wantPiece(int(r.Index)) {
                return false
        }
@@ -725,7 +725,7 @@ func (t *torrent) wantChunk(r request) bool {
 }
 
 // TODO: This should be called wantPieceIndex.
-func (t *torrent) wantPiece(index int) bool {
+func (t *Torrent) wantPiece(index int) bool {
        if !t.haveInfo() {
                return false
        }
@@ -747,7 +747,7 @@ func (t *torrent) wantPiece(index int) bool {
        })
 }
 
-func (t *torrent) forNeededPieces(f func(piece int) (more bool)) (all bool) {
+func (t *Torrent) forNeededPieces(f func(piece int) (more bool)) (all bool) {
        return t.forReaderOffsetPieces(func(begin, end int) (more bool) {
                for i := begin; begin < end; i++ {
                        if !f(i) {
@@ -758,18 +758,18 @@ func (t *torrent) forNeededPieces(f func(piece int) (more bool)) (all bool) {
        })
 }
 
-func (t *torrent) connHasWantedPieces(c *connection) bool {
+func (t *Torrent) connHasWantedPieces(c *connection) bool {
        return !c.pieceRequestOrder.IsEmpty()
 }
 
-func (t *torrent) extentPieces(off, _len int64) (pieces []int) {
+func (t *Torrent) extentPieces(off, _len int64) (pieces []int) {
        for i := off / int64(t.usualPieceSize()); i*int64(t.usualPieceSize()) < off+_len; i++ {
                pieces = append(pieces, int(i))
        }
        return
 }
 
-func (t *torrent) worstBadConn(cl *Client) *connection {
+func (t *Torrent) worstBadConn(cl *Client) *connection {
        wcs := t.worstConns(cl)
        heap.Init(wcs)
        for wcs.Len() != 0 {
@@ -792,7 +792,7 @@ type PieceStateChange struct {
        PieceState
 }
 
-func (t *torrent) publishPieceChange(piece int) {
+func (t *Torrent) publishPieceChange(piece int) {
        cur := t.pieceState(piece)
        p := &t.pieces[piece]
        if cur != p.PublicPieceState {
@@ -804,18 +804,18 @@ func (t *torrent) publishPieceChange(piece int) {
        }
 }
 
-func (t *torrent) pieceNumPendingChunks(piece int) int {
+func (t *Torrent) pieceNumPendingChunks(piece int) int {
        if t.pieceComplete(piece) {
                return 0
        }
        return t.pieceNumChunks(piece) - t.pieces[piece].numDirtyChunks()
 }
 
-func (t *torrent) pieceAllDirty(piece int) bool {
+func (t *Torrent) pieceAllDirty(piece int) bool {
        return t.pieces[piece].DirtyChunks.Len() == t.pieceNumChunks(piece)
 }
 
-func (t *torrent) forUrgentPieces(f func(piece int) (again bool)) (all bool) {
+func (t *Torrent) forUrgentPieces(f func(piece int) (again bool)) (all bool) {
        return t.forReaderOffsetPieces(func(begin, end int) (again bool) {
                if begin < end {
                        if !f(begin) {
@@ -826,17 +826,17 @@ func (t *torrent) forUrgentPieces(f func(piece int) (again bool)) (all bool) {
        })
 }
 
-func (t *torrent) readersChanged() {
+func (t *Torrent) readersChanged() {
        t.updatePiecePriorities()
 }
 
-func (t *torrent) maybeNewConns() {
+func (t *Torrent) maybeNewConns() {
        // Tickle the accept routine.
        t.cl.event.Broadcast()
        t.openNewConns()
 }
 
-func (t *torrent) piecePriorityChanged(piece int) {
+func (t *Torrent) piecePriorityChanged(piece int) {
        for _, c := range t.conns {
                c.updatePiecePriority(piece)
        }
@@ -844,7 +844,7 @@ func (t *torrent) piecePriorityChanged(piece int) {
        t.publishPieceChange(piece)
 }
 
-func (t *torrent) updatePiecePriority(piece int) bool {
+func (t *Torrent) updatePiecePriority(piece int) bool {
        p := &t.pieces[piece]
        newPrio := t.piecePriorityUncached(piece)
        if newPrio == p.priority {
@@ -856,7 +856,7 @@ func (t *torrent) updatePiecePriority(piece int) bool {
 
 // Update all piece priorities in one hit. This function should have the same
 // output as updatePiecePriority, but across all pieces.
-func (t *torrent) updatePiecePriorities() {
+func (t *Torrent) updatePiecePriorities() {
        newPrios := make([]piecePriority, t.numPieces())
        t.pendingPieces.IterTyped(func(piece int) (more bool) {
                newPrios[piece] = PiecePriorityNormal
@@ -883,7 +883,7 @@ func (t *torrent) updatePiecePriorities() {
        }
 }
 
-func (t *torrent) byteRegionPieces(off, size int64) (begin, end int) {
+func (t *Torrent) byteRegionPieces(off, size int64) (begin, end int) {
        if off >= t.length {
                return
        }
@@ -903,7 +903,7 @@ func (t *torrent) byteRegionPieces(off, size int64) (begin, end int) {
 }
 
 // Returns true if all iterations complete without breaking.
-func (t *torrent) forReaderOffsetPieces(f func(begin, end int) (more bool)) (all bool) {
+func (t *Torrent) forReaderOffsetPieces(f func(begin, end int) (more bool)) (all bool) {
        // There's an oppurtunity here to build a map of beginning pieces, and a
        // bitmap of the rest. I wonder if it's worth the allocation overhead.
        for r := range t.readers {
@@ -924,14 +924,14 @@ func (t *torrent) forReaderOffsetPieces(f func(begin, end int) (more bool)) (all
        return true
 }
 
-func (t *torrent) piecePriority(piece int) piecePriority {
+func (t *Torrent) piecePriority(piece int) piecePriority {
        if !t.haveInfo() {
                return PiecePriorityNone
        }
        return t.pieces[piece].priority
 }
 
-func (t *torrent) piecePriorityUncached(piece int) (ret piecePriority) {
+func (t *Torrent) piecePriorityUncached(piece int) (ret piecePriority) {
        ret = PiecePriorityNone
        if t.pieceComplete(piece) {
                return
@@ -952,7 +952,7 @@ func (t *torrent) piecePriorityUncached(piece int) (ret piecePriority) {
        return
 }
 
-func (t *torrent) pendPiece(piece int) {
+func (t *Torrent) pendPiece(piece int) {
        if t.pendingPieces.Contains(piece) {
                return
        }
@@ -966,28 +966,28 @@ func (t *torrent) pendPiece(piece int) {
        t.piecePriorityChanged(piece)
 }
 
-func (t *torrent) getCompletedPieces() (ret bitmap.Bitmap) {
+func (t *Torrent) getCompletedPieces() (ret bitmap.Bitmap) {
        return t.completedPieces.Copy()
 }
 
-func (t *torrent) unpendPieces(unpend *bitmap.Bitmap) {
+func (t *Torrent) unpendPieces(unpend *bitmap.Bitmap) {
        t.pendingPieces.Sub(unpend)
        t.updatePiecePriorities()
 }
 
-func (t *torrent) pendPieceRange(begin, end int) {
+func (t *Torrent) pendPieceRange(begin, end int) {
        for i := begin; i < end; i++ {
                t.pendPiece(i)
        }
 }
 
-func (t *torrent) unpendPieceRange(begin, end int) {
+func (t *Torrent) unpendPieceRange(begin, end int) {
        var bm bitmap.Bitmap
        bm.AddRange(begin, end)
        t.unpendPieces(&bm)
 }
 
-func (t *torrent) connRequestPiecePendingChunks(c *connection, piece int) (more bool) {
+func (t *Torrent) connRequestPiecePendingChunks(c *connection, piece int) (more bool) {
        if !c.PeerHasPiece(piece) {
                return true
        }
@@ -998,20 +998,20 @@ func (t *torrent) connRequestPiecePendingChunks(c *connection, piece int) (more
        })
 }
 
-func (t *torrent) pendRequest(req request) {
+func (t *Torrent) pendRequest(req request) {
        ci := chunkIndex(req.chunkSpec, t.chunkSize)
        t.pieces[req.Index].pendChunkIndex(ci)
 }
 
-func (t *torrent) pieceChanged(piece int) {
+func (t *Torrent) pieceChanged(piece int) {
        t.cl.pieceChanged(t, piece)
 }
 
-func (t *torrent) openNewConns() {
+func (t *Torrent) openNewConns() {
        t.cl.openNewConns(t)
 }
 
-func (t *torrent) getConnPieceInclination() []int {
+func (t *Torrent) getConnPieceInclination() []int {
        _ret := t.connPieceInclinationPool.Get()
        if _ret == nil {
                pieceInclinationsNew.Add(1)
@@ -1021,12 +1021,12 @@ func (t *torrent) getConnPieceInclination() []int {
        return _ret.([]int)
 }
 
-func (t *torrent) putPieceInclination(pi []int) {
+func (t *Torrent) putPieceInclination(pi []int) {
        t.connPieceInclinationPool.Put(pi)
        pieceInclinationsPut.Add(1)
 }
 
-func (t *torrent) updatePieceCompletion(piece int) {
+func (t *Torrent) updatePieceCompletion(piece int) {
        pcu := t.pieceCompleteUncached(piece)
        changed := t.completedPieces.Get(piece) != pcu
        t.completedPieces.Set(piece, pcu)
@@ -1036,13 +1036,13 @@ func (t *torrent) updatePieceCompletion(piece int) {
 }
 
 // Non-blocking read. Client lock is not required.
-func (t *torrent) readAt(b []byte, off int64) (n int, err error) {
+func (t *Torrent) readAt(b []byte, off int64) (n int, err error) {
        p := &t.pieces[off/t.info.PieceLength]
        p.waitNoPendingWrites()
        return p.Storage().ReadAt(b, off-p.Info().Offset())
 }
 
-func (t *torrent) updateAllPieceCompletions() {
+func (t *Torrent) updateAllPieceCompletions() {
        for i := range iter.N(t.numPieces()) {
                t.updatePieceCompletion(i)
        }
index bca6f775f10bba480af15bea6d5c2d1b068d910b..6ffc860549fbc357658770582dd7e224e9be7831 100644 (file)
@@ -52,8 +52,8 @@ func TestAppendToCopySlice(t *testing.T) {
 }
 
 func TestTorrentString(t *testing.T) {
-       tor := &torrent{}
-       s := tor.InfoHash.HexString()
+       tor := &Torrent{}
+       s := tor.InfoHash().HexString()
        if s != "0000000000000000000000000000000000000000" {
                t.FailNow()
        }
index 0f7aa3aa7842b2c5190b259067b8b08fba7f7716..7b9c5a916a0322d72f92f841e15778ab8d18bffc 100644 (file)
@@ -7,7 +7,7 @@ import (
 // Implements heap functions such that [0] is the worst connection.
 type worstConns struct {
        c  []*connection
-       t  *torrent
+       t  *Torrent
        cl *Client
 }