summaryrefslogtreecommitdiff
path: root/src/mbgl
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-06-10 21:17:23 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-06-13 17:22:05 -0700
commit282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a (patch)
treef83ef7974687a84341dd616b364b2aa5a9c012a8 /src/mbgl
parent36bef2157595e1455aa55c64c6c526f096dd1c8e (diff)
downloadqtlocation-mapboxgl-282e626ac112b1ca7a9bf9f9d4c0239db8fbd97a.tar.gz
[core] Make enum ↔ string conversion more generic-friendly
Rewrite enum.hpp in such a way that parseConstant can be defined generically for all enumerated types. While there, properly validated enumerated property values.
Diffstat (limited to 'src/mbgl')
-rw-r--r--src/mbgl/platform/event.cpp34
-rw-r--r--src/mbgl/platform/log.cpp3
-rw-r--r--src/mbgl/style/parser.cpp33
-rw-r--r--src/mbgl/style/property_parsing.cpp148
-rw-r--r--src/mbgl/style/property_parsing.hpp28
-rw-r--r--src/mbgl/style/source.cpp4
-rw-r--r--src/mbgl/style/types.cpp80
7 files changed, 157 insertions, 173 deletions
diff --git a/src/mbgl/platform/event.cpp b/src/mbgl/platform/event.cpp
new file mode 100644
index 0000000000..68d75a2941
--- /dev/null
+++ b/src/mbgl/platform/event.cpp
@@ -0,0 +1,34 @@
+#include <mbgl/platform/event.hpp>
+#include <mbgl/util/enum.hpp>
+
+namespace mbgl {
+
+MBGL_DEFINE_ENUM(EventSeverity, {
+ { EventSeverity::Debug, "DEBUG" },
+ { EventSeverity::Info, "INFO" },
+ { EventSeverity::Warning, "WARNING" },
+ { EventSeverity::Error, "ERROR" },
+ { EventSeverity(-1), "UNKNOWN" },
+});
+
+MBGL_DEFINE_ENUM(Event, {
+ { Event::General, "General" },
+ { Event::Setup, "Setup" },
+ { Event::Shader, "Shader" },
+ { Event::ParseStyle, "ParseStyle" },
+ { Event::ParseTile, "ParseTile" },
+ { Event::Render, "Render" },
+ { Event::Style, "Style" },
+ { Event::Database, "Database" },
+ { Event::HttpRequest, "HttpRequest" },
+ { Event::Sprite, "Sprite" },
+ { Event::Image, "Image" },
+ { Event::OpenGL, "OpenGL" },
+ { Event::JNI, "JNI" },
+ { Event::Android, "Android" },
+ { Event::Crash, "Crash" },
+ { Event::Glyph, "Glyph" },
+ { Event(-1), "Unknown" },
+});
+
+} // namespace mbgl
diff --git a/src/mbgl/platform/log.cpp b/src/mbgl/platform/log.cpp
index 2118511592..4b56435df0 100644
--- a/src/mbgl/platform/log.cpp
+++ b/src/mbgl/platform/log.cpp
@@ -1,4 +1,5 @@
#include <mbgl/platform/log.hpp>
+#include <mbgl/util/enum.hpp>
#include <cstdio>
#include <cstdarg>
@@ -54,7 +55,7 @@ void Log::record(EventSeverity severity, Event event, int64_t code, const std::s
logStream << "{" << name << "}";
#endif
- logStream << "[" << event << "]";
+ logStream << "[" << Enum<Event>::toString(event) << "]";
if (code >= 0) {
logStream << "(" << code << ")";
diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp
index 8e632ac6a0..870fd6d71e 100644
--- a/src/mbgl/style/parser.cpp
+++ b/src/mbgl/style/parser.cpp
@@ -14,6 +14,7 @@
#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/util/mapbox.hpp>
+#include <mbgl/util/enum.hpp>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>
@@ -161,11 +162,15 @@ void Parser::parseSources(const JSValue& value) {
const JSValue& typeVal = sourceVal["type"];
if (!typeVal.IsString()) {
- Log::Warning(Event::ParseStyle, "source type must have one of the enum values");
+ Log::Warning(Event::ParseStyle, "source type must be a string");
continue;
}
- const auto type = SourceTypeClass({ typeVal.GetString(), typeVal.GetStringLength() });
+ const auto type = Enum<SourceType>::toEnum({ typeVal.GetString(), typeVal.GetStringLength() });
+ if (!type) {
+ Log::Warning(Event::ParseStyle, "source type must have one of the enum values");
+ continue;
+ }
// Sources can have URLs, either because they reference an external TileJSON file, or
// because reference a GeoJSON file. They don't have to have one though when all source
@@ -177,7 +182,7 @@ void Parser::parseSources(const JSValue& value) {
std::unique_ptr<Tileset> tileset;
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
- switch (type) {
+ switch (*type) {
case SourceType::Raster:
if (sourceVal.HasMember("tileSize")) {
const JSValue& tileSizeVal = sourceVal["tileSize"];
@@ -236,7 +241,7 @@ void Parser::parseSources(const JSValue& value) {
}
const std::string id { nameVal.GetString(), nameVal.GetStringLength() };
- std::unique_ptr<Source> source = std::make_unique<Source>(type, id, url, tileSize, std::move(tileset), std::move(geojsonvt));
+ std::unique_ptr<Source> source = std::make_unique<Source>(*type, id, url, tileSize, std::move(tileset), std::move(geojsonvt));
sourcesMap.emplace(id, source.get());
sources.emplace_back(std::move(source));
@@ -481,21 +486,25 @@ void Parser::parseLayer(const std::string& id, const JSValue& value, std::unique
}
}
-MBGL_DEFINE_ENUM_CLASS(VisibilityTypeClass, VisibilityType, {
- { VisibilityType::Visible, "visible" },
- { VisibilityType::None, "none" },
-})
-
void Parser::parseVisibility(Layer& layer, const JSValue& value) {
Layer::Impl& impl = *layer.baseImpl;
+
if (!value.HasMember("visibility")) {
return;
- } else if (!value["visibility"].IsString()) {
+ }
+
+ if (!value["visibility"].IsString()) {
Log::Warning(Event::ParseStyle, "value of 'visibility' must be a string");
- impl.visibility = VisibilityType::Visible;
return;
}
- impl.visibility = VisibilityTypeClass({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
+
+ const auto enumValue = Enum<VisibilityType>::toEnum({ value["visibility"].GetString(), value["visibility"].GetStringLength() });
+ if (!enumValue) {
+ Log::Warning(Event::ParseStyle, "value of 'visibility' must be a valid enumeration value");
+ return;
+ }
+
+ impl.visibility = *enumValue;
}
Value parseFeatureType(const Value& value) {
diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp
index 6e5174e936..9985cc7f39 100644
--- a/src/mbgl/style/property_parsing.cpp
+++ b/src/mbgl/style/property_parsing.cpp
@@ -55,154 +55,6 @@ optional<Color> parseConstant(const char* name, const JSValue& value) {
css_color.a}};
}
-MBGL_DEFINE_ENUM_CLASS(TranslateAnchorTypeClass, TranslateAnchorType, {
- { TranslateAnchorType::Map, "map" },
- { TranslateAnchorType::Viewport, "viewport" },
-})
-
-template <>
-optional<TranslateAnchorType> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { TranslateAnchorTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(RotateAnchorTypeClass, RotateAnchorType, {
- { RotateAnchorType::Map, "map" },
- { RotateAnchorType::Viewport, "viewport" },
-})
-
-template <>
-optional<RotateAnchorType> parseConstant<RotateAnchorType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { RotateAnchorTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(LineCapTypeClass, LineCapType, {
- { LineCapType::Round, "round" },
- { LineCapType::Butt, "butt" },
- { LineCapType::Square, "square" },
-})
-
-template <>
-optional<LineCapType> parseConstant<LineCapType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { LineCapTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(LineJoinTypeClass, LineJoinType, {
- { LineJoinType::Miter, "miter" },
- { LineJoinType::Bevel, "bevel" },
- { LineJoinType::Round, "round" },
- { LineJoinType::FakeRound, "fakeround" },
- { LineJoinType::FlipBevel, "flipbevel" },
-})
-
-template <>
-optional<LineJoinType> parseConstant<LineJoinType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { LineJoinTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(SymbolPlacementTypeClass, SymbolPlacementType, {
- { SymbolPlacementType::Point, "point" },
- { SymbolPlacementType::Line, "line" },
-})
-
-template <>
-optional<SymbolPlacementType> parseConstant<SymbolPlacementType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { SymbolPlacementTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(TextAnchorTypeClass, TextAnchorType, {
- { TextAnchorType::Center, "center" },
- { TextAnchorType::Left, "left" },
- { TextAnchorType::Right, "right" },
- { TextAnchorType::Top, "top" },
- { TextAnchorType::Bottom, "bottom" },
- { TextAnchorType::TopLeft, "top-left" },
- { TextAnchorType::TopRight, "top-right" },
- { TextAnchorType::BottomLeft, "bottom-left" },
- { TextAnchorType::BottomRight, "bottom-right" }
-})
-
-template <>
-optional<TextAnchorType> parseConstant<TextAnchorType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { TextAnchorTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(TextJustifyTypeClass, TextJustifyType, {
- { TextJustifyType::Center, "center" },
- { TextJustifyType::Left, "left" },
- { TextJustifyType::Right, "right" },
-})
-
-template <>
-optional<TextJustifyType> parseConstant<TextJustifyType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { TextJustifyTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(TextTransformTypeClass, TextTransformType, {
- { TextTransformType::None, "none" },
- { TextTransformType::Uppercase, "uppercase" },
- { TextTransformType::Lowercase, "lowercase" },
-})
-
-template <>
-optional<TextTransformType> parseConstant<TextTransformType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { TextTransformTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
-MBGL_DEFINE_ENUM_CLASS(AlignmentTypeClass, AlignmentType, {
- { AlignmentType::Map, "map" },
- { AlignmentType::Viewport, "viewport" },
-})
-
-template <>
-optional<AlignmentType> parseConstant<AlignmentType>(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return { AlignmentTypeClass({ value.GetString(), value.GetStringLength() }) };
-}
-
template <>
optional<std::array<float, 2>> parseConstant(const char* name, const JSValue& value) {
if (value.IsArray() && value.Size() == 2 &&
diff --git a/src/mbgl/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp
index d2d283fe17..d27a9e5031 100644
--- a/src/mbgl/style/property_parsing.hpp
+++ b/src/mbgl/style/property_parsing.hpp
@@ -7,6 +7,7 @@
#include <mbgl/util/rapidjson.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/color.hpp>
+#include <mbgl/util/enum.hpp>
#include <mbgl/platform/log.hpp>
@@ -17,27 +18,34 @@
namespace mbgl {
namespace style {
-template <typename T>
+template <typename T, typename = std::enable_if_t<!std::is_enum<T>::value>>
optional<T> parseConstant(const char* name, const JSValue&);
template <> optional<bool> parseConstant(const char*, const JSValue&);
template <> optional<float> parseConstant(const char*, const JSValue&);
template <> optional<std::string> parseConstant(const char*, const JSValue&);
template <> optional<Color> parseConstant(const char*, const JSValue&);
-template <> optional<TranslateAnchorType> parseConstant(const char*, const JSValue&);
-template <> optional<RotateAnchorType> parseConstant(const char*, const JSValue&);
-template <> optional<LineCapType> parseConstant(const char*, const JSValue&);
-template <> optional<LineJoinType> parseConstant(const char*, const JSValue&);
-template <> optional<SymbolPlacementType> parseConstant(const char*, const JSValue&);
-template <> optional<TextAnchorType> parseConstant(const char*, const JSValue&);
-template <> optional<TextJustifyType> parseConstant(const char*, const JSValue&);
-template <> optional<TextTransformType> parseConstant(const char*, const JSValue&);
-template <> optional<AlignmentType> parseConstant(const char*, const JSValue&);
template <> optional<std::array<float, 2>> parseConstant(const char*, const JSValue&);
template <> optional<std::vector<float>> parseConstant(const char*, const JSValue&);
template <> optional<std::vector<std::string>> parseConstant(const char*, const JSValue&);
template <typename T>
+optional<T> parseConstant(const char* name, const JSValue& value,
+ typename std::enable_if_t<std::is_enum<T>::value, void*> = nullptr) {
+ if (!value.IsString()) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
+ return {};
+ }
+
+ const auto result = Enum<T>::toEnum({ value.GetString(), value.GetStringLength() });
+ if (!result) {
+ Log::Warning(Event::ParseStyle, "value of '%s' must be a valid enumeration value", name);
+ }
+
+ return result;
+}
+
+template <typename T>
PropertyValue<T> parseProperty(const char* name, const JSValue& value) {
if (!value.IsObject()) {
auto constant = parseConstant<T>(name, value);
diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp
index 544d230a25..bffb6a8fcc 100644
--- a/src/mbgl/style/source.cpp
+++ b/src/mbgl/style/source.cpp
@@ -18,6 +18,7 @@
#include <mbgl/util/token.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/tile_cover.hpp>
+#include <mbgl/util/enum.hpp>
#include <mbgl/tile/raster_tile.hpp>
#include <mbgl/tile/geojson_tile.hpp>
@@ -197,8 +198,7 @@ std::unique_ptr<Tile> Source::createTile(const OverscaledTileID& overscaledTileI
} else if (type == SourceType::GeoJSON) {
return std::make_unique<GeoJSONTile>(overscaledTileID, id, parameters, geojsonvt.get());
} else {
- Log::Warning(Event::Style, "Source type '%s' is not implemented",
- SourceTypeClass(type).c_str());
+ Log::Warning(Event::Style, "Source type '%s' is not implemented", Enum<SourceType>::toString(type));
return nullptr;
}
}
diff --git a/src/mbgl/style/types.cpp b/src/mbgl/style/types.cpp
new file mode 100644
index 0000000000..d292d2d5b4
--- /dev/null
+++ b/src/mbgl/style/types.cpp
@@ -0,0 +1,80 @@
+#include <mbgl/style/types.hpp>
+#include <mbgl/util/enum.hpp>
+
+namespace mbgl {
+
+using namespace style;
+
+MBGL_DEFINE_ENUM(SourceType, {
+ { SourceType::Vector, "vector" },
+ { SourceType::Raster, "raster" },
+ { SourceType::GeoJSON, "geojson" },
+ { SourceType::Video, "video" },
+ { SourceType::Annotations, "annotations" },
+});
+
+MBGL_DEFINE_ENUM(VisibilityType, {
+ { VisibilityType::Visible, "visible" },
+ { VisibilityType::None, "none" },
+});
+
+MBGL_DEFINE_ENUM(TranslateAnchorType, {
+ { TranslateAnchorType::Map, "map" },
+ { TranslateAnchorType::Viewport, "viewport" },
+});
+
+MBGL_DEFINE_ENUM(RotateAnchorType, {
+ { RotateAnchorType::Map, "map" },
+ { RotateAnchorType::Viewport, "viewport" },
+});
+
+MBGL_DEFINE_ENUM(LineCapType, {
+ { LineCapType::Round, "round" },
+ { LineCapType::Butt, "butt" },
+ { LineCapType::Square, "square" },
+});
+
+MBGL_DEFINE_ENUM(LineJoinType, {
+ { LineJoinType::Miter, "miter" },
+ { LineJoinType::Bevel, "bevel" },
+ { LineJoinType::Round, "round" },
+ { LineJoinType::FakeRound, "fakeround" },
+ { LineJoinType::FlipBevel, "flipbevel" },
+});
+
+MBGL_DEFINE_ENUM(SymbolPlacementType, {
+ { SymbolPlacementType::Point, "point" },
+ { SymbolPlacementType::Line, "line" },
+});
+
+MBGL_DEFINE_ENUM(TextAnchorType, {
+ { TextAnchorType::Center, "center" },
+ { TextAnchorType::Left, "left" },
+ { TextAnchorType::Right, "right" },
+ { TextAnchorType::Top, "top" },
+ { TextAnchorType::Bottom, "bottom" },
+ { TextAnchorType::TopLeft, "top-left" },
+ { TextAnchorType::TopRight, "top-right" },
+ { TextAnchorType::BottomLeft, "bottom-left" },
+ { TextAnchorType::BottomRight, "bottom-right" }
+});
+
+MBGL_DEFINE_ENUM(TextJustifyType, {
+ { TextJustifyType::Center, "center" },
+ { TextJustifyType::Left, "left" },
+ { TextJustifyType::Right, "right" },
+});
+
+MBGL_DEFINE_ENUM(TextTransformType, {
+ { TextTransformType::None, "none" },
+ { TextTransformType::Uppercase, "uppercase" },
+ { TextTransformType::Lowercase, "lowercase" },
+});
+
+MBGL_DEFINE_ENUM(AlignmentType, {
+ { AlignmentType::Map, "map" },
+ { AlignmentType::Viewport, "viewport" },
+ { AlignmentType::Undefined, "undefined" },
+});
+
+} // namespace mbgl