File tree 2 files changed +42
-3
lines changed
2 files changed +42
-3
lines changed Original file line number Diff line number Diff line change @@ -3,7 +3,6 @@ package plumbing
3
3
import (
4
4
"bytes"
5
5
"io"
6
- "io/ioutil"
7
6
)
8
7
9
8
// MemoryObject on memory Object implementation
@@ -39,9 +38,11 @@ func (o *MemoryObject) Size() int64 { return o.sz }
39
38
// afterwards
40
39
func (o * MemoryObject ) SetSize (s int64 ) { o .sz = s }
41
40
42
- // Reader returns a ObjectReader used to read the object's content.
41
+ // Reader returns an io.ReadCloser used to read the object's content.
42
+ //
43
+ // For a MemoryObject, this reader is seekable.
43
44
func (o * MemoryObject ) Reader () (io.ReadCloser , error ) {
44
- return ioutil . NopCloser ( bytes .NewBuffer (o .cont )) , nil
45
+ return nopCloser { bytes .NewReader (o .cont )} , nil
45
46
}
46
47
47
48
// Writer returns a ObjectWriter used to write the object's content.
@@ -59,3 +60,13 @@ func (o *MemoryObject) Write(p []byte) (n int, err error) {
59
60
// Close releases any resources consumed by the object when it is acting as a
60
61
// ObjectWriter.
61
62
func (o * MemoryObject ) Close () error { return nil }
63
+
64
+ // nopCloser exposes the extra methods of bytes.Reader while nopping Close().
65
+ //
66
+ // This allows clients to attempt seeking in a cached Blob's Reader.
67
+ type nopCloser struct {
68
+ * bytes.Reader
69
+ }
70
+
71
+ // Close does nothing.
72
+ func (nc nopCloser ) Close () error { return nil }
Original file line number Diff line number Diff line change 1
1
package plumbing
2
2
3
3
import (
4
+ "io"
4
5
"io/ioutil"
5
6
6
7
. "gopkg.in/check.v1"
@@ -56,6 +57,33 @@ func (s *MemoryObjectSuite) TestReader(c *C) {
56
57
c .Assert (b , DeepEquals , []byte ("foo" ))
57
58
}
58
59
60
+ func (s * MemoryObjectSuite ) TestSeekableReader (c * C ) {
61
+ const pageSize = 4096
62
+ const payload = "foo"
63
+ content := make ([]byte , pageSize + len (payload ))
64
+ copy (content [pageSize :], []byte (payload ))
65
+
66
+ o := & MemoryObject {cont : content }
67
+
68
+ reader , err := o .Reader ()
69
+ c .Assert (err , IsNil )
70
+ defer func () { c .Assert (reader .Close (), IsNil ) }()
71
+
72
+ rs , ok := reader .(io.ReadSeeker )
73
+ c .Assert (ok , Equals , true )
74
+
75
+ _ , err = rs .Seek (pageSize , io .SeekStart )
76
+ c .Assert (err , IsNil )
77
+
78
+ b , err := ioutil .ReadAll (rs )
79
+ c .Assert (err , IsNil )
80
+ c .Assert (b , DeepEquals , []byte (payload ))
81
+
82
+ // Check that our Reader isn't also accidentally writable
83
+ _ , ok = reader .(io.WriteSeeker )
84
+ c .Assert (ok , Equals , false )
85
+ }
86
+
59
87
func (s * MemoryObjectSuite ) TestWriter (c * C ) {
60
88
o := & MemoryObject {}
61
89
You can’t perform that action at this time.
0 commit comments