7 "github.com/anacrolix/missinggo"
9 "github.com/anacrolix/torrent/metainfo"
16 func NewClient(cl ClientImpl) *Client {
20 func (cl Client) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (*Torrent, error) {
21 t, err := cl.ci.OpenTorrent(info, infoHash)
25 return &Torrent{t}, nil
32 func (t Torrent) Piece(p metainfo.Piece) Piece {
33 return Piece{t.TorrentImpl.Piece(p), p}
41 func (p Piece) WriteAt(b []byte, off int64) (n int, err error) {
42 // Callers should not be writing to completed pieces, but it's too
43 // expensive to be checking this on every single write using uncached
46 // c := p.Completion()
47 // if c.Ok && c.Complete {
48 // err = errors.New("piece already completed")
51 if off+int64(len(b)) > p.mip.Length() {
52 panic("write overflows piece")
54 b = missinggo.LimitLen(b, p.mip.Length()-off)
55 return p.PieceImpl.WriteAt(b, off)
58 func (p Piece) ReadAt(b []byte, off int64) (n int, err error) {
63 if off >= p.mip.Length() {
67 b = missinggo.LimitLen(b, p.mip.Length()-off)
71 n, err = p.PieceImpl.ReadAt(b, off)
75 if n == 0 && err == nil {
76 panic("io.Copy will get stuck")
80 // Doing this here may be inaccurate. There's legitimate reasons we may fail to read while the
81 // data is still there, such as too many open files. There should probably be a specific error
82 // to return if the data has been lost.
83 if off < p.mip.Length() {