|
|
@@ -4,7 +4,7 @@ extern crate protobuf;
|
|
4
|
4
|
extern crate byteorder;
|
|
5
|
5
|
extern crate memmap;
|
|
6
|
6
|
|
|
7
|
|
-use blob::{BlobDecode, BlobType, decode_blob};
|
|
|
7
|
+use blob::{BlobDecode, ByteOffset, BlobType, decode_blob};
|
|
8
|
8
|
use block::{HeaderBlock, PrimitiveBlock};
|
|
9
|
9
|
use byteorder::ByteOrder;
|
|
10
|
10
|
use error::{BlobError, Result, new_blob_error, new_protobuf_error};
|
|
|
@@ -83,6 +83,7 @@ impl Mmap {
|
|
83
|
83
|
pub struct MmapBlob<'a> {
|
|
84
|
84
|
header: BlobHeader,
|
|
85
|
85
|
data: &'a [u8],
|
|
|
86
|
+ offset: ByteOffset,
|
|
86
|
87
|
}
|
|
87
|
88
|
|
|
88
|
89
|
impl<'a> MmapBlob<'a> {
|
|
|
@@ -112,6 +113,11 @@ impl<'a> MmapBlob<'a> {
|
|
112
|
113
|
x => BlobType::Unknown(x),
|
|
113
|
114
|
}
|
|
114
|
115
|
}
|
|
|
116
|
+
|
|
|
117
|
+ /// Returns the byte offset of the blob from the start of its memory map.
|
|
|
118
|
+ pub fn offset(&self) -> ByteOffset {
|
|
|
119
|
+ self.offset
|
|
|
120
|
+ }
|
|
115
|
121
|
}
|
|
116
|
122
|
|
|
117
|
123
|
/// A reader for memory mapped PBF files that allows iterating over `MmapBlob`s.
|
|
|
@@ -144,6 +150,32 @@ impl<'a> MmapBlobReader<'a> {
|
|
144
|
150
|
last_blob_ok: true,
|
|
145
|
151
|
}
|
|
146
|
152
|
}
|
|
|
153
|
+
|
|
|
154
|
+ /// Move the cursor to the given byte offset.
|
|
|
155
|
+ ///
|
|
|
156
|
+ /// # Example
|
|
|
157
|
+ /// ```
|
|
|
158
|
+ /// use osmpbf::*;
|
|
|
159
|
+ ///
|
|
|
160
|
+ /// # fn foo() -> Result<()> {
|
|
|
161
|
+ ///
|
|
|
162
|
+ /// let mmap = unsafe { Mmap::from_path("tests/test.osm.pbf")? };
|
|
|
163
|
+ /// let mut reader = MmapBlobReader::new(&mmap);
|
|
|
164
|
+ ///
|
|
|
165
|
+ /// let first_blob = reader.next().unwrap()?;
|
|
|
166
|
+ /// let second_blob = reader.next().unwrap()?;
|
|
|
167
|
+ ///
|
|
|
168
|
+ /// reader.seek(first_blob.offset());
|
|
|
169
|
+ /// let first_blob_again = reader.next().unwrap()?;
|
|
|
170
|
+ ///
|
|
|
171
|
+ /// assert_eq!(first_blob.offset(), first_blob_again.offset());
|
|
|
172
|
+ ///
|
|
|
173
|
+ /// # Ok(())
|
|
|
174
|
+ /// # }
|
|
|
175
|
+ /// ```
|
|
|
176
|
+ pub fn seek(&mut self, pos: ByteOffset) {
|
|
|
177
|
+ self.offset = pos.0 as usize;
|
|
|
178
|
+ }
|
|
147
|
179
|
}
|
|
148
|
180
|
|
|
149
|
181
|
impl<'a> Iterator for MmapBlobReader<'a> {
|
|
|
@@ -195,11 +227,13 @@ impl<'a> Iterator for MmapBlobReader<'a> {
|
|
195
|
227
|
return Some(Err(io_error.into()));
|
|
196
|
228
|
}
|
|
197
|
229
|
|
|
|
230
|
+ let prev_offset = self.offset;
|
|
198
|
231
|
self.offset += chunk_size;
|
|
199
|
232
|
|
|
200
|
233
|
Some(Ok(MmapBlob {
|
|
201
|
234
|
header,
|
|
202
|
|
- data: &slice[(4 + header_size)..chunk_size]
|
|
|
235
|
+ data: &slice[(4 + header_size)..chunk_size],
|
|
|
236
|
+ offset: ByteOffset(prev_offset as u64),
|
|
203
|
237
|
}))
|
|
204
|
238
|
}
|
|
205
|
239
|
}
|