]> Sergey Matveev's repositories - btrtrc.git/blob - data/pieceStore/data.go
Ditch Data.WriteSectionTo, and fix cmd/torrent-verify
[btrtrc.git] / data / pieceStore / data.go
1 package pieceStore
2
3 import (
4         "encoding/hex"
5         "io"
6
7         "github.com/anacrolix/torrent/metainfo"
8 )
9
10 type data struct {
11         info  *metainfo.Info
12         store *store
13 }
14
15 func (me *data) pieceHashHex(i int) string {
16         return hex.EncodeToString(me.info.Pieces[i*20 : (i+1)*20])
17 }
18
19 func (me *data) Close() {}
20
21 // TODO: Make sure that reading completed can't read from incomplete. Then
22 // also it'll be possible to verify that the Content-Range on completed
23 // returns the correct piece length so there aren't short reads.
24
25 func (me *data) ReadAt(b []byte, off int64) (n int, err error) {
26         for len(b) != 0 {
27                 if off >= me.info.TotalLength() {
28                         err = io.EOF
29                         break
30                 }
31                 p := me.info.Piece(int(off / me.info.PieceLength))
32                 b1 := b
33                 maxN1 := int(p.Length() - off%me.info.PieceLength)
34                 if len(b1) > maxN1 {
35                         b1 = b1[:maxN1]
36                 }
37                 var n1 int
38                 n1, err = me.store.pieceReadAt(p, b1, off%me.info.PieceLength)
39                 n += n1
40                 off += int64(n1)
41                 b = b[n1:]
42                 if err != nil {
43                         break
44                 }
45         }
46         return
47 }
48
49 // TODO: Rewrite this later, on short writes to a piece it will start to play up.
50 func (me *data) WriteAt(p []byte, off int64) (n int, err error) {
51         i := int(off / me.info.PieceLength)
52         off %= me.info.PieceLength
53         for len(p) != 0 {
54                 p1 := p
55                 maxN := me.info.Piece(i).Length() - off
56                 if int64(len(p1)) > maxN {
57                         p1 = p1[:maxN]
58                 }
59                 var n1 int
60                 n1, err = me.store.pieceWriteAt(me.info.Piece(i), p1, off)
61                 n += n1
62                 if err != nil {
63                         return
64                 }
65                 p = p[n1:]
66                 off = 0
67                 i++
68         }
69         return
70 }
71
72 func (me *data) pieceReader(p metainfo.Piece, off int64) (ret io.ReadCloser, err error) {
73         return me.store.getPieceRange(p, off, p.Length()-off)
74 }
75
76 func (me *data) PieceCompleted(index int) (err error) {
77         return me.store.pieceCompleted(me.info.Piece(index))
78 }
79
80 func (me *data) PieceComplete(piece int) bool {
81         return me.store.pieceComplete(me.info.Piece(piece))
82 }