func (me *store) pieceComplete(p metainfo.Piece) bool { if me.completionKnown(p) { return me.isComplete(p) } // Prevent a errors from stalling the caller. if !me.lastError.IsZero() && time.Since(me.lastError) < time.Second { return false } length, err := me.db.GetLength(me.completedPiecePath(p)) if err == dataBackend.ErrNotFound { me.setCompletion(p, false) return false } if err != nil { me.lastError = time.Now() log.Printf("%+v", err) return false } complete := length == p.Length() if !complete { log.Printf("completed piece %x has wrong length: %d", p.Hash(), length) } me.setCompletion(p, complete) return complete }
func (me *store) PieceCompleted(p metainfo.Piece) (err error) { err = me.makeSpace(p.Length()) if err != nil { return } var ( incompletePiecePath = me.path(p, false) completedPiecePath = me.path(p, true) ) fSrc, err := os.Open(incompletePiecePath) if err != nil { return } defer fSrc.Close() os.MkdirAll(filepath.Dir(completedPiecePath), dirPerm) fDst, err := os.OpenFile(completedPiecePath, os.O_EXCL|os.O_CREATE|os.O_WRONLY, filePerm) if err != nil { return } defer fDst.Close() hasher := sha1.New() r := io.TeeReader(io.LimitReader(fSrc, p.Length()), hasher) _, err = io.Copy(fDst, r) if err != nil { return } if !bytes.Equal(hasher.Sum(nil), p.Hash()) { err = errors.New("piece incomplete") os.Remove(completedPiecePath) return } os.Remove(incompletePiecePath) me.completed[sliceToPieceHashArray(p.Hash())] = struct{}{} return }
func (me *mmapTorrentStorage) Piece(p metainfo.Piece) Piece { return mmapStoragePiece{ storage: me, p: p, ReaderAt: io.NewSectionReader(me.span, p.Offset(), p.Length()), WriterAt: missinggo.NewSectionWriter(me.span, p.Offset(), p.Length()), } }
func (fts *fileTorrentStorage) Piece(p metainfo.Piece) Piece { // Create a view onto the file-based torrent storage. _io := fileStorageTorrent{fts} // Return the appropriate segments of this. return &fileStoragePiece{ fts, p, missinggo.NewSectionWriter(_io, p.Offset(), p.Length()), io.NewSectionReader(_io, p.Offset(), p.Length()), } }
func (me *fileStorage) Piece(p metainfo.Piece) Piece { _io := &fileStorageTorrent{ p.Info, me.baseDir, } return &fileStoragePiece{ me, p, missinggo.NewSectionWriter(_io, p.Offset(), p.Length()), io.NewSectionReader(_io, p.Offset(), p.Length()), } }
func (me *store) PieceCompleted(p metainfo.Piece) (err error) { hash, err := me.hashCopyFile(me.incompletePiecePath(p), me.completedPiecePath(p), p.Length()) if err == nil && !bytes.Equal(hash, p.Hash()) { err = errors.New("piece incomplete") } if err != nil { me.deleteCompleted(p) return } me.removePath(me.incompletePiecePath(p)) me.setCompletion(p, true) return }
func (me *data) pieceReader(p metainfo.Piece, off int64) (ret io.ReadCloser, err error) { return me.store.getPieceRange(p, off, p.Length()-off) }