func (t *Torrent) HaveAllPieces() bool {
	l := t.newLocker()
	l.lock()
	defer l.unlock()
	return t.haveAll()
}
HaveAllPieces returns whether all torrent's data has been downloaded
package torrent
import (
	"errors"
	"io"
	"strings"
	"github.com/lkslts64/charo-torrent/metainfo"
)
var errTorrentClosed = errors.New("torrent closed")
var errMetainfoNotAvailable = errors.New("metainfo not yet available")
func (t *Torrent) AddPeers(peers ...Peer) error {
	l := t.newLocker()
	if l.lock(); l.closed {
		return errTorrentClosed
	}
	defer l.unlock()
	t.gotPeers(peers)
	return nil
}
func (t *Torrent) Swarm() []Peer {
	l := t.newLocker()
	l.lock()
	defer l.unlock()
	return t.swarm()
}
func (t *Torrent) StartDataTransfer() error {
	l := t.newLocker()
	l.lock()
	defer l.unlock()
	if l.closed {
		return errTorrentClosed
	}
	if !t.haveInfo() {
		return errors.New("can't download data without having the info first")
	}
	if t.uploadEnabled || t.downloadEnabled {
		return errors.New("already downloading data or seeding")
	}
	t.uploadEnabled, t.downloadEnabled = true, true
	if !t.infoWasDownloaded() && len(t.conns) > 0 {
		panic("why have conns?")
	}
	if !t.haveAll() {
		t.pieces.setDownloadEnabled(true)
		for _, c := range t.conns {
			c.reviewInterestsOnBitfield()
		}
		t.broadcastToConns(requestsAvailable{})
	}
	t.tryAnnounceAll()
	t.dialConns()
	return nil
}
func (t *Torrent) WriteStatus(w io.Writer) {
	l := t.newLocker()
	l.lock()
	defer l.unlock()
	b := new(strings.Builder)
	t.writeStatus(b)
	w.Write([]byte(b.String()))
}
func (t *Torrent) Metainfo() *metainfo.MetaInfo {
	l := t.newLocker()
	l.lock()
	defer l.unlock()
	return t.mi
}
func (t *Torrent) Info() *metainfo.InfoDict {
	l := t.newLocker()
	l.lock()
	defer l.unlock()
	return t.mi.Info
}