@@ -17,48 +17,6 @@ type IBinaryReader interface {
1717 Close () error
1818}
1919
20- type binaryReaderFile struct {
21- f * os.File
22- size int64
23- }
24-
25- func newBinaryReaderFile (filename string ) (* binaryReaderFile , error ) {
26- f , err := os .Open (filename )
27- if err != nil {
28- return nil , err
29- }
30- fi , err := f .Stat ()
31- if err != nil {
32- f .Close ()
33- return nil , err
34- }
35- return & binaryReaderFile {f , fi .Size ()}, nil
36- }
37-
38- // Close closes the reader.
39- func (r * binaryReaderFile ) Close () error {
40- return r .f .Close ()
41- }
42-
43- // Len returns the length of the underlying memory-mapped file.
44- func (r * binaryReaderFile ) Len () int64 {
45- return r .size
46- }
47-
48- func (r * binaryReaderFile ) Bytes (b []byte , n , off int64 ) ([]byte , error ) {
49- if b == nil {
50- b = make ([]byte , n )
51- }
52- if m , err := r .f .ReadAt (b , off ); err != nil {
53- return b [:m ], err
54- } else if off + int64 (m ) == r .size {
55- return b [:m ], io .EOF
56- } else if int64 (m ) != n {
57- return b [:m ], errors .New ("file: could not read all bytes" )
58- }
59- return b , nil
60- }
61-
6220type binaryReaderBytes struct {
6321 data []byte
6422}
@@ -97,17 +55,12 @@ func (r *binaryReaderBytes) Bytes(b []byte, n, off int64) ([]byte, error) {
9755}
9856
9957type binaryReaderReader struct {
100- r io.Reader
101- size int64
102- readerAt bool
103- seeker bool
104- mu sync.Mutex
58+ r io.Reader
59+ pos , size int64
10560}
10661
10762func newBinaryReaderReader (r io.Reader , n int64 ) * binaryReaderReader {
108- _ , readerAt := r .(io.ReaderAt )
109- _ , seeker := r .(io.Seeker )
110- return & binaryReaderReader {r , n , readerAt , seeker , sync.Mutex {}}
63+ return & binaryReaderReader {r , 0 , n }
11164}
11265
11366// Close closes the reader.
@@ -118,46 +71,118 @@ func (r *binaryReaderReader) Close() error {
11871 return nil
11972}
12073
121- // Len returns the length of the underlying memory-mapped file.
74+ // Len returns the length of the file.
12275func (r * binaryReaderReader ) Len () int64 {
12376 return r .size
12477}
12578
12679func (r * binaryReaderReader ) Bytes (b []byte , n , off int64 ) ([]byte , error ) {
127- if b == nil {
80+ if off != r .pos {
81+ return nil , errors .New ("reader: does not implement io.Seeker or io.ReaderAt" )
82+ } else if b == nil {
12883 b = make ([]byte , n )
12984 }
13085
131- // seeker seems faster than readerAt by 10%
132- if r .seeker {
133- r .mu .Lock ()
134- if _ , err := r .r .(io.Seeker ).Seek (off , 0 ); err != nil {
135- r .mu .Unlock ()
136- return nil , err
86+ for i := 0 ; i < int (n ); {
87+ m , err := r .r .Read (b [i :])
88+ r .pos += int64 (m )
89+ i += m
90+ if err != nil {
91+ return b [:i ], err
92+ } else if m == 0 {
93+ return b [:i ], errors .New ("reader: could not read all bytes" )
13794 }
95+ }
96+ if off + n == r .size {
97+ return b , io .EOF
98+ }
99+ return b , nil
100+ }
101+
102+ type binaryReaderSeeker struct {
103+ r io.ReadSeeker
104+ size int64
105+ mu sync.Mutex
106+ }
138107
139- m , err := r .r .Read (b )
108+ func newBinaryReaderSeeker (r io.ReadSeeker , n int64 ) * binaryReaderSeeker {
109+ return & binaryReaderSeeker {r , n , sync.Mutex {}}
110+ }
111+
112+ // Close closes the reader.
113+ func (r * binaryReaderSeeker ) Close () error {
114+ if closer , ok := r .r .(io.Closer ); ok {
115+ return closer .Close ()
116+ }
117+ return nil
118+ }
119+
120+ // Len returns the length of the file.
121+ func (r * binaryReaderSeeker ) Len () int64 {
122+ return r .size
123+ }
124+
125+ func (r * binaryReaderSeeker ) Bytes (b []byte , n , off int64 ) ([]byte , error ) {
126+ if b == nil {
127+ b = make ([]byte , n )
128+ }
129+
130+ r .mu .Lock ()
131+ if _ , err := r .r .Seek (off , 0 ); err != nil {
140132 r .mu .Unlock ()
133+ return nil , err
134+ }
135+ for i := 0 ; i < int (n ); {
136+ m , err := r .r .Read (b [i :])
137+ i += m
141138 if err != nil {
142- return b [:m ], err
143- } else if off + int64 (m ) == r .size {
144- return b [:m ], io .EOF
145- } else if int64 (m ) != n {
146- return b [:m ], errors .New ("reader: could not read all bytes" )
147- }
148- return b , nil
149- } else if r .readerAt {
150- m , err := r .r .(io.ReaderAt ).ReadAt (b , off )
151- if err != nil {
152- return b [:m ], err
153- } else if off + int64 (m ) == r .size {
154- return b [:m ], io .EOF
155- } else if int64 (m ) != n {
156- return b [:m ], errors .New ("reader: could not read all bytes" )
139+ return b [:i ], err
140+ } else if m == 0 {
141+ return b [:i ], errors .New ("reader: could not read all bytes" )
157142 }
158- return b , nil
159143 }
160- return nil , errors .New ("io.Seeker and io.ReaderAt not implemented" )
144+ r .mu .Unlock ()
145+
146+ if off + n == r .size {
147+ return b , io .EOF
148+ }
149+ return b , nil
150+ }
151+
152+ type binaryReaderReaderAt struct {
153+ r io.ReaderAt
154+ size int64
155+ }
156+
157+ func newBinaryReaderReaderAt (r io.ReaderAt , n int64 ) * binaryReaderReaderAt {
158+ return & binaryReaderReaderAt {r , n }
159+ }
160+
161+ // Close closes the reader.
162+ func (r * binaryReaderReaderAt ) Close () error {
163+ if closer , ok := r .r .(io.Closer ); ok {
164+ return closer .Close ()
165+ }
166+ return nil
167+ }
168+
169+ // Len returns the length of the file.
170+ func (r * binaryReaderReaderAt ) Len () int64 {
171+ return r .size
172+ }
173+
174+ func (r * binaryReaderReaderAt ) Bytes (b []byte , n , off int64 ) ([]byte , error ) {
175+ if b == nil {
176+ b = make ([]byte , n )
177+ }
178+ if m , err := r .r .ReadAt (b , off ); err != nil {
179+ return b [:m ], err
180+ } else if off + int64 (m ) == r .size {
181+ return b [:m ], io .EOF
182+ } else if int64 (m ) != n {
183+ return b [:m ], errors .New ("reader: could not read all bytes" )
184+ }
185+ return b , nil
161186}
162187
163188type BinaryReader struct {
@@ -175,19 +200,36 @@ func NewBinaryReader(f IBinaryReader) *BinaryReader {
175200 }
176201}
177202
203+ // Will use Bytes when interface { Bytes() []byte } is implemented (n not used), Seeker when io.Seeker is implemented (negative n tolerated), ReaderAt when io.ReaderAt is implemented, otherwise it will read all bytes if n is negative or returns a non-Seeking/non-ReaderAt reader that does not allow Seek.
178204func NewBinaryReaderReader (r io.Reader , n int64 ) (* BinaryReader , error ) {
179- _ , isReaderAt := r .(io.ReaderAt )
180- _ , isSeeker := r .(io.Seeker )
181-
182205 var f IBinaryReader
183- if isReaderAt || isSeeker {
184- f = newBinaryReaderReader (r , n )
185- } else {
186- b := make ([]byte , n )
187- if _ , err := io .ReadFull (r , b ); err != nil {
206+ if b , ok := r .(interface { Bytes () []byte }); ok {
207+ f = newBinaryReaderBytes (b .Bytes ())
208+ } else if seeker , ok := r .(io.ReadSeeker ); ok {
209+ // seeker seems faster than readerAt by 10%
210+ if n < 0 {
211+ if offset , err := seeker .Seek (0 , os .SEEK_CUR ); err != nil {
212+ return nil , err
213+ } else if n , err = seeker .Seek (0 , os .SEEK_END ); err != nil {
214+ return nil , err
215+ } else if _ , err = seeker .Seek (offset , os .SEEK_SET ); err != nil {
216+ return nil , err
217+ }
218+ }
219+ f = newBinaryReaderSeeker (seeker , n )
220+ } else if readerAt , ok := r .(io.ReaderAt ); ok {
221+ if n < 0 {
222+ return nil , fmt .Errorf ("invalid negative size" )
223+ }
224+ f = newBinaryReaderReaderAt (readerAt , n )
225+ } else if n < 0 {
226+ b , err := io .ReadAll (r )
227+ if err != nil {
188228 return nil , err
189229 }
190230 f = newBinaryReaderBytes (b )
231+ } else {
232+ f = newBinaryReaderReader (r , n )
191233 }
192234 return NewBinaryReader (f ), nil
193235}
@@ -197,12 +239,25 @@ func NewBinaryReaderBytes(data []byte) *BinaryReader {
197239 return NewBinaryReader (f )
198240}
199241
200- func NewBinaryReaderFile (filename string ) (* BinaryReader , error ) {
201- f , err := newBinaryReaderFile ( filename )
242+ func NewBinaryReaderFile (f * os. File ) (* BinaryReader , error ) {
243+ info , err := f . Stat ( )
202244 if err != nil {
203245 return nil , err
204246 }
205- return NewBinaryReader (f ), nil
247+ return NewBinaryReader (newBinaryReaderSeeker (f , info .Size ())), nil
248+ }
249+
250+ func NewBinaryReaderPath (filename string ) (* BinaryReader , error ) {
251+ f , err := os .Open (filename )
252+ if err != nil {
253+ return nil , err
254+ }
255+ r , err := NewBinaryReaderFile (f )
256+ if err != nil {
257+ f .Close ()
258+ return nil , err
259+ }
260+ return r , nil
206261}
207262
208263func (r * BinaryReader ) IBinaryReader () IBinaryReader {
@@ -285,7 +340,9 @@ func (r *BinaryReader) ReadAt(b []byte, off int64) (int, error) {
285340func (r * BinaryReader ) ReadBytes (n int64 ) []byte {
286341 data , err := r .f .Bytes (nil , n , r .pos )
287342 r .pos += int64 (len (data ))
288- r .err = err
343+ if r .err == nil {
344+ r .err = err
345+ }
289346 return data
290347}
291348
0 commit comments