@@ -30,20 +30,23 @@ use crate::error::{AsyncTiffError, AsyncTiffResult};
30
30
///
31
31
/// [`tokio::fs::File`]: https://docs.rs/tokio/latest/tokio/fs/struct.File.html
32
32
pub trait AsyncFileReader : Debug + Send + Sync {
33
- /// Retrieve the bytes in `range`
34
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > ;
33
+ /// Retrieve the bytes in `range` as part of a request for header metadata.
34
+ fn get_metadata_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > ;
35
35
36
- /// Retrieve multiple byte ranges. The default implementation will call `get_bytes`
37
- /// sequentially
38
- fn get_byte_ranges (
36
+ /// Retrieve the bytes in `range` as part of a request for image data, not header metadata.
37
+ fn get_image_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > ;
38
+
39
+ /// Retrieve multiple byte ranges as part of a request for image data, not header metadata. The
40
+ /// default implementation will call `get_image_bytes` sequentially
41
+ fn get_image_byte_ranges (
39
42
& self ,
40
43
ranges : Vec < Range < u64 > > ,
41
44
) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > > {
42
45
async move {
43
46
let mut result = Vec :: with_capacity ( ranges. len ( ) ) ;
44
47
45
48
for range in ranges. into_iter ( ) {
46
- let data = self . get_bytes ( range) . await ?;
49
+ let data = self . get_image_bytes ( range) . await ?;
47
50
result. push ( data) ;
48
51
}
49
52
@@ -55,15 +58,19 @@ pub trait AsyncFileReader: Debug + Send + Sync {
55
58
56
59
/// This allows Box<dyn AsyncFileReader + '_> to be used as an AsyncFileReader,
57
60
impl AsyncFileReader for Box < dyn AsyncFileReader + ' _ > {
58
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
59
- self . as_ref ( ) . get_bytes ( range)
61
+ fn get_metadata_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
62
+ self . as_ref ( ) . get_metadata_bytes ( range)
63
+ }
64
+
65
+ fn get_image_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
66
+ self . as_ref ( ) . get_image_bytes ( range)
60
67
}
61
68
62
- fn get_byte_ranges (
69
+ fn get_image_byte_ranges (
63
70
& self ,
64
71
ranges : Vec < Range < u64 > > ,
65
72
) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > > {
66
- self . as_ref ( ) . get_byte_ranges ( ranges)
73
+ self . as_ref ( ) . get_image_byte_ranges ( ranges)
67
74
}
68
75
}
69
76
@@ -89,31 +96,36 @@ impl<T: tokio::io::AsyncRead + tokio::io::AsyncSeek + Unpin + Send + Debug> Toki
89
96
pub fn new ( inner : T ) -> Self {
90
97
Self ( tokio:: sync:: Mutex :: new ( inner) )
91
98
}
92
- }
93
99
94
- #[ cfg( feature = "tokio" ) ]
95
- impl < T : tokio:: io:: AsyncRead + tokio:: io:: AsyncSeek + Unpin + Send + Debug > AsyncFileReader
96
- for TokioReader < T >
97
- {
98
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
100
+ async fn make_range_request ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > {
99
101
use std:: io:: SeekFrom ;
100
102
use tokio:: io:: { AsyncReadExt , AsyncSeekExt } ;
101
103
102
- async move {
103
- let mut file = self . 0 . lock ( ) . await ;
104
-
105
- file. seek ( SeekFrom :: Start ( range. start ) ) . await ?;
104
+ let mut file = self . 0 . lock ( ) . await ;
106
105
107
- let to_read = range. end - range. start ;
108
- let mut buffer = Vec :: with_capacity ( to_read as usize ) ;
109
- let read = file. read ( & mut buffer) . await ? as u64 ;
110
- if read != to_read {
111
- return Err ( AsyncTiffError :: EndOfFile ( to_read, read) ) ;
112
- }
106
+ file. seek ( SeekFrom :: Start ( range. start ) ) . await ?;
113
107
114
- Ok ( buffer. into ( ) )
108
+ let to_read = range. end - range. start ;
109
+ let mut buffer = Vec :: with_capacity ( to_read as usize ) ;
110
+ let read = file. read ( & mut buffer) . await ? as u64 ;
111
+ if read != to_read {
112
+ return Err ( AsyncTiffError :: EndOfFile ( to_read, read) ) ;
115
113
}
116
- . boxed ( )
114
+
115
+ Ok ( buffer. into ( ) )
116
+ }
117
+ }
118
+
119
+ #[ cfg( feature = "tokio" ) ]
120
+ impl < T : tokio:: io:: AsyncRead + tokio:: io:: AsyncSeek + Unpin + Send + Debug > AsyncFileReader
121
+ for TokioReader < T >
122
+ {
123
+ fn get_metadata_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
124
+ self . make_range_request ( range) . boxed ( )
125
+ }
126
+
127
+ fn get_image_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
128
+ self . make_range_request ( range) . boxed ( )
117
129
}
118
130
}
119
131
@@ -133,19 +145,30 @@ impl ObjectReader {
133
145
pub fn new ( store : Arc < dyn object_store:: ObjectStore > , path : object_store:: path:: Path ) -> Self {
134
146
Self { store, path }
135
147
}
136
- }
137
148
138
- #[ cfg( feature = "object_store" ) ]
139
- impl AsyncFileReader for ObjectReader {
140
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
149
+ async fn make_range_request ( & self , range : Range < u64 > ) -> AsyncTiffResult < Bytes > {
141
150
let range = range. start as _ ..range. end as _ ;
142
151
self . store
143
152
. get_range ( & self . path , range)
144
153
. map_err ( |e| e. into ( ) )
145
- . boxed ( )
154
+ . await
155
+ }
156
+ }
157
+
158
+ #[ cfg( feature = "object_store" ) ]
159
+ impl AsyncFileReader for ObjectReader {
160
+ fn get_metadata_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
161
+ self . make_range_request ( range) . boxed ( )
146
162
}
147
163
148
- fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > >
164
+ fn get_image_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
165
+ self . make_range_request ( range) . boxed ( )
166
+ }
167
+
168
+ fn get_image_byte_ranges (
169
+ & self ,
170
+ ranges : Vec < Range < u64 > > ,
171
+ ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > >
149
172
where
150
173
Self : Send ,
151
174
{
@@ -177,11 +200,8 @@ impl ReqwestReader {
177
200
pub fn new ( client : reqwest:: Client , url : reqwest:: Url ) -> Self {
178
201
Self { client, url }
179
202
}
180
- }
181
203
182
- #[ cfg( feature = "reqwest" ) ]
183
- impl AsyncFileReader for ReqwestReader {
184
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
204
+ fn make_range_request ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
185
205
let url = self . url . clone ( ) ;
186
206
let client = self . client . clone ( ) ;
187
207
// HTTP range is inclusive, so we need to subtract 1 from the end
@@ -195,6 +215,17 @@ impl AsyncFileReader for ReqwestReader {
195
215
}
196
216
}
197
217
218
+ #[ cfg( feature = "reqwest" ) ]
219
+ impl AsyncFileReader for ReqwestReader {
220
+ fn get_metadata_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
221
+ self . make_range_request ( range)
222
+ }
223
+
224
+ fn get_image_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
225
+ self . make_range_request ( range)
226
+ }
227
+ }
228
+
198
229
/// An AsyncFileReader that caches the first `prefetch` bytes of a file.
199
230
#[ derive( Debug ) ]
200
231
pub struct PrefetchReader {
@@ -205,34 +236,43 @@ pub struct PrefetchReader {
205
236
impl PrefetchReader {
206
237
/// Construct a new PrefetchReader, catching the first `prefetch` bytes of the file.
207
238
pub async fn new ( reader : Arc < dyn AsyncFileReader > , prefetch : u64 ) -> AsyncTiffResult < Self > {
208
- let buffer = reader. get_bytes ( 0 ..prefetch) . await ?;
239
+ let buffer = reader. get_metadata_bytes ( 0 ..prefetch) . await ?;
209
240
Ok ( Self { reader, buffer } )
210
241
}
211
242
}
212
243
213
244
impl AsyncFileReader for PrefetchReader {
214
- fn get_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
245
+ fn get_metadata_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
215
246
if range. start < self . buffer . len ( ) as _ {
216
247
if range. end < self . buffer . len ( ) as _ {
217
248
let usize_range = range. start as usize ..range. end as usize ;
218
249
let result = self . buffer . slice ( usize_range) ;
219
250
async { Ok ( result) } . boxed ( )
220
251
} else {
221
252
// TODO: reuse partial internal buffer
222
- self . reader . get_bytes ( range)
253
+ self . reader . get_metadata_bytes ( range)
223
254
}
224
255
} else {
225
- self . reader . get_bytes ( range)
256
+ self . reader . get_metadata_bytes ( range)
226
257
}
227
258
}
228
259
229
- fn get_byte_ranges ( & self , ranges : Vec < Range < u64 > > ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > >
260
+ fn get_image_bytes ( & self , range : Range < u64 > ) -> BoxFuture < ' _ , AsyncTiffResult < Bytes > > {
261
+ // In practice, get_image_bytes is only used for fetching tiles, which are unlikely
262
+ // to overlap a metadata prefetch.
263
+ self . reader . get_image_bytes ( range)
264
+ }
265
+
266
+ fn get_image_byte_ranges (
267
+ & self ,
268
+ ranges : Vec < Range < u64 > > ,
269
+ ) -> BoxFuture < ' _ , AsyncTiffResult < Vec < Bytes > > >
230
270
where
231
271
Self : Send ,
232
272
{
233
- // In practice, get_byte_ranges is only used for fetching tiles, which are unlikely to
234
- // overlap a metadata prefetch.
235
- self . reader . get_byte_ranges ( ranges)
273
+ // In practice, get_image_byte_ranges is only used for fetching tiles, which are unlikely
274
+ // to overlap a metadata prefetch.
275
+ self . reader . get_image_byte_ranges ( ranges)
236
276
}
237
277
}
238
278
@@ -293,7 +333,7 @@ impl AsyncCursor {
293
333
pub ( crate ) async fn read ( & mut self , length : u64 ) -> AsyncTiffResult < EndianAwareReader > {
294
334
let range = self . offset as _ ..( self . offset + length) as _ ;
295
335
self . offset += length;
296
- let bytes = self . reader . get_bytes ( range) . await ?;
336
+ let bytes = self . reader . get_metadata_bytes ( range) . await ?;
297
337
Ok ( EndianAwareReader {
298
338
reader : bytes. reader ( ) ,
299
339
endianness : self . endianness ,
0 commit comments