2
0
mirror of synced 2025-02-24 14:48:27 +00:00
torrent/storage/piece_file.go

92 lines
2.0 KiB
Go
Raw Normal View History

2016-03-29 11:14:34 +11:00
package storage
import (
2016-03-29 12:13:03 +11:00
"io"
2016-03-29 11:14:34 +11:00
"os"
"path"
"github.com/anacrolix/missinggo"
"github.com/anacrolix/torrent/metainfo"
)
type pieceFileStorage struct {
fs missinggo.FileStore
2016-03-29 11:14:34 +11:00
}
func NewPieceFileStorage(fs missinggo.FileStore) I {
2016-03-29 11:14:34 +11:00
return &pieceFileStorage{
fs: fs,
}
}
type pieceFileTorrentStorage struct {
s *pieceFileStorage
}
func (me *pieceFileStorage) OpenTorrent(info *metainfo.InfoEx) (Torrent, error) {
return &pieceFileTorrentStorage{me}, nil
}
func (me *pieceFileTorrentStorage) Close() error {
return nil
}
func (me *pieceFileTorrentStorage) Piece(p metainfo.Piece) Piece {
return pieceFileTorrentStoragePiece{me, p, me.s.fs}
}
type pieceFileTorrentStoragePiece struct {
ts *pieceFileTorrentStorage
p metainfo.Piece
fs missinggo.FileStore
2016-03-29 11:14:34 +11:00
}
func (me pieceFileTorrentStoragePiece) completedPath() string {
return path.Join("completed", me.p.Hash().HexString())
}
func (me pieceFileTorrentStoragePiece) incompletePath() string {
return path.Join("incomplete", me.p.Hash().HexString())
}
func (me pieceFileTorrentStoragePiece) GetIsComplete() bool {
fi, err := me.ts.s.fs.Stat(me.completedPath())
return err == nil && fi.Size() == me.p.Length()
}
func (me pieceFileTorrentStoragePiece) MarkComplete() error {
return me.fs.Rename(me.incompletePath(), me.completedPath())
}
func (me pieceFileTorrentStoragePiece) ReadAt(b []byte, off int64) (n int, err error) {
f, err := me.fs.OpenFile(me.completedPath(), os.O_RDONLY)
if err != nil {
f, err = me.fs.OpenFile(me.incompletePath(), os.O_RDONLY)
2016-03-29 12:13:03 +11:00
if os.IsNotExist(err) {
err = io.ErrUnexpectedEOF
return
}
2016-03-29 11:14:34 +11:00
if err != nil {
return
}
}
defer f.Close()
n, err = f.ReadAt(b, off)
off += int64(n)
if err == io.EOF && off < me.p.Length() {
err = io.ErrUnexpectedEOF
}
return
2016-03-29 11:14:34 +11:00
}
func (me pieceFileTorrentStoragePiece) WriteAt(b []byte, off int64) (n int, err error) {
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)
}