]> Sergey Matveev's repositories - btrtrc.git/blob - data/file/file.go
Rewrite imports to local bencode and metainfo
[btrtrc.git] / data / file / file.go
1 package file
2
3 import (
4         "io"
5         "os"
6         "path/filepath"
7
8         "github.com/anacrolix/torrent/metainfo"
9 )
10
11 type data struct {
12         info *metainfo.Info
13         loc  string
14 }
15
16 func TorrentData(md *metainfo.Info, location string) data {
17         return data{md, location}
18 }
19
20 func (me data) ReadAt(p []byte, off int64) (n int, err error) {
21         for _, fi := range me.info.UpvertedFiles() {
22                 if off >= fi.Length {
23                         off -= fi.Length
24                         continue
25                 }
26                 n1 := len(p)
27                 if int64(n1) > fi.Length-off {
28                         n1 = int(fi.Length - off)
29                 }
30                 var f *os.File
31                 f, err = os.Open(me.fileInfoName(fi))
32                 if err != nil {
33                         return
34                 }
35                 n1, err = f.ReadAt(p[:n1], off)
36                 f.Close()
37                 if err != nil {
38                         return
39                 }
40                 n += n1
41                 off = 0
42                 p = p[n1:]
43                 if len(p) == 0 {
44                         break
45                 }
46         }
47         return
48 }
49
50 func (me data) WriteAt(p []byte, off int64) (n int, err error) {
51         for _, fi := range me.info.UpvertedFiles() {
52                 if off >= fi.Length {
53                         off -= fi.Length
54                         continue
55                 }
56                 n1 := len(p)
57                 if int64(n1) > fi.Length-off {
58                         n1 = int(fi.Length - off)
59                 }
60                 name := me.fileInfoName(fi)
61                 os.MkdirAll(filepath.Dir(name), 0770)
62                 var f *os.File
63                 f, err = os.OpenFile(name, os.O_WRONLY|os.O_CREATE, 0660)
64                 if err != nil {
65                         return
66                 }
67                 n1, err = f.WriteAt(p[:n1], off)
68                 f.Close()
69                 if err != nil {
70                         return
71                 }
72                 n += n1
73                 off = 0
74                 p = p[n1:]
75                 if len(p) == 0 {
76                         break
77                 }
78         }
79         return
80 }
81
82 func (me data) WriteSectionTo(w io.Writer, off, n int64) (written int64, err error) {
83         for _, fi := range me.info.UpvertedFiles() {
84                 if off >= fi.Length {
85                         off -= fi.Length
86                         continue
87                 }
88                 n1 := fi.Length - off
89                 if n1 > n {
90                         n1 = n
91                 }
92                 var f *os.File
93                 f, err = os.Open(me.fileInfoName(fi))
94                 if err != nil {
95                         return
96                 }
97                 n1, err = io.Copy(w, io.NewSectionReader(f, off, n1))
98                 f.Close()
99                 if err != nil {
100                         return
101                 }
102                 written += n1
103                 off = 0
104                 n -= n1
105                 if n == 0 {
106                         break
107                 }
108         }
109         return
110 }
111
112 func (me data) fileInfoName(fi metainfo.FileInfo) string {
113         return filepath.Join(append([]string{me.loc, me.info.Name}, fi.Path...)...)
114 }