summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-06-19 20:05:05 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-06-21 15:38:13 -0700
commita18d6dda5de5247b14611a3bd901fdf65e13beeb (patch)
tree4f2266e499f38e4b9f4d1ad1a8e688c147a7f933 /src
parent7ea0a0db32300cac63775501bd92bb884ef550c4 (diff)
downloadqtlocation-mapboxgl-a18d6dda5de5247b14611a3bd901fdf65e13beeb.tar.gz
[core] Rewrite style parsing logic for reuse in node bindings
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/style/property_parsing.cpp128
-rw-r--r--src/mbgl/style/property_parsing.hpp106
-rw-r--r--src/mbgl/style/rapidjson_conversion.hpp55
3 files changed, 61 insertions, 228 deletions
diff --git a/src/mbgl/style/property_parsing.cpp b/src/mbgl/style/property_parsing.cpp
index 263516f201..16ce0f4adc 100644
--- a/src/mbgl/style/property_parsing.cpp
+++ b/src/mbgl/style/property_parsing.cpp
@@ -1,136 +1,8 @@
#include <mbgl/style/property_parsing.hpp>
-#include <mbgl/platform/log.hpp>
-
namespace mbgl {
namespace style {
-template <>
-optional<bool> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsBool()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a boolean", name);
- return {};
- }
-
- return value.GetBool();
-}
-
-template <>
-optional<float> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsNumber()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a number, or a number function", name);
- return {};
- }
-
- return value.GetDouble();
-}
-
-template <>
-optional<std::string> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- return std::string { value.GetString(), value.GetStringLength() };
-}
-
-template <>
-optional<Color> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a string", name);
- return {};
- }
-
- optional<Color> result = Color::parse({ value.GetString(), value.GetStringLength() });
- if (!result) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be a valid color", name);
- return {};
- }
-
- return result;
-}
-
-template <>
-optional<std::array<float, 2>> parseConstant(const char* name, const JSValue& value) {
- if (value.IsArray() && value.Size() == 2 &&
- value[rapidjson::SizeType(0)].IsNumber() &&
- value[rapidjson::SizeType(1)].IsNumber()) {
-
- float first = value[rapidjson::SizeType(0)].GetDouble();
- float second = value[rapidjson::SizeType(1)].GetDouble();
- return { {{ first, second }} };
- } else {
- Log::Warning(Event::ParseStyle, "value of '%s' must be an array of two numbers", name);
- return {};
- }
-}
-
-template <>
-optional<std::array<float, 4>> parseConstant(const char* name, const JSValue& value) {
- if (value.IsArray() && value.Size() == 4 &&
- value[rapidjson::SizeType(0)].IsNumber() &&
- value[rapidjson::SizeType(1)].IsNumber() &&
- value[rapidjson::SizeType(2)].IsNumber() &&
- value[rapidjson::SizeType(3)].IsNumber()) {
-
- float first = value[rapidjson::SizeType(0)].GetDouble();
- float second = value[rapidjson::SizeType(1)].GetDouble();
- float third = value[rapidjson::SizeType(2)].GetDouble();
- float fourth = value[rapidjson::SizeType(3)].GetDouble();
- return { {{ first, second, third, fourth }} };
- } else {
- Log::Warning(Event::ParseStyle, "value of '%s' must be an array of four numbers", name);
- return {};
- }
-}
-
-template <>
-optional<std::vector<float>> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsArray()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be an array of numbers", name);
- return {};
- }
-
- std::vector<float> result;
-
- for (rapidjson::SizeType i = 0; i < value.Size(); ++i) {
- const JSValue& part = value[i];
-
- if (!part.IsNumber()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be an array of numbers", name);
- return {};
- }
-
- result.push_back(part.GetDouble());
- }
-
- return result;
-}
-
-template <>
-optional<std::vector<std::string>> parseConstant(const char* name, const JSValue& value) {
- if (!value.IsArray()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be an array of strings", name);
- return {};
- }
-
- std::vector<std::string> result;
-
- for (rapidjson::SizeType i = 0; i < value.Size(); ++i) {
- const JSValue& part = value[i];
-
- if (!part.IsString()) {
- Log::Warning(Event::ParseStyle, "value of '%s' must be an array of strings", name);
- return {};
- }
-
- result.push_back({ part.GetString(), part.GetStringLength() });
- }
-
- return result;
-}
-
optional<TransitionOptions> parseTransitionOptions(const char *, const JSValue& value) {
if (!value.IsObject()) {
return {};
diff --git a/src/mbgl/style/property_parsing.hpp b/src/mbgl/style/property_parsing.hpp
index d27a9e5031..0c750ca298 100644
--- a/src/mbgl/style/property_parsing.hpp
+++ b/src/mbgl/style/property_parsing.hpp
@@ -1,117 +1,23 @@
#pragma once
-#include <mbgl/style/types.hpp>
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/transition_options.hpp>
-
-#include <mbgl/util/rapidjson.hpp>
-#include <mbgl/util/optional.hpp>
-#include <mbgl/util/color.hpp>
-#include <mbgl/util/enum.hpp>
+#include <mbgl/style/rapidjson_conversion.hpp>
+#include <mbgl/style/conversion.hpp>
#include <mbgl/platform/log.hpp>
-#include <string>
-#include <array>
-#include <vector>
-
namespace mbgl {
namespace style {
-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<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);
-
- if (!constant) {
- return {};
- }
-
- return *constant;
- }
-
- if (!value.HasMember("stops")) {
- Log::Warning(Event::ParseStyle, "function must specify a function type");
- return {};
- }
-
- float base = 1.0f;
-
- if (value.HasMember("base")) {
- const JSValue& value_base = value["base"];
-
- if (!value_base.IsNumber()) {
- Log::Warning(Event::ParseStyle, "base must be numeric");
- return {};
- }
-
- base = value_base.GetDouble();
- }
-
- const JSValue& stopsValue = value["stops"];
-
- if (!stopsValue.IsArray()) {
- Log::Warning(Event::ParseStyle, "stops function must specify a stops array");
+ conversion::Result<PropertyValue<T>> result = conversion::convertPropertyValue<T>(value);
+ if (result.template is<conversion::Error>()) {
+ Log::Warning(Event::ParseStyle, "%s: %s", name, result.template get<conversion::Error>().message);
return {};
}
-
- std::vector<std::pair<float, T>> stops;
-
- for (rapidjson::SizeType i = 0; i < stopsValue.Size(); ++i) {
- const JSValue& stop = stopsValue[i];
-
- if (!stop.IsArray()) {
- Log::Warning(Event::ParseStyle, "function argument must be a numeric value");
- return {};
- }
-
- if (stop.Size() != 2) {
- Log::Warning(Event::ParseStyle, "stop must have zoom level and value specification");
- return {};
- }
-
- const JSValue& z = stop[rapidjson::SizeType(0)];
- if (!z.IsNumber()) {
- Log::Warning(Event::ParseStyle, "zoom level in stop must be a number");
- return {};
- }
-
- optional<T> v = parseConstant<T>(name, stop[rapidjson::SizeType(1)]);
- if (!v) {
- return {};
- }
-
- stops.emplace_back(z.GetDouble(), *v);
- }
-
- return Function<T>(stops, base);
+ return result.template get<PropertyValue<T>>();
}
optional<TransitionOptions> parseTransitionOptions(const char * name, const JSValue&);
diff --git a/src/mbgl/style/rapidjson_conversion.hpp b/src/mbgl/style/rapidjson_conversion.hpp
new file mode 100644
index 0000000000..93577ac8b2
--- /dev/null
+++ b/src/mbgl/style/rapidjson_conversion.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <mbgl/util/rapidjson.hpp>
+
+namespace mbgl {
+namespace style {
+namespace conversion {
+
+inline bool isArray(const JSValue& value) {
+ return value.IsArray();
+}
+
+inline std::size_t arrayLength(const JSValue& value) {
+ return value.Size();
+}
+
+inline const JSValue& arrayMember(const JSValue& value, std::size_t i) {
+ return value[rapidjson::SizeType(i)];
+}
+
+inline bool isObject(const JSValue& value) {
+ return value.IsObject();
+}
+
+inline const JSValue* objectMember(const JSValue& value, const char * name) {
+ if (!value.HasMember(name)) {
+ return nullptr;
+ }
+ return &value[name];
+}
+
+inline optional<bool> toBool(const JSValue& value) {
+ if (!value.IsBool()) {
+ return {};
+ }
+ return value.GetBool();
+}
+
+inline optional<float> toNumber(const JSValue& value) {
+ if (!value.IsNumber()) {
+ return {};
+ }
+ return value.GetDouble();
+}
+
+inline optional<std::string> toString(const JSValue& value) {
+ if (!value.IsString()) {
+ return {};
+ }
+ return {{ value.GetString(), value.GetStringLength() }};
+}
+
+} // namespace conversion
+} // namespace style
+} // namespace mbgl