summaryrefslogtreecommitdiff
path: root/platform/android/src/gson/json_element.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/src/gson/json_element.cpp')
-rw-r--r--platform/android/src/gson/json_element.cpp132
1 files changed, 65 insertions, 67 deletions
diff --git a/platform/android/src/gson/json_element.cpp b/platform/android/src/gson/json_element.cpp
index 5eaaf531f4..7c9a34c03c 100644
--- a/platform/android/src/gson/json_element.cpp
+++ b/platform/android/src/gson/json_element.cpp
@@ -1,90 +1,88 @@
#include "json_element.hpp"
-
#include "json_array.hpp"
#include "json_object.hpp"
#include "json_primitive.hpp"
-#include <mapbox/geometry/feature.hpp>
-#include <mapbox/variant.hpp>
-
namespace mbgl {
namespace android {
namespace gson {
-/**
- * Turn mapbox::geometry::value into Java Gson JsonElement
- */
-class JsonElementEvaluator {
-public:
-
- jni::JNIEnv& env;
-
- jni::Object<JsonElement> operator()(const JsonPrimitive::value value) const {
- return jni::Cast(env, JsonPrimitive::New(env, value), JsonElement::javaClass);
- }
-
- jni::Object<JsonElement> operator()(const std::vector<mapbox::geometry::value> &values) const {
- return jni::Cast(env, JsonArray::New(env, values), JsonElement::javaClass);
- }
-
- jni::Object<JsonElement> operator()(const std::unordered_map<std::string, mapbox::geometry::value> &values) const {
- return jni::Cast(env, JsonObject::New(env, values), JsonElement::javaClass);
- }
-
-};
-
-
-jni::Object<JsonElement> JsonElement::New(jni::JNIEnv& env, const mapbox::geometry::value& value) {
- JsonElementEvaluator evaluator { env } ;
- return mapbox::geometry::value::visit(value, evaluator);
+jni::Local<jni::Object<JsonElement>> JsonElement::New(jni::JNIEnv& env, const mbgl::Value& value) {
+ static auto& primitive = jni::Class<JsonPrimitive>::Singleton(env);
+ static auto stringConstructor = primitive.GetConstructor<jni::String>(env);
+ static auto numberConstructor = primitive.GetConstructor<jni::Number>(env);
+ static auto booleanConstructor = primitive.GetConstructor<jni::Boolean>(env);
+
+ return value.match(
+ [&] (const mbgl::NullValue&) {
+ return jni::Local<jni::Object<JsonElement>>();
+ },
+ [&] (const std::string& value) {
+ return primitive.New(env, stringConstructor, jni::Make<jni::String>(env, value));
+ },
+ [&] (const double value) {
+ return primitive.New(env, numberConstructor, jni::Box(env, value));
+ },
+ [&] (const int64_t value) {
+ return primitive.New(env, numberConstructor, jni::Box(env, value));
+ },
+ [&] (const uint64_t value) {
+ return primitive.New(env, numberConstructor, jni::Box(env, int64_t(value))); // TODO: should use BigInteger
+ },
+ [&] (const bool value) {
+ return primitive.New(env, booleanConstructor, jni::Box(env, value ? jni::jni_true : jni::jni_false));
+ },
+ [&] (const std::vector<mbgl::Value>& values) {
+ return JsonArray::New(env, values);
+ },
+ [&] (const mbgl::PropertyMap& values) {
+ return JsonObject::New(env, values);
+ }
+ );
}
-mapbox::geometry::value JsonElement::convert(jni::JNIEnv &env, jni::Object<JsonElement> jsonElement) {
- mapbox::geometry::value value;
+mbgl::Value JsonElement::convert(jni::JNIEnv &env, const jni::Object<JsonElement>& jsonElement) {
+ if (!jsonElement) {
+ return mbgl::NullValue();
+ }
- if (jsonElement) {
- if (isJsonPrimitive(env, jsonElement)) {
- auto primitive = JsonPrimitive::convert(env, jni::Cast(env, jsonElement, JsonPrimitive::javaClass));
- value = mapbox::util::apply_visitor([](auto t) { return mapbox::geometry::value { t }; }, primitive);
- } else if (isJsonObject(env, jsonElement)) {
- mapbox::geometry::property_map map = JsonObject::convert(env, jni::Cast(env, jsonElement, JsonObject::javaClass));
- value = mapbox::util::recursive_wrapper<std::unordered_map<std::string, mapbox::geometry::value>> { map } ;
- } else if (isJsonArray(env, jsonElement)) {
- value = JsonArray::convert(env, jni::Cast(env, jsonElement, JsonArray::javaClass));
+ static auto& elementClass = jni::Class<JsonElement>::Singleton(env);
+ static auto isJsonObject = elementClass.GetMethod<jni::jboolean ()>(env, "isJsonObject");
+ static auto isJsonArray = elementClass.GetMethod<jni::jboolean ()>(env, "isJsonArray");
+ static auto isJsonPrimitive = elementClass.GetMethod<jni::jboolean ()>(env, "isJsonPrimitive");
+
+ static auto& primitiveClass = jni::Class<JsonPrimitive>::Singleton(env);
+ static auto isBoolean = primitiveClass.GetMethod<jni::jboolean ()>(env, "isBoolean");
+ static auto isString = primitiveClass.GetMethod<jni::jboolean ()>(env, "isString");
+ static auto isNumber = primitiveClass.GetMethod<jni::jboolean ()>(env, "isNumber");
+ static auto getAsBoolean = primitiveClass.GetMethod<jni::jboolean ()>(env, "getAsBoolean");
+ static auto getAsString = primitiveClass.GetMethod<jni::String ()>(env, "getAsString");
+ static auto getAsDouble = primitiveClass.GetMethod<jni::jdouble ()>(env, "getAsDouble");
+
+ if (jsonElement.Call(env, isJsonPrimitive)) {
+ auto primitive = jni::Cast(env, primitiveClass, jsonElement);
+ if (primitive.Call(env, isBoolean)) {
+ return bool(primitive.Call(env, getAsBoolean));
+ } else if (primitive.Call(env, isNumber)) {
+ return primitive.Call(env, getAsDouble); // TODO: how to differentiate types here?
+ } else if (primitive.Call(env, isString)) {
+ return jni::Make<std::string>(env, primitive.Call(env, getAsString));
} else {
- value = mapbox::geometry::null_value;
+ return mbgl::NullValue();
}
+ } else if (jsonElement.Call(env, isJsonObject)) {
+ return JsonObject::convert(env, jni::Cast(env, jni::Class<JsonObject>::Singleton(env), jsonElement));
+ } else if (jsonElement.Call(env, isJsonArray)) {
+ return JsonArray::convert(env, jni::Cast(env, jni::Class<JsonArray>::Singleton(env), jsonElement));
+ } else {
+ return mbgl::NullValue();
}
- return value;
-}
-
-bool JsonElement::isJsonObject(JNIEnv& env, jni::Object<JsonElement> jsonElement) {
- static auto method = JsonElement::javaClass.GetMethod<jni::jboolean ()>(env, "isJsonObject");
- return jsonElement.Call(env, method);
-}
-
-bool JsonElement::isJsonArray(JNIEnv& env, jni::Object<JsonElement> jsonElement) {
- static auto method = JsonElement::javaClass.GetMethod<jni::jboolean ()>(env, "isJsonArray");
- return jsonElement.Call(env, method);
-}
-
-bool JsonElement::isJsonPrimitive(JNIEnv& env, jni::Object<JsonElement> jsonElement) {
- static auto method = JsonElement::javaClass.GetMethod<jni::jboolean ()>(env, "isJsonPrimitive");
- return jsonElement.Call(env, method);
-}
-
-bool JsonElement::isJsonNull(JNIEnv& env, jni::Object<JsonElement> jsonElement) {
- static auto method = JsonElement::javaClass.GetMethod<jni::jboolean ()>(env, "isJsonNull");
- return jsonElement.Call(env, method);
}
void JsonElement::registerNative(jni::JNIEnv &env) {
- // Lookup the class
- javaClass = *jni::Class<JsonElement>::Find(env).NewGlobalRef(env).release();
+ jni::Class<JsonElement>::Singleton(env);
}
-jni::Class<JsonElement> JsonElement::javaClass;
-
} // namespace gson
} // namespace android
} // namespace mbgl \ No newline at end of file