]> Sergey Matveev's repositories - btrtrc.git/blob - storage/wrappers.go
goimports -local
[btrtrc.git] / storage / wrappers.go
1 package storage
2
3 import (
4         "io"
5         "os"
6
7         "github.com/anacrolix/missinggo"
8
9         "github.com/anacrolix/torrent/metainfo"
10 )
11
12 type Client struct {
13         ci ClientImpl
14 }
15
16 func NewClient(cl ClientImpl) *Client {
17         return &Client{cl}
18 }
19
20 func (cl Client) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (*Torrent, error) {
21         t, err := cl.ci.OpenTorrent(info, infoHash)
22         return &Torrent{t}, err
23 }
24
25 type Torrent struct {
26         TorrentImpl
27 }
28
29 func (t Torrent) Piece(p metainfo.Piece) Piece {
30         return Piece{t.TorrentImpl.Piece(p), p}
31 }
32
33 type Piece struct {
34         PieceImpl
35         mip metainfo.Piece
36 }
37
38 func (p Piece) WriteAt(b []byte, off int64) (n int, err error) {
39         // Callers should not be writing to completed pieces, but it's too
40         // expensive to be checking this on every single write using uncached
41         // completions.
42
43         // c := p.Completion()
44         // if c.Ok && c.Complete {
45         //      err = errors.New("piece already completed")
46         //      return
47         // }
48         if off+int64(len(b)) > p.mip.Length() {
49                 panic("write overflows piece")
50         }
51         b = missinggo.LimitLen(b, p.mip.Length()-off)
52         return p.PieceImpl.WriteAt(b, off)
53 }
54
55 func (p Piece) ReadAt(b []byte, off int64) (n int, err error) {
56         if off < 0 {
57                 err = os.ErrInvalid
58                 return
59         }
60         if off >= p.mip.Length() {
61                 err = io.EOF
62                 return
63         }
64         b = missinggo.LimitLen(b, p.mip.Length()-off)
65         if len(b) == 0 {
66                 return
67         }
68         n, err = p.PieceImpl.ReadAt(b, off)
69         if n > len(b) {
70                 panic(n)
71         }
72         off += int64(n)
73         if err == io.EOF && off < p.mip.Length() {
74                 err = io.ErrUnexpectedEOF
75         }
76         if err == nil && off >= p.mip.Length() {
77                 err = io.EOF
78         }
79         if n == 0 && err == nil {
80                 err = io.ErrUnexpectedEOF
81         }
82         if off < p.mip.Length() && err != nil {
83                 p.MarkNotComplete()
84         }
85         return
86 }