[core] port to protozero (#4906)

This commit is contained in:
Dane Springmeyer
2016-05-03 13:57:17 -07:00
parent 7d1a4c5ec1
commit c82b02c508
14 changed files with 119 additions and 280 deletions

View File

@@ -9,25 +9,24 @@
namespace mbgl {
Value parseValue(pbf data) {
Value parseValue(protozero::pbf_reader data) {
while (data.next())
{
switch (data.tag)
{
switch (data.tag()) {
case 1: // string_value
return data.string();
return data.get_string();
case 2: // float_value
return static_cast<double>(data.float32());
return static_cast<double>(data.get_float());
case 3: // double_value
return data.float64();
return data.get_double();
case 4: // int_value
return data.varint<int64_t>();
return data.get_int64();
case 5: // uint_value
return data.varint<uint64_t>();
return data.get_uint64();
case 6: // sint_value
return data.svarint<int64_t>();
return data.get_sint64();
case 7: // bool_value
return data.boolean();
return data.get_bool();
default:
data.skip();
break;
@@ -36,19 +35,25 @@ Value parseValue(pbf data) {
return false;
}
VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& layer_)
VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, const VectorTileLayer& layer_)
: layer(layer_) {
while (feature_pbf.next()) {
if (feature_pbf.tag == 1) { // id
id = feature_pbf.varint<uint64_t>();
} else if (feature_pbf.tag == 2) { // tags
tags_pbf = feature_pbf.message();
} else if (feature_pbf.tag == 3) { // type
type = (FeatureType)feature_pbf.varint();
} else if (feature_pbf.tag == 4) { // geometry
geometry_pbf = feature_pbf.message();
} else {
switch (feature_pbf.tag()) {
case 1: // id
id = feature_pbf.get_uint64();
break;
case 2: // tags
tags_iter = feature_pbf.get_packed_uint32();
break;
case 3: // type
type = static_cast<FeatureType>(feature_pbf.get_enum());
break;
case 4: // geometry
geometry_iter = feature_pbf.get_packed_uint32();
break;
default:
feature_pbf.skip();
break;
}
}
}
@@ -59,19 +64,20 @@ optional<Value> VectorTileFeature::getValue(const std::string& key) const {
return optional<Value>();
}
pbf tags = tags_pbf;
while (tags) {
uint32_t tag_key = tags.varint();
auto start_itr = tags_iter.first;
const auto & end_itr = tags_iter.second;
while (start_itr != end_itr) {
uint32_t tag_key = static_cast<uint32_t>(*start_itr++);
if (layer.keysMap.size() <= tag_key) {
throw std::runtime_error("feature referenced out of range key");
}
if (!tags) {
if (start_itr == end_itr) {
throw std::runtime_error("uneven number of feature tag ids");
}
uint32_t tag_val = tags.varint();
uint32_t tag_val = static_cast<uint32_t>(*start_itr++);;
if (layer.values.size() <= tag_val) {
throw std::runtime_error("feature referenced out of range value");
}
@@ -86,10 +92,11 @@ optional<Value> VectorTileFeature::getValue(const std::string& key) const {
std::unordered_map<std::string,Value> VectorTileFeature::getProperties() const {
std::unordered_map<std::string,Value> properties;
pbf tags = tags_pbf;
while (tags) {
uint32_t tag_key = tags.varint();
uint32_t tag_val = tags.varint();
auto start_itr = tags_iter.first;
const auto & end_itr = tags_iter.second;
while (start_itr != end_itr) {
uint32_t tag_key = static_cast<uint32_t>(*start_itr++);
uint32_t tag_val = static_cast<uint32_t>(*start_itr++);
properties[layer.keys.at(tag_key)] = layer.values.at(tag_val);
}
return properties;
@@ -100,7 +107,6 @@ uint64_t VectorTileFeature::getID() const {
}
GeometryCollection VectorTileFeature::getGeometries() const {
pbf data(geometry_pbf);
uint8_t cmd = 1;
uint32_t length = 0;
int32_t x = 0;
@@ -111,9 +117,10 @@ GeometryCollection VectorTileFeature::getGeometries() const {
lines.emplace_back();
GeometryCoordinates* line = &lines.back();
while (data.data < data.end) {
auto g_itr = geometry_iter;
while (g_itr.first != g_itr.second) {
if (length == 0) {
uint32_t cmd_length = data.varint();
uint32_t cmd_length = static_cast<uint32_t>(*g_itr.first++);
cmd = cmd_length & 0x7;
length = cmd_length >> 3;
}
@@ -121,8 +128,8 @@ GeometryCollection VectorTileFeature::getGeometries() const {
--length;
if (cmd == 1 || cmd == 2) {
x += data.svarint();
y += data.svarint();
x += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr.first++));
y += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr.first++));
if (cmd == 1 && !line->empty()) { // moveTo
lines.emplace_back();
@@ -155,14 +162,10 @@ VectorTile::VectorTile(std::shared_ptr<const std::string> data_)
util::ptr<GeometryTileLayer> VectorTile::getLayer(const std::string& name) const {
if (!parsed) {
parsed = true;
pbf tile_pbf(reinterpret_cast<const unsigned char *>(data->c_str()), data->size());
while (tile_pbf.next()) {
if (tile_pbf.tag == 3) { // layer
util::ptr<VectorTileLayer> layer = std::make_shared<VectorTileLayer>(tile_pbf.message());
layers.emplace(layer->name, layer);
} else {
tile_pbf.skip();
}
protozero::pbf_reader tile_pbf(*data);
while (tile_pbf.next(3)) {
util::ptr<VectorTileLayer> layer = std::make_shared<VectorTileLayer>(tile_pbf.get_message());
layers.emplace(layer->name, layer);
}
}
@@ -174,20 +177,27 @@ util::ptr<GeometryTileLayer> VectorTile::getLayer(const std::string& name) const
return nullptr;
}
VectorTileLayer::VectorTileLayer(pbf layer_pbf) {
VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf) {
while (layer_pbf.next()) {
if (layer_pbf.tag == 1) { // name
name = layer_pbf.string();
} else if (layer_pbf.tag == 2) { // feature
features.push_back(layer_pbf.message());
} else if (layer_pbf.tag == 3) { // keys
keysMap.emplace(layer_pbf.string(), keysMap.size());
} else if (layer_pbf.tag == 4) { // values
values.emplace_back(parseValue(layer_pbf.message()));
} else if (layer_pbf.tag == 5) { // extent
extent = layer_pbf.varint();
} else {
switch (layer_pbf.tag()) {
case 1: // name
name = layer_pbf.get_string();
break;
case 2: // feature
features.push_back(layer_pbf.get_message());
break;
case 3: // keys
keysMap.emplace(layer_pbf.get_string(), keysMap.size());
break;
case 4: // values
values.emplace_back(parseValue(layer_pbf.get_message()));
break;
case 5: // extent
extent = layer_pbf.get_uint32();
break;
default:
layer_pbf.skip();
break;
}
}