1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::codecs::varint::parse_varint;
#[cfg(feature = "unstable-v2")]
use crate::decoder::root02::parse_layer02;
use crate::decoder::{ColumnDecl, ColumnStorage, Layer01, ParsedLayer01, Unknown};
#[cfg(feature = "unstable-v2")]
use crate::decoder::{Layer02, ParsedLayer02};
use crate::utils::{parse_u8, take};
use crate::{
DecodeState, Decoder, Layer, Lazy, LazyParsed, MltError, MltRefResult, MltResult, ParsedLayer,
Parser,
};
impl<'a, S: DecodeState> Layer<'a, S> {
/// The layer's name whatever its tag, or `None` for a tag this build does not
/// know. A value, unlike a layer, cannot silently lose a version's columns.
#[must_use]
pub fn name(&self) -> Option<&'a str> {
match self {
Self::Tag01(l) => Some(l.name()),
#[cfg(feature = "unstable-v2")]
Self::Tag02(l) => Some(l.layer().name()),
Self::Unknown(_) => None,
}
}
}
impl<'a> Layer<'a> {
/// Parse a single tuple that consists of `size (varint)`, `tag (varint)`, and `value (bytes)`.
/// Reserves memory for decoded data against the parser's budget.
pub(crate) fn from_bytes(input: &'a [u8], parser: &mut Parser) -> MltRefResult<'a, Self> {
let (input, size) = parse_varint::<u32>(input)?;
// tag is a varint, but we know fewer than 127 tags for now,
// so we can use a faster u8 and fail if it is bigger than 127.
let (input, tag) = parse_u8(input)?;
// 1 byte must be parsed for the tag, so if size is 0, it's invalid
let size = size.checked_sub(1).ok_or(MltError::ZeroLayerSize)?;
let (input, value) = take(input, size)?;
let layer = match tag {
1 => Layer::Tag01(Layer01::from_bytes(value, parser)?),
#[cfg(feature = "unstable-v2")]
2 => Layer::Tag02(parse_layer02(value, parser)?),
tag => Layer::Unknown(Unknown { tag, value }),
};
Ok((input, layer))
}
/// Decode all columns and return a fully-decoded [`ParsedLayer`].
///
/// Consumes `self`. For partial / incremental decoding, destructure with
/// `Layer::Tag01(lazy)` and call the individual methods on [`Layer01`].
pub fn decode_all(self, dec: &mut Decoder) -> MltResult<ParsedLayer<'a>> {
match self {
Layer::Tag01(v) => Ok(Layer::Tag01(v.decode_all(dec)?)),
#[cfg(feature = "unstable-v2")]
Layer::Tag02(v) => Ok(Layer::Tag02(v.decode_all(dec)?)),
Layer::Unknown(u) => Ok(Layer::Unknown(u)),
}
}
}
impl<'a> Layer01<'a, Lazy> {
/// Call `cb` with the [`ColumnStorage`] of every column that has one to report.
///
/// Decoding a string column reconstructs its values, leaving nothing to say whether
/// they arrived plain, dictionary-coded, FSST-compressed or front-coded, so a caller
/// reporting on how a tile is stored has to ask before [`Self::decode_all`] runs.
pub fn for_each_column_storage(&self, cb: &mut dyn FnMut(ColumnStorage)) {
for column in &self.properties {
if let LazyParsed::Raw(raw) = column
&& let Some(storage) = raw.storage()
{
cb(storage);
}
}
}
/// Call `cb` with the [`ColumnDecl`] of every column the layer stores, id first.
///
/// Decoding resolves these away, so a caller reporting on a tile has to ask before
/// [`Self::decode_all`] runs.
pub fn for_each_column_decl(&self, cb: &mut dyn FnMut(ColumnDecl)) {
if let Some(LazyParsed::Raw(id)) = self.id.as_ref() {
cb(id.decl());
}
for column in &self.properties {
if let LazyParsed::Raw(raw) = column {
raw.for_each_decl(cb);
}
}
}
/// Decode all columns and transition to [`Layer01<Parsed>`].
///
/// Consumes `self` (a `Layer01<Lazy>`) and returns a `Layer01<Parsed>` where every
/// column field holds its parsed value directly, enabling infallible readonly access.
pub fn decode_all(self, dec: &mut Decoder) -> MltResult<ParsedLayer01<'a>> {
Ok(Layer01 {
name: self.name,
extent: self.extent,
id: self.id.map(|id| id.into_parsed(dec)).transpose()?,
geometry: self.geometry.into_parsed(dec)?,
properties: self
.properties
.into_iter()
.map(|p| p.into_parsed(dec))
.collect::<MltResult<Vec<_>>>()?,
#[cfg(fuzzing)]
layer_order: self.layer_order,
})
}
}
#[cfg(feature = "unstable-v2")]
impl<'a> Layer02<'a, Lazy> {
/// Decode every column, shared and v2-only.
pub fn decode_all(self, dec: &mut Decoder) -> MltResult<ParsedLayer02<'a>> {
let layer = Layer02 {
layer: self.layer.decode_all(dec)?,
nested: self
.nested
.into_iter()
.map(|n| n.into_parsed(dec))
.collect::<MltResult<Vec<_>>>()?,
m_values: self
.m_values
.into_iter()
.map(|m| m.into_parsed(dec))
.collect::<MltResult<Vec<_>>>()?,
layout: self.layout,
};
// An m-value column's length is only checkable once the geometry is decoded
// too, which it now is. Every later walk of a column relies on this check.
for column in &layer.m_values {
column.check_length(&layer.layer.geometry)?;
}
Ok(layer)
}
}