1pub mod city_buffer;
2pub mod deserializer;
3use crate::static_btree::Offset;
4use city_buffer::*;
5use cjseq::CityJSONFeature;
6use deserializer::to_cj_feature;
7
8use crate::error::Error;
9use crate::fb::{size_prefixed_root_as_city_feature, CityFeature};
10use crate::packed_rtree::{self, PackedRTree, Query};
11use crate::{check_magic_bytes, size_prefixed_root_as_header, Header, HEADER_MAX_BUFFER_SIZE};
12use fallible_streaming_iterator::FallibleStreamingIterator;
13use std::io::{self, Read, Seek, SeekFrom, Write};
14mod attr_query;
15pub mod geom_decoder;
16pub use attr_query::*;
17use std::marker::PhantomData;
18mod meta;
19pub use meta::{Column as MetaColumn, ColumnType as MetaColumnType, Meta};
20
21pub struct FcbReader<R> {
22 reader: R,
23 verify: bool,
24 buffer: FcbBuffer,
25}
26
27pub struct FeatureIter<R, S> {
28 reader: R,
29 verify: bool,
31 buffer: FcbBuffer,
34 item_filter: Option<Vec<packed_rtree::SearchResultItem>>,
36 item_attr_filter: Option<Vec<Offset>>,
38 count: Option<usize>,
40 feat_no: usize,
42 cur_pos: u64,
44 state: State,
46 seekable_marker: PhantomData<S>,
48 feature_offset: FeatureOffset,
49 total_feat_count: u64,
50}
51
52#[doc(hidden)]
53pub(super) struct FeatureOffset {
54 magic_bytes: u64,
55 header: u64,
56 rtree_index: u64,
57 attributes: u64,
58}
59
60#[derive(Debug, PartialEq, Eq)]
61enum State {
62 Init,
63 ReadFirstFeatureSize,
64 Reading,
65 Finished,
66}
67
68#[doc(hidden)]
69pub mod reader_trait {
70 pub struct Seekable;
71 pub struct NotSeekable;
72}
73use reader_trait::*;
74
75impl<R: Read> FcbReader<R> {
76 pub fn open(reader: R) -> Result<FcbReader<R>, Error> {
77 let reader = Self::read_header(reader, true)?;
78 Ok(reader)
79 }
80
81 pub unsafe fn open_unchecked(reader: R) -> Result<FcbReader<R>, Error> {
87 Self::read_header(reader, false)
88 }
89
90 fn read_header(mut reader: R, verify: bool) -> Result<FcbReader<R>, Error> {
91 let mut magic_buf: [u8; 8] = [0; 8];
92 reader.read_exact(&mut magic_buf)?;
93 if !check_magic_bytes(&magic_buf) {
94 return Err(Error::MissingMagicBytes);
95 }
96
97 let mut size_buf: [u8; 4] = [0; 4]; reader.read_exact(&mut size_buf)?;
99 let header_size = u32::from_le_bytes(size_buf) as usize;
100 if !((8..=HEADER_MAX_BUFFER_SIZE).contains(&header_size)) {
101 return Err(Error::IllegalHeaderSize(header_size));
102 }
103
104 let mut header_buf = Vec::with_capacity(header_size + 4); header_buf.extend_from_slice(&size_buf);
106 header_buf.resize(header_buf.capacity(), 0);
107 reader.read_exact(&mut header_buf[4..])?;
108
109 if verify {
110 let _header = size_prefixed_root_as_header(&header_buf);
111 }
112
113 Ok(FcbReader {
114 reader,
115 verify,
116 buffer: FcbBuffer {
117 header_buf,
118 features_buf: Vec::new(),
119 },
120 })
121 }
122
123 pub fn select_all_seq(mut self) -> Result<FeatureIter<R, NotSeekable>, Error> {
124 let index_size = self.attr_index_size() + self.rtree_index_size();
125 io::copy(&mut (&mut self.reader).take(index_size), &mut io::sink())?;
127 let feature_offset = FeatureOffset {
128 magic_bytes: 8,
129 header: 4 + self.buffer.header_buf.len() as u64,
130 rtree_index: self.rtree_index_size(),
131 attributes: self.attr_index_size(),
132 };
133 let total_feat_count = self.buffer.header().features_count();
134 Ok(FeatureIter::new(
135 self.reader,
136 self.verify,
137 self.buffer,
138 None,
139 None,
140 feature_offset,
141 total_feat_count,
142 ))
143 }
144
145 pub fn select_query_seq(mut self, query: Query) -> Result<FeatureIter<R, NotSeekable>, Error> {
146 let header = self.buffer.header();
148 if header.index_node_size() == 0 || header.features_count() == 0 {
149 return Err(Error::NoIndex);
150 }
151 let index = PackedRTree::from_buf(
152 &mut self.reader,
153 header.features_count() as usize,
154 header.index_node_size(),
155 )?;
156 let list = index.search(query)?;
157 debug_assert!(
158 list.windows(2).all(|w| w[0].offset < w[1].offset),
159 "Since the tree is traversed breadth first, list should be sorted by construction."
160 );
161 let index_size = self.attr_index_size();
163 io::copy(&mut (&mut self.reader).take(index_size), &mut io::sink())?;
164 let feature_offset = FeatureOffset {
165 magic_bytes: 8,
166 header: 4 + self.buffer.header_buf.len() as u64,
167 rtree_index: self.rtree_index_size(),
168 attributes: self.attr_index_size(),
169 };
170 let total_feat_count = list.len() as u64;
171 Ok(FeatureIter::new(
172 self.reader,
173 self.verify,
174 self.buffer,
175 Some(list),
176 None,
177 feature_offset,
178 total_feat_count,
179 ))
180 }
181}
182
183impl<R: Read + Seek> FcbReader<R> {
184 pub fn select_all(mut self) -> Result<FeatureIter<R, Seekable>, Error> {
185 let feature_offset = FeatureOffset {
187 magic_bytes: 8,
188 header: 4 + self.buffer.header_buf.len() as u64,
189 rtree_index: self.rtree_index_size(),
190 attributes: self.attr_index_size(),
191 };
192 let index_size = self.attr_index_size() + self.rtree_index_size();
193 self.reader.seek(SeekFrom::Current(index_size as i64))?;
194 let total_feat_count = self.buffer.header().features_count();
195 Ok(FeatureIter::new(
196 self.reader,
197 self.verify,
198 self.buffer,
199 None,
200 None,
201 feature_offset,
202 total_feat_count,
203 ))
204 }
205
206 pub fn select_query(
207 mut self,
208 query: Query,
209 limit: Option<usize>,
210 offset: Option<usize>,
211 ) -> Result<FeatureIter<R, Seekable>, Error> {
212 let header = self.buffer.header();
214 if header.index_node_size() == 0 || header.features_count() == 0 {
215 return Err(Error::NoIndex);
216 }
217 let list = PackedRTree::stream_search(
220 &mut self.reader,
221 header.features_count() as usize,
222 header.index_node_size(),
223 query,
224 )?;
225 let list: Vec<_> = list
226 .into_iter()
227 .skip(offset.unwrap_or(0))
228 .take(limit.unwrap_or(usize::MAX))
229 .collect();
230 debug_assert!(
231 list.windows(2).all(|w| w[0].offset < w[1].offset),
232 "Since the tree is traversed breadth first, list should be sorted by construction."
233 );
234
235 self.reader
237 .seek(SeekFrom::Current(self.attr_index_size() as i64))?;
238 let feature_offset = FeatureOffset {
239 magic_bytes: 8,
240 header: 4 + self.buffer.header_buf.len() as u64,
241 rtree_index: self.rtree_index_size(),
242 attributes: self.attr_index_size(),
243 };
244 let total_feat_count = list.len() as u64;
245 Ok(FeatureIter::new(
246 self.reader,
247 self.verify,
248 self.buffer,
249 Some(list),
250 None,
251 feature_offset,
252 total_feat_count,
253 ))
254 }
255}
256
257impl<R: Read> FcbReader<R> {
258 pub fn header(&self) -> Header<'_> {
259 self.buffer.header()
260 }
261
262 pub fn root_attr_schema(
263 &self,
264 ) -> Option<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<crate::fb::Column<'_>>>> {
265 self.buffer.header().columns()
266 }
267
268 fn rtree_index_size(&self) -> u64 {
269 let header = self.buffer.header();
270 let feat_count = header.features_count() as usize;
271 if header.index_node_size() > 0 && feat_count > 0 {
272 PackedRTree::index_size(feat_count, header.index_node_size()) as u64
273 } else {
274 0
275 }
276 }
277
278 fn attr_index_size(&self) -> u64 {
279 let header = self.buffer.header();
280 let len = header
281 .attribute_index()
282 .map(|attr_index| {
283 attr_index
284 .iter()
285 .try_fold(0u64, |acc, ai| {
286 let len = ai.length() as u64;
287 if len > u64::MAX - acc {
288 Err(Error::AttributeIndexSizeOverflow)
289 } else {
290 Ok(acc + len)
291 }
292 })
293 .unwrap_or(0)
294 })
295 .unwrap_or(0);
296 len
297 }
298}
299
300impl FeatureOffset {
301 fn total_size(&self) -> u64 {
302 self.magic_bytes + self.header + self.rtree_index + self.attributes
303 }
304}
305
306impl<R: Read> FallibleStreamingIterator for FeatureIter<R, NotSeekable> {
307 type Item = FcbBuffer;
308 type Error = Error;
309
310 fn advance(&mut self) -> Result<(), Error> {
311 if self.advance_finished() {
312 return Ok(());
313 }
314 if let Some(filter) = &self.item_filter {
315 let item = &filter[self.feat_no];
316 if item.offset as u64 > self.cur_pos {
317 if self.state == State::ReadFirstFeatureSize {
318 self.state = State::Reading;
319 }
320 let seek_bytes = item.offset as u64 - self.cur_pos;
322 io::copy(&mut (&mut self.reader).take(seek_bytes), &mut io::sink())?;
323 self.cur_pos += seek_bytes;
324 }
325 }
326
327 if let Some(attr_filter) = &self.item_attr_filter {
328 let item_offset = attr_filter[self.feat_no];
329 if item_offset > self.cur_pos {
331 if self.state == State::ReadFirstFeatureSize {
332 self.state = State::Reading;
333 }
334 let seek_bytes = item_offset - self.cur_pos;
335 io::copy(&mut (&mut self.reader).take(seek_bytes), &mut io::sink())?;
336 self.cur_pos += seek_bytes;
337 }
338 }
339
340 self.read_feature()
341 }
342
343 fn get(&self) -> Option<&FcbBuffer> {
344 self.iter_get()
345 }
346
347 fn size_hint(&self) -> (usize, Option<usize>) {
348 self.iter_size_hint()
349 }
350}
351
352impl<R: Read + Seek> FallibleStreamingIterator for FeatureIter<R, Seekable> {
353 type Item = FcbBuffer;
354 type Error = Error;
355
356 fn advance(&mut self) -> Result<(), Error> {
357 if self.advance_finished() {
358 return Ok(());
359 }
360 if let Some(filter) = &self.item_filter {
361 let item = &filter[self.feat_no];
362 if item.offset as u64 > self.cur_pos {
363 if self.state == State::ReadFirstFeatureSize {
364 self.state = State::Reading;
365 }
366 let seek_bytes = item.offset as u64 - self.cur_pos;
368 self.reader.seek(SeekFrom::Current(seek_bytes as i64))?;
369 self.cur_pos += seek_bytes;
370 }
371 }
372
373 if let Some(attr_filter) = &self.item_attr_filter {
374 if self.state == State::ReadFirstFeatureSize {
375 self.state = State::Reading;
376 }
377 let item_offset = attr_filter[self.feat_no];
378 self.reader.seek(SeekFrom::Start(
379 self.feature_offset.total_size() + item_offset,
380 ))?;
381 self.cur_pos = item_offset;
382 }
383
384 self.read_feature()
385 }
386
387 fn get(&self) -> Option<&FcbBuffer> {
388 self.iter_get()
389 }
390
391 fn size_hint(&self) -> (usize, Option<usize>) {
392 self.iter_size_hint()
393 }
394}
395
396impl<R: Read> FeatureIter<R, NotSeekable> {
397 pub fn cur_feature(&self) -> CityFeature<'_> {
398 self.buffer.feature()
399 }
400
401 pub fn cur_cj_feature(&self) -> Result<CityJSONFeature, Error> {
402 let fcb_feature = self.buffer.feature();
403 let root_attr_schema = self.buffer.header().columns();
404 let semantic_attr_schema = self.buffer.header().semantic_columns();
405
406 to_cj_feature(fcb_feature, root_attr_schema, semantic_attr_schema)
407 }
408
409 pub fn get_features(&mut self) -> Result<Vec<CityFeature<'_>>, Error> {
410 todo!("implement")
412 }
413
414 #[allow(clippy::should_implement_trait)]
415 pub fn next(&mut self) -> Result<Option<&Self>, Error> {
416 self.advance()?;
417 if self.get().is_some() {
418 Ok(Some(self))
419 } else {
420 Ok(None)
421 }
422 }
423}
424
425impl<R: Read + Seek> FeatureIter<R, Seekable> {
426 pub fn cur_feature(&self) -> CityFeature<'_> {
427 self.buffer.feature()
428 }
429 pub fn cur_feature_len(&self) -> usize {
430 self.buffer.features_buf.len()
431 }
432 pub fn cur_cj_feature(&self) -> Result<CityJSONFeature, Error> {
434 let fcb_feature = self.buffer.feature();
435 let root_attr_schema = self.buffer.header().columns();
436 let semantic_attr_schema = self.buffer.header().semantic_columns();
437 to_cj_feature(fcb_feature, root_attr_schema, semantic_attr_schema)
438 }
439
440 pub fn get_features(&mut self, _: impl Write) -> Result<(), Error> {
441 todo!("implement")
442 }
443
444 pub fn get_current_feature(&self) -> CityFeature<'_> {
445 self.buffer.feature()
446 }
447
448 #[allow(clippy::should_implement_trait)]
449 pub fn next(&mut self) -> Result<Option<&Self>, Error> {
450 self.advance()?;
451 if self.get().is_some() {
452 Ok(Some(self))
453 } else {
454 Ok(None)
455 }
456 }
457}
458
459impl<R: Read, S> FeatureIter<R, S> {
460 pub(super) fn new(
461 reader: R,
462 verify: bool,
463 buffer: FcbBuffer,
464 item_filter: Option<Vec<packed_rtree::SearchResultItem>>,
465 item_attr_filter: Option<Vec<Offset>>,
466 feature_offset: FeatureOffset,
467 total_feat_count: u64,
468 ) -> FeatureIter<R, S> {
469 let mut iter = FeatureIter {
470 reader,
471 verify,
472 buffer,
473 item_filter,
474 item_attr_filter,
475 count: None,
476 feat_no: 0,
477 cur_pos: 0,
478 state: State::Init,
479 seekable_marker: PhantomData,
480 feature_offset,
481 total_feat_count,
482 };
483
484 if iter.read_feature_size() {
485 iter.state = State::Finished;
486 } else {
487 iter.state = State::ReadFirstFeatureSize
488 }
489
490 iter.count = match &iter.item_filter {
491 Some(list) => Some(list.len()),
492 None => {
493 let feat_count = iter.buffer.header().features_count() as usize;
494 if feat_count > 0 {
495 Some(feat_count)
496 } else if iter.state == State::Finished {
497 Some(0)
498 } else {
499 None
500 }
501 }
502 };
503
504 iter
505 }
506
507 pub fn header(&self) -> Header<'_> {
508 self.buffer.header()
509 }
510
511 pub fn root_attr_schema(
512 &self,
513 ) -> Option<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<crate::fb::Column<'_>>>> {
514 self.buffer.header().columns()
515 }
516
517 pub fn features_count(&self) -> Option<usize> {
518 Some(self.total_feat_count as usize)
519 }
520
521 fn advance_finished(&mut self) -> bool {
522 if self.state == State::Finished {
523 return true;
524 }
525 if let Some(count) = self.count {
526 if self.feat_no >= count {
527 self.state = State::Finished;
528 return true;
529 }
530 }
531 if let Some(attr_filter) = &self.item_attr_filter {
532 if self.feat_no >= attr_filter.len() {
533 self.state = State::Finished;
534 return true;
535 }
536 }
537 false
538 }
539
540 fn read_feature_size(&mut self) -> bool {
542 self.buffer.features_buf.resize(4, 0);
543 self.cur_pos += 4;
544 self.reader
545 .read_exact(&mut self.buffer.features_buf)
546 .is_err()
547 }
548
549 fn read_feature(&mut self) -> Result<(), Error> {
550 match self.state {
551 State::ReadFirstFeatureSize => {
552 self.state = State::Reading;
553 }
554 State::Reading => {
555 if self.read_feature_size() {
556 self.state = State::Finished;
557 return Ok(());
558 }
559 }
560 State::Finished => {
561 debug_assert!(
562 false,
563 "shouldn't call read_feature on already finished Iter"
564 );
565 return Ok(());
566 }
567 State::Init => {
568 unreachable!("should have read first feature size before reading any features")
569 }
570 }
571 let sbuf = &self.buffer.features_buf;
572 let feature_size = u32::from_le_bytes([sbuf[0], sbuf[1], sbuf[2], sbuf[3]]) as usize;
573 self.buffer.features_buf.resize(feature_size + 4, 0);
574 self.reader.read_exact(&mut self.buffer.features_buf[4..])?;
575 if self.verify {
576 let _feature = size_prefixed_root_as_city_feature(&self.buffer.features_buf)?;
577 }
578 self.feat_no += 1;
579 self.cur_pos += feature_size as u64;
580
581 Ok(())
582 }
583
584 fn iter_get(&self) -> Option<&FcbBuffer> {
585 if self.state == State::Finished {
586 None
587 } else {
588 debug_assert!(self.state == State::Reading);
589 Some(&self.buffer)
590 }
591 }
592
593 fn iter_size_hint(&self) -> (usize, Option<usize>) {
594 if self.state == State::Finished {
595 (0, Some(0))
596 } else if let Some(count) = self.count {
597 let remaining = count - self.feat_no;
598 (remaining, Some(remaining))
599 } else {
600 (0, None)
601 }
602 }
603}