@@ -18,13 +18,23 @@ import (
1818 "io"
1919)
2020
21+ type seekable struct {
22+ * reader
23+ }
24+
25+ type ReadSeekCloser interface {
26+ io.ReadCloser
27+ io.Seeker
28+ }
29+
2130type reader struct {
2231 in io.Reader // Input reader
2332 closer io.Closer // Optional closer
2433 ready chan * buffer // Buffers ready to be handed to the reader
2534 reuse chan * buffer // Buffers to reuse for input reading
2635 exit chan struct {} // Closes when finished
2736 buffers int // Number of buffers
37+ size int // Size of each buffer
2838 err error // If an error has occurred it is here
2939 cur * buffer // Current buffer being served
3040 exited chan struct {} // Channel is closed been the async reader shuts down
@@ -38,6 +48,8 @@ type reader struct {
3848//
3949// The input can be read from the returned reader.
4050// When done use Close() to release the buffers.
51+ // If a reader supporting the io.Seeker is given,
52+ // the returned reader will also support it.
4153func NewReader (rd io.Reader ) io.ReadCloser {
4254 if rd == nil {
4355 return nil
@@ -61,6 +73,8 @@ func NewReader(rd io.Reader) io.ReadCloser {
6173// The input can be read from the returned reader.
6274// When done use Close() to release the buffers,
6375// which will also close the supplied closer.
76+ // If a reader supporting the io.Seeker is given,
77+ // the returned reader will also support it.
6478func NewReadCloser (rd io.ReadCloser ) io.ReadCloser {
6579 if rd == nil {
6680 return nil
@@ -75,10 +89,39 @@ func NewReadCloser(rd io.ReadCloser) io.ReadCloser {
7589 return ret
7690}
7791
92+ // New returns a reader that will asynchronously read from
93+ // the supplied reader into 4 buffers of 1MB each.
94+ //
95+ // It will start reading from the input at once, maybe even before this
96+ // function has returned.
97+ //
98+ // The input can be read and seeked from the returned reader.
99+ // When done use Close() to release the buffers.
100+ func NewReadSeeker (rd io.ReadSeeker ) ReadSeekCloser {
101+ //Not checking for result as the input interface guarantees it's seekable
102+ res , _ := NewReader (rd ).(ReadSeekCloser )
103+ return res
104+ }
105+
106+ // New returns a reader that will asynchronously read from
107+ // the supplied reader into 4 buffers of 1MB each.
108+ //
109+ // It will start reading from the input at once, maybe even before this
110+ // function has returned.
111+ //
112+ // The input can be read and seeked from the returned reader.
113+ // When done use Close() to release the buffers,
114+ // which will also close the supplied closer.
115+ func NewReadSeekCloser (rd ReadSeekCloser ) ReadSeekCloser {
116+ //Not checking for result as the input interface guarantees it's seekable
117+ res , _ := NewReadCloser (rd ).(ReadSeekCloser )
118+ return res
119+ }
120+
78121// NewReaderSize returns a reader with a custom number of buffers and size.
79122// buffers is the number of queued buffers and size is the size of each
80123// buffer in bytes.
81- func NewReaderSize (rd io.Reader , buffers , size int ) (io.ReadCloser , error ) {
124+ func NewReaderSize (rd io.Reader , buffers , size int ) (res io.ReadCloser , err error ) {
82125 if size <= 0 {
83126 return nil , fmt .Errorf ("buffer size too small" )
84127 }
@@ -89,14 +132,19 @@ func NewReaderSize(rd io.Reader, buffers, size int) (io.ReadCloser, error) {
89132 return nil , fmt .Errorf ("nil input reader supplied" )
90133 }
91134 a := & reader {}
135+ if _ , ok := rd .(io.Seeker ); ok {
136+ res = & seekable {a }
137+ } else {
138+ res = a
139+ }
92140 a .init (rd , buffers , size )
93- return a , nil
141+ return
94142}
95143
96144// NewReadCloserSize returns a reader with a custom number of buffers and size.
97145// buffers is the number of queued buffers and size is the size of each
98146// buffer in bytes.
99- func NewReadCloserSize (rc io.ReadCloser , buffers , size int ) (io.ReadCloser , error ) {
147+ func NewReadCloserSize (rc io.ReadCloser , buffers , size int ) (res io.ReadCloser , err error ) {
100148 if size <= 0 {
101149 return nil , fmt .Errorf ("buffer size too small" )
102150 }
@@ -107,8 +155,39 @@ func NewReadCloserSize(rc io.ReadCloser, buffers, size int) (io.ReadCloser, erro
107155 return nil , fmt .Errorf ("nil input reader supplied" )
108156 }
109157 a := & reader {closer : rc }
158+ if _ , ok := rc .(io.Seeker ); ok {
159+ res = & seekable {a }
160+ } else {
161+ res = a
162+ }
110163 a .init (rc , buffers , size )
111- return a , nil
164+ return
165+ }
166+
167+ // NewReadSeekerSize returns a reader with a custom number of buffers and size.
168+ // buffers is the number of queued buffers and size is the size of each
169+ // buffer in bytes.
170+ func NewReadSeekerSize (rd io.ReadSeeker , buffers , size int ) (res ReadSeekCloser , err error ) {
171+ reader , err := NewReaderSize (rd , buffers , size )
172+ if err != nil {
173+ return nil , err
174+ }
175+ //Not checking for result as the input interface guarantees it's seekable
176+ res , _ = reader .(ReadSeekCloser )
177+ return
178+ }
179+
180+ // NewReadSeekCloserSize returns a reader with a custom number of buffers and size.
181+ // buffers is the number of queued buffers and size is the size of each
182+ // buffer in bytes.
183+ func NewReadSeekCloserSize (rd ReadSeekCloser , buffers , size int ) (res ReadSeekCloser , err error ) {
184+ reader , err := NewReadCloserSize (rd , buffers , size )
185+ if err != nil {
186+ return nil , err
187+ }
188+ //Not checking for result as the input interface guarantees it's seekable
189+ res , _ = reader .(ReadSeekCloser )
190+ return
112191}
113192
114193// initialize the reader
@@ -119,7 +198,9 @@ func (a *reader) init(rd io.Reader, buffers, size int) {
119198 a .exit = make (chan struct {}, 0 )
120199 a .exited = make (chan struct {}, 0 )
121200 a .buffers = buffers
201+ a .size = size
122202 a .cur = nil
203+ a .err = nil
123204
124205 // Create buffers
125206 for i := 0 ; i < buffers ; i ++ {
@@ -130,13 +211,13 @@ func (a *reader) init(rd io.Reader, buffers, size int) {
130211 go func () {
131212 // Ensure that when we exit this is signalled.
132213 defer close (a .exited )
214+ defer close (a .ready )
133215 for {
134216 select {
135217 case b := <- a .reuse :
136218 err := b .read (a .in )
137219 a .ready <- b
138220 if err != nil {
139- close (a .ready )
140221 return
141222 }
142223 case <- a .exit :
@@ -183,6 +264,34 @@ func (a *reader) Read(p []byte) (n int, err error) {
183264 return n , nil
184265}
185266
267+ func (a * seekable ) Seek (offset int64 , whence int ) (res int64 , err error ) {
268+ //Not checking the result as seekable receiver guarantees it to be assertable
269+ seeker , _ := a .in .(io.Seeker )
270+ //Make sure the async routine is closed
271+ select {
272+ case <- a .exited :
273+ case a .exit <- struct {}{}:
274+ <- a .exited
275+ }
276+ if whence == io .SeekCurrent {
277+ //If need to seek based on current position, take into consideration the bytes we read but the consumer
278+ //doesn't know about
279+ err = nil
280+ for a .cur != nil {
281+ if err = a .fill (); err == nil && a .cur != nil {
282+ offset -= int64 (len (a .cur .buffer ()))
283+ a .cur .offset = len (a .cur .buf )
284+ }
285+ }
286+ }
287+ //Seek the actual Seeker
288+ if res , err = seeker .Seek (offset , whence ); err == nil {
289+ //If the seek was successful, reinitalize ourselves (with the new position).
290+ a .init (a .in , a .buffers , a .size )
291+ }
292+ return
293+ }
294+
186295// WriteTo writes data to w until there's no more data to write or when an error occurs.
187296// The return value n is the number of bytes written.
188297// Any error encountered during the write is also returned.
0 commit comments