]> Sergey Matveev's repositories - btrtrc.git/blob - storage/file-piece.go
Fix file storage segments for v2 torrents
[btrtrc.git] / storage / file-piece.go
1 package storage
2
3 import (
4         "github.com/anacrolix/torrent/segments"
5         "io"
6         "log"
7         "os"
8
9         "github.com/anacrolix/torrent/metainfo"
10 )
11
12 type filePieceImpl struct {
13         *fileTorrentImpl
14         p metainfo.Piece
15         io.WriterAt
16         io.ReaderAt
17 }
18
19 var _ PieceImpl = (*filePieceImpl)(nil)
20
21 func (me *filePieceImpl) pieceKey() metainfo.PieceKey {
22         return metainfo.PieceKey{me.infoHash, me.p.Index()}
23 }
24
25 func (fs *filePieceImpl) Completion() Completion {
26         c, err := fs.completion.Get(fs.pieceKey())
27         if err != nil {
28                 log.Printf("error getting piece completion: %s", err)
29                 c.Ok = false
30                 return c
31         }
32
33         verified := true
34         if c.Complete {
35                 // If it's allegedly complete, check that its constituent files have the necessary length.
36                 if !fs.segmentLocater.Locate(segments.Extent{
37                         Start:  fs.p.Offset(),
38                         Length: fs.p.Length(),
39                 }, func(i int, extent segments.Extent) bool {
40                         file := fs.files[i]
41                         s, err := os.Stat(file.path)
42                         if err != nil || s.Size() < extent.Start+extent.Length {
43                                 verified = false
44                                 return false
45                         }
46                         return true
47                 }) {
48                         panic("files do not cover piece extent")
49                 }
50         }
51
52         if !verified {
53                 // The completion was wrong, fix it.
54                 c.Complete = false
55                 fs.completion.Set(fs.pieceKey(), false)
56         }
57
58         return c
59 }
60
61 func (fs *filePieceImpl) MarkComplete() error {
62         return fs.completion.Set(fs.pieceKey(), true)
63 }
64
65 func (fs *filePieceImpl) MarkNotComplete() error {
66         return fs.completion.Set(fs.pieceKey(), false)
67 }