]> Sergey Matveev's repositories - btrtrc.git/blob - storage/piece_resource.go
Track completion known to implementation state
[btrtrc.git] / storage / piece_resource.go
1 package storage
2
3 import (
4         "path"
5
6         "github.com/anacrolix/missinggo/resource"
7
8         "github.com/anacrolix/torrent/metainfo"
9 )
10
11 type piecePerResource struct {
12         p resource.Provider
13 }
14
15 func NewResourcePieces(p resource.Provider) ClientImpl {
16         return &piecePerResource{
17                 p: p,
18         }
19 }
20
21 func (s *piecePerResource) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (TorrentImpl, error) {
22         return s, nil
23 }
24
25 func (s *piecePerResource) Close() error {
26         return nil
27 }
28
29 func (s *piecePerResource) Piece(p metainfo.Piece) PieceImpl {
30         completed, err := s.p.NewInstance(path.Join("completed", p.Hash().HexString()))
31         if err != nil {
32                 panic(err)
33         }
34         incomplete, err := s.p.NewInstance(path.Join("incomplete", p.Hash().HexString()))
35         if err != nil {
36                 panic(err)
37         }
38         return piecePerResourcePiece{
39                 p: p,
40                 c: completed,
41                 i: incomplete,
42         }
43 }
44
45 type piecePerResourcePiece struct {
46         p metainfo.Piece
47         c resource.Instance
48         i resource.Instance
49 }
50
51 func (s piecePerResourcePiece) Completion() Completion {
52         fi, err := s.c.Stat()
53         return Completion{
54                 Complete: err == nil && fi.Size() == s.p.Length(),
55                 Ok:       true,
56         }
57 }
58
59 func (s piecePerResourcePiece) MarkComplete() error {
60         return resource.Move(s.i, s.c)
61 }
62
63 func (s piecePerResourcePiece) MarkNotComplete() error {
64         return s.c.Delete()
65 }
66
67 func (s piecePerResourcePiece) ReadAt(b []byte, off int64) (int, error) {
68         if s.Completion().Complete {
69                 return s.c.ReadAt(b, off)
70         } else {
71                 return s.i.ReadAt(b, off)
72         }
73 }
74
75 func (s piecePerResourcePiece) WriteAt(b []byte, off int64) (n int, err error) {
76         return s.i.WriteAt(b, off)
77 }