diff options
Diffstat (limited to 'platform/android/src/gson/json_element.cpp')
-rw-r--r-- | platform/android/src/gson/json_element.cpp | 132 |
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 |