9 "github.com/anacrolix/libtorgo/metainfo"
17 func TorrentData(info *metainfo.Info, baseDir string) *data {
18 return &data{info, baseDir}
21 func (me *data) pieceHashHex(i int) string {
22 return hex.EncodeToString(me.info.Pieces[i*20 : (i+1)*20])
25 func (me *data) Close() {}
27 func (me *data) ReadAt(p []byte, off int64) (n int, err error) {
28 hash := me.pieceHashHex(int(off / me.info.PieceLength))
29 f, err := os.Open(me.baseDir + "/complete/" + hash)
30 if os.IsNotExist(err) {
31 f, err = os.Open(me.baseDir + "/incomplete/" + hash)
32 if os.IsNotExist(err) {
39 } else if err != nil {
43 off %= me.info.PieceLength
44 return f.ReadAt(p, off)
47 func (me *data) openComplete(piece int) (f *os.File, err error) {
48 return os.OpenFile(me.baseDir+"/complete/"+me.pieceHashHex(piece), os.O_RDWR, 0660)
51 func (me *data) WriteAt(p []byte, off int64) (n int, err error) {
52 i := int(off / me.info.PieceLength)
53 off %= me.info.PieceLength
55 _, err = os.Stat(me.baseDir + "/complete/" + me.pieceHashHex(i))
57 err = errors.New("can't write to completed piece")
60 os.MkdirAll(me.baseDir+"/incomplete", 0750)
62 f, err = os.OpenFile(me.baseDir+"/incomplete/"+me.pieceHashHex(i), os.O_WRONLY|os.O_CREATE, 0640)
67 maxN := me.info.Piece(i).Length() - off
68 if int64(len(p1)) > maxN {
72 n1, err = f.WriteAt(p1, off)
84 func (me *data) pieceReader(piece int, off int64) (ret io.ReadCloser, err error) {
85 hash := me.pieceHashHex(piece)
86 f, err := os.Open(me.baseDir + "/complete/" + hash)
87 if os.IsNotExist(err) {
88 f, err = os.Open(me.baseDir + "/incomplete/" + hash)
89 if os.IsNotExist(err) {
96 } else if err != nil {
102 }{io.NewSectionReader(f, off, me.info.Piece(piece).Length()-off), f}, nil
105 func (me *data) WriteSectionTo(w io.Writer, off, n int64) (written int64, err error) {
106 i := int(off / me.info.PieceLength)
107 off %= me.info.PieceLength
110 pr, err = me.pieceReader(i, off)
118 n1, err = io.CopyN(w, pr, n)