// Performs at most one successful read to torrent storage. func (r *Reader) readOnceAt(b []byte, pos int64, ctxErr *error) (n int, err error) { if pos >= r.t.length { err = io.EOF return } for { avail := r.waitAvailable(pos, int64(len(b)), ctxErr) if avail == 0 { if r.t.closed.IsSet() { err = errors.New("torrent closed") return } if *ctxErr != nil { err = *ctxErr return } } b1 := b[:avail] pi := int(pos / r.t.Info().PieceLength) ip := r.t.Info().Piece(pi) po := pos % ip.Length() missinggo.LimitLen(&b1, ip.Length()-po) 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.updateAllPieceCompletions() r.t.updatePiecePriorities() r.t.cl.mu.Unlock() } }
func (me pieceFileTorrentStoragePiece) WriteAt(b []byte, off int64) (n int, err error) { if me.GetIsComplete() { err = errors.New("piece completed") return } f, err := me.fs.OpenFile(me.incompletePath(), os.O_WRONLY|os.O_CREATE) if err != nil { return } defer f.Close() missinggo.LimitLen(&b, me.p.Length()-off) return f.WriteAt(b, off) }
func (s piecePerResourcePiece) ReadAt(b []byte, off int64) (n int, err error) { missinggo.LimitLen(&b, s.p.Length()-off) n, err = s.c.ReadAt(b, off) if err != nil { n, err = s.i.ReadAt(b, off) } off += int64(n) if off >= s.p.Length() { err = io.EOF } else if err == io.EOF { err = io.ErrUnexpectedEOF } return }
func (me pieceFileTorrentStoragePiece) ReadAt(b []byte, off int64) (n int, err error) { f, err := me.openFile() if err != nil { return } defer f.Close() missinggo.LimitLen(&b, me.p.Length()-off) n, err = f.ReadAt(b, off) off += int64(n) if off >= me.p.Length() { err = io.EOF } else if err == io.EOF { err = io.ErrUnexpectedEOF } return }
func (s piecePerResourcePiece) WriteAt(b []byte, off int64) (n int, err error) { missinggo.LimitLen(&b, s.p.Length()-off) return s.i.WriteAt(b, off) }