1#![doc=include_str!("../readme.md")]
2use quick_protobuf::{MessageRead,Reader};
3use std::io::{Read,Seek,SeekFrom};
4
5pub mod proto;
6pub use proto::fileformat::{Blob,BlobHeader};
7mod decode;
8pub mod element;
9pub use element::{Element,Info,Node,Way,Relation,Member,MemberType};
10mod scan;
11pub use scan::{Scan,ScanTable};
12mod scan_bytes;
13
14pub type Error = Box<dyn std::error::Error+Send+Sync+'static>;
15
16pub struct Parser<F: Read+Seek> {
17 handle: Box<F>,
18}
19
20impl<F> Parser<F> where F: Read+Seek {
21 pub fn new(handle: Box<F>) -> Self {
22 Self { handle }
23 }
24 pub fn read_fileblock(&mut self, offset: u64) -> Result<(u64,BlobHeader,Blob),Error> {
25 let (s,blob_header) = self.read_blob_header(offset)?;
26 let blob = self.read_blob(offset + s, blob_header.datasize as usize)?;
27 Ok((s + blob_header.datasize as u64, blob_header, blob))
28 }
29 pub fn read_blob_header(&mut self, offset: u64) -> Result<(u64,BlobHeader),Error> {
30 let mut len_buf = [0,0,0,0];
31 self.handle.seek(SeekFrom::Start(offset))?;
32 self.handle.read_exact(&mut len_buf)?;
33 let len = u32::from_be_bytes(len_buf) as usize;
34 self.handle.seek(SeekFrom::Start(offset+4))?;
35 let mut buf = vec![0u8;len];
36 self.handle.read_exact(&mut buf)?;
37 let mut reader = Reader::from_bytes(buf);
38 let blob_header = reader.read(BlobHeader::from_reader)?;
39 Ok(((len+4) as u64, blob_header))
40 }
41 pub fn read_blob(&mut self, offset: u64, len: usize) -> Result<Blob,Error> {
42 self.handle.seek(SeekFrom::Start(offset))?;
43 let mut buf = vec![0u8;len];
44 self.handle.read_exact(&mut buf)?;
45 let mut reader = Reader::from_bytes(buf);
46 let blob = reader.read(Blob::from_reader)?;
47 Ok(blob)
48 }
49 pub fn read(&mut self, offset: u64) -> Result<(u64,Vec<element::Element>),Error> {
50 let (len,_blob_header,blob) = self.read_fileblock(offset)?;
51 if offset == 0 { Ok((len, vec![]))
53 } else {
54 Ok((len, blob.decode_primitive()?.decode()))
55 }
56 }
57}