]> Sergey Matveev's repositories - btrtrc.git/blob - mmap_span.go
810c8257f97f88c57ce85b2105b3d73641a471a8
[btrtrc.git] / mmap_span.go
1 package torrent
2
3 import (
4         "io"
5
6         "launchpad.net/gommap"
7 )
8
9 type MMap struct {
10         gommap.MMap
11 }
12
13 func (me MMap) Size() int64 {
14         return int64(len(me.MMap))
15 }
16
17 type MMapSpan []MMap
18
19 func (me MMapSpan) span() (s span) {
20         for _, mmap := range me {
21                 s = append(s, mmap)
22         }
23         return
24 }
25
26 func (me MMapSpan) Close() {
27         for _, mMap := range me {
28                 mMap.UnsafeUnmap()
29         }
30 }
31
32 func (me MMapSpan) Size() (ret int64) {
33         for _, mmap := range me {
34                 ret += mmap.Size()
35         }
36         return
37 }
38
39 func (me MMapSpan) ReadAt(p []byte, off int64) (n int, err error) {
40         me.span().ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
41                 _n := copy(p, interval.(MMap).MMap[intervalOffset:])
42                 p = p[_n:]
43                 n += _n
44                 return len(p) == 0
45         })
46         if len(p) != 0 {
47                 err = io.EOF
48         }
49         return
50 }
51
52 func (me MMapSpan) WriteSectionTo(w io.Writer, off, n int64) (written int64, err error) {
53         me.span().ApplyTo(off, func(intervalOffset int64, interval sizer) (stop bool) {
54                 var _n int
55                 p := interval.(MMap).MMap[intervalOffset:]
56                 if n < int64(len(p)) {
57                         p = p[:n]
58                 }
59                 _n, err = w.Write(p)
60                 written += int64(_n)
61                 n -= int64(_n)
62                 if err != nil {
63                         return true
64                 }
65                 return n == 0
66         })
67         return
68 }
69
70 func (me MMapSpan) WriteAt(p []byte, off int64) (n int, err error) {
71         me.span().ApplyTo(off, func(iOff int64, i sizer) (stop bool) {
72                 mMap := i.(MMap)
73                 _n := copy(mMap.MMap[iOff:], p)
74                 // err = mMap.Sync(gommap.MS_ASYNC)
75                 // if err != nil {
76                 //      return true
77                 // }
78                 p = p[_n:]
79                 n += _n
80                 return len(p) == 0
81         })
82         if err != nil && len(p) != 0 {
83                 err = io.ErrShortWrite
84         }
85         return
86 }