From 6be8302296147515e0b0d7ed7cc46d195227118e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 22 Aug 2018 11:28:07 -0700 Subject: [android] Simplify JSON conversion --- platform/android/src/gson/json_array.cpp | 7 +- platform/android/src/gson/json_array.hpp | 6 +- platform/android/src/gson/json_element.cpp | 138 +++++++++++++-------------- platform/android/src/gson/json_element.hpp | 11 +-- platform/android/src/gson/json_object.cpp | 6 +- platform/android/src/gson/json_object.hpp | 6 +- platform/android/src/gson/json_primitive.cpp | 129 ------------------------- platform/android/src/gson/json_primitive.hpp | 15 --- 8 files changed, 82 insertions(+), 236 deletions(-) diff --git a/platform/android/src/gson/json_array.cpp b/platform/android/src/gson/json_array.cpp index 333b402aa0..b5fb85e5d9 100644 --- a/platform/android/src/gson/json_array.cpp +++ b/platform/android/src/gson/json_array.cpp @@ -1,12 +1,11 @@ #include "json_array.hpp" - #include "json_element.hpp" namespace mbgl { namespace android { namespace gson { -jni::Object JsonArray::New(jni::JNIEnv& env, const std::vector& values){ +jni::Object JsonArray::New(jni::JNIEnv& env, const std::vector& values){ static auto javaClass = jni::Class::Singleton(env); static auto constructor = javaClass.GetConstructor(env); static auto addMethod = javaClass.GetMethod)>(env, "add"); @@ -20,8 +19,8 @@ jni::Object JsonArray::New(jni::JNIEnv& env, const std::vector JsonArray::convert(jni::JNIEnv& env, const jni::Object jsonArray) { - std::vector values; +std::vector JsonArray::convert(jni::JNIEnv& env, const jni::Object jsonArray) { + std::vector values; if (jsonArray) { static auto javaClass = jni::Class::Singleton(env); diff --git a/platform/android/src/gson/json_array.hpp b/platform/android/src/gson/json_array.hpp index e74b92176f..b41596819f 100644 --- a/platform/android/src/gson/json_array.hpp +++ b/platform/android/src/gson/json_array.hpp @@ -2,8 +2,6 @@ #include "json_element.hpp" -#include - #include namespace mbgl { @@ -14,8 +12,8 @@ class JsonArray : public JsonElement { public: static constexpr auto Name() { return "com/google/gson/JsonArray"; }; - static jni::Object New(jni::JNIEnv&, const std::vector&); - static std::vector convert(JNIEnv&, jni::Object); + static jni::Object New(jni::JNIEnv&, const std::vector&); + static std::vector convert(JNIEnv&, jni::Object); static void registerNative(jni::JNIEnv&); }; diff --git a/platform/android/src/gson/json_element.cpp b/platform/android/src/gson/json_element.cpp index d5304ed674..28cb368386 100644 --- a/platform/android/src/gson/json_element.cpp +++ b/platform/android/src/gson/json_element.cpp @@ -1,87 +1,87 @@ #include "json_element.hpp" - #include "json_array.hpp" #include "json_object.hpp" #include "json_primitive.hpp" -#include -#include - namespace mbgl { namespace android { namespace gson { -/** - * Turn mapbox::geometry::value into Java Gson JsonElement - */ -class JsonElementEvaluator { -public: - - jni::JNIEnv& env; - - jni::Object operator()(const JsonPrimitive::value value) const { - return JsonPrimitive::New(env, value); - } - - jni::Object operator()(const std::vector &values) const { - return JsonArray::New(env, values); - } - - jni::Object operator()(const std::unordered_map &values) const { - return JsonObject::New(env, values); - } -}; - - -jni::Object JsonElement::New(jni::JNIEnv& env, const mapbox::geometry::value& value) { - JsonElementEvaluator evaluator { env } ; - return mapbox::geometry::value::visit(value, evaluator); +jni::Object JsonElement::New(jni::JNIEnv& env, const mbgl::Value& value) { + static auto primitive = jni::Class::Singleton(env); + static auto stringConstructor = primitive.GetConstructor(env); + static auto numberConstructor = primitive.GetConstructor(env); + static auto booleanConstructor = primitive.GetConstructor(env); + + return value.match( + [&] (const mbgl::NullValue&) { + return jni::Object(); + }, + [&] (const std::string& value) { + return primitive.New(env, stringConstructor, + *jni::SeizeLocal(env, jni::Make(env, value))); + }, + [&] (const double value) { + return primitive.New(env, numberConstructor, + *jni::SeizeLocal(env, jni::Number(jni::Box(env, value)))); + }, + [&] (const int64_t value) { + return primitive.New(env, numberConstructor, + *jni::SeizeLocal(env, jni::Number(jni::Box(env, value)))); + }, + [&] (const uint64_t value) { + return primitive.New(env, numberConstructor, + *jni::SeizeLocal(env, jni::Number(jni::Box(env, int64_t(value))))); // TODO: should use BigInteger + }, + [&] (const bool value) { + return primitive.New(env, booleanConstructor, + *jni::SeizeLocal(env, jni::Box(env, value ? jni::jni_true : jni::jni_false))); + }, + [&] (const std::vector& 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) { - mapbox::geometry::value value; +mbgl::Value JsonElement::convert(jni::JNIEnv &env, jni::Object jsonElement) { + if (!jsonElement) { + return mbgl::NullValue(); + } - if (jsonElement) { - if (isJsonPrimitive(env, jsonElement)) { - static auto primitiveClass = jni::Class::Singleton(env); - auto primitive = JsonPrimitive::convert(env, jni::Cast(env, primitiveClass, jsonElement)); - value = mapbox::util::apply_visitor([](auto t) { return mapbox::geometry::value { t }; }, primitive); - } else if (isJsonObject(env, jsonElement)) { - static auto objectClass = jni::Class::Singleton(env); - mapbox::geometry::property_map map = JsonObject::convert(env, jni::Cast(env, objectClass, jsonElement)); - value = mapbox::util::recursive_wrapper> { map } ; - } else if (isJsonArray(env, jsonElement)) { - static auto arrayClass = jni::Class::Singleton(env); - value = JsonArray::convert(env, jni::Cast(env, arrayClass, jsonElement)); + static auto elementClass = jni::Class::Singleton(env); + static auto isJsonObject = elementClass.GetMethod(env, "isJsonObject"); + static auto isJsonArray = elementClass.GetMethod(env, "isJsonArray"); + static auto isJsonPrimitive = elementClass.GetMethod(env, "isJsonPrimitive"); + + static auto primitiveClass = jni::Class::Singleton(env); + static auto isBoolean = primitiveClass.GetMethod(env, "isBoolean"); + static auto isString = primitiveClass.GetMethod(env, "isString"); + static auto isNumber = primitiveClass.GetMethod(env, "isNumber"); + static auto getAsBoolean = primitiveClass.GetMethod(env, "getAsBoolean"); + static auto getAsString = primitiveClass.GetMethod(env, "getAsString"); + static auto getAsDouble = primitiveClass.GetMethod(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(env, *jni::SeizeLocal(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::Singleton(env), jsonElement)); + } else if (jsonElement.Call(env, isJsonArray)) { + return JsonArray::convert(env, jni::Cast(env, jni::Class::Singleton(env), jsonElement)); + } else { + return mbgl::NullValue(); } - return value; -} - -bool JsonElement::isJsonObject(JNIEnv& env, jni::Object jsonElement) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isJsonObject"); - return jsonElement.Call(env, method); -} - -bool JsonElement::isJsonArray(JNIEnv& env, jni::Object jsonElement) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isJsonArray"); - return jsonElement.Call(env, method); -} - -bool JsonElement::isJsonPrimitive(JNIEnv& env, jni::Object jsonElement) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isJsonPrimitive"); - return jsonElement.Call(env, method); -} - -bool JsonElement::isJsonNull(JNIEnv& env, jni::Object jsonElement) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isJsonNull"); - return jsonElement.Call(env, method); } void JsonElement::registerNative(jni::JNIEnv &env) { diff --git a/platform/android/src/gson/json_element.hpp b/platform/android/src/gson/json_element.hpp index 5c68934871..384459dc41 100644 --- a/platform/android/src/gson/json_element.hpp +++ b/platform/android/src/gson/json_element.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,8 @@ class JsonElement : public jni::ObjectTag { public: static constexpr auto Name() { return "com/google/gson/JsonElement"; }; - static jni::Object New(jni::JNIEnv&, const mapbox::geometry::value&); - static mapbox::geometry::value convert(JNIEnv&, jni::Object); - - static bool isJsonObject(JNIEnv&, jni::Object); - static bool isJsonArray(JNIEnv&, jni::Object); - static bool isJsonPrimitive(JNIEnv&, jni::Object); - static bool isJsonNull(JNIEnv&, jni::Object); + static jni::Object New(jni::JNIEnv&, const mbgl::Value&); + static mbgl::Value convert(JNIEnv&, jni::Object); static void registerNative(jni::JNIEnv&); }; diff --git a/platform/android/src/gson/json_object.cpp b/platform/android/src/gson/json_object.cpp index 4a2ec07563..5dcb07642f 100644 --- a/platform/android/src/gson/json_object.cpp +++ b/platform/android/src/gson/json_object.cpp @@ -9,7 +9,7 @@ namespace android { namespace gson { -jni::Object JsonObject::New(jni::JNIEnv& env, const std::unordered_map& values) { +jni::Object JsonObject::New(jni::JNIEnv& env, const mbgl::PropertyMap& values) { static auto javaClass = jni::Class::Singleton(env); static auto constructor = javaClass.GetConstructor(env); static auto addMethod = javaClass.GetMethod)>(env, "add"); @@ -46,8 +46,8 @@ static void iterateEntrySet(jni::JNIEnv& env, jni::Object jsonObject } } -mapbox::geometry::property_map JsonObject::convert(jni::JNIEnv &env, jni::Object jsonObject) { - mapbox::geometry::property_map map; +mbgl::PropertyMap JsonObject::convert(jni::JNIEnv &env, jni::Object jsonObject) { + mbgl::PropertyMap map; if (jsonObject) { iterateEntrySet(env, jsonObject, [&map, &env](jni::String jId, jni::Object jsonElement) { diff --git a/platform/android/src/gson/json_object.hpp b/platform/android/src/gson/json_object.hpp index 85e8828d91..256161f0d9 100644 --- a/platform/android/src/gson/json_object.hpp +++ b/platform/android/src/gson/json_object.hpp @@ -2,8 +2,6 @@ #include "json_element.hpp" -#include - #include namespace mbgl { @@ -14,8 +12,8 @@ class JsonObject : public JsonElement { public: static constexpr auto Name() { return "com/google/gson/JsonObject"; }; - static jni::Object New(jni::JNIEnv&, const std::unordered_map&); - static mapbox::geometry::property_map convert(JNIEnv&, jni::Object); + static jni::Object New(jni::JNIEnv&, const mbgl::PropertyMap&); + static mbgl::PropertyMap convert(JNIEnv&, jni::Object); static void registerNative(jni::JNIEnv&); }; diff --git a/platform/android/src/gson/json_primitive.cpp b/platform/android/src/gson/json_primitive.cpp index 2b03629135..79d6b07617 100644 --- a/platform/android/src/gson/json_primitive.cpp +++ b/platform/android/src/gson/json_primitive.cpp @@ -4,135 +4,6 @@ namespace mbgl { namespace android { namespace gson { -/** - * Turn mapbox::geometry::value into Java Gson JsonPrimitives - */ -class JsonPrimitiveEvaluator { -public: - - jni::JNIEnv& env; - - /** - * Create a null primitive - */ - jni::Object operator()(const mapbox::geometry::null_value_t) const { - return jni::Object(); - } - - /** - * Create a primitive containing a string value - */ - jni::Object operator()(const std::string value) const { - static auto javaClass = jni::Class::Singleton(env); - static auto constructor = javaClass.GetConstructor(env); - - return javaClass.New(env, constructor, - *jni::SeizeLocal(env, jni::Make(env, value))); - } - - /** - * Create a primitive containing a number value with type double - */ - jni::Object operator()(const double value) const { - static auto javaClass = jni::Class::Singleton(env); - static auto constructor = javaClass.GetConstructor(env); - - return javaClass.New(env, constructor, - *jni::SeizeLocal(env, jni::Number(jni::Box(env, value)))); - } - - /** - * Create a primitive containing a number value with type long - */ - jni::Object operator()(const int64_t value) const { - static auto javaClass = jni::Class::Singleton(env); - static auto constructor = javaClass.GetConstructor(env); - - return javaClass.New(env, constructor, - *jni::SeizeLocal(env, jni::Number(jni::Box(env, value)))); - } - - /** - * Create a primitive containing a number value with type long - */ - jni::Object operator()(const uint64_t value) const { - static auto javaClass = jni::Class::Singleton(env); - static auto constructor = javaClass.GetConstructor(env); - - return javaClass.New(env, constructor, - *jni::SeizeLocal(env, jni::Number(jni::Box(env, int64_t(value))))); // TODO: should use BigInteger - } - - /** - * Create a primitive containing a boolean value - */ - jni::Object operator()(const bool value) const { - static auto javaClass = jni::Class::Singleton(env); - static auto constructor = javaClass.GetConstructor(env); - - return javaClass.New(env, constructor, - *jni::SeizeLocal(env, jni::Box(env, value ? jni::jni_true : jni::jni_false))); - } -}; - -jni::Object JsonPrimitive::New(jni::JNIEnv &env, const value& value) { - JsonPrimitiveEvaluator evaluator { env }; - return value::visit(value, evaluator); -} - -JsonPrimitive::value JsonPrimitive::convert(jni::JNIEnv &env, jni::Object jsonPrimitive) { - value value; - if (jsonPrimitive) { - if (isBoolean(env, jsonPrimitive)) { - value = getAsBoolean(env, jsonPrimitive); - } else if (isNumber(env, jsonPrimitive)) { - //TODO: how to differentiate types here? - value = getAsDouble(env, jsonPrimitive); - } else if (isString(env, jsonPrimitive)) { - value = getAsString(env, jsonPrimitive); - } else { - value = mapbox::geometry::null_value; - } - } - return value; -} - -bool JsonPrimitive::isBoolean(JNIEnv& env, jni::Object jsonPrimitive) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isBoolean"); - return jsonPrimitive.Call(env, method); -} - -bool JsonPrimitive::isString(JNIEnv& env, jni::Object jsonPrimitive) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isString"); - return jsonPrimitive.Call(env, method); -} - -bool JsonPrimitive::isNumber(JNIEnv& env, jni::Object jsonPrimitive) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "isNumber"); - return jsonPrimitive.Call(env, method); -} - -bool JsonPrimitive::getAsBoolean(JNIEnv& env, jni::Object jsonPrimitive) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "getAsBoolean"); - return jsonPrimitive.Call(env, method); -} - -std::string JsonPrimitive::getAsString(JNIEnv& env, jni::Object jsonPrimitive) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "getAsString"); - return jni::Make(env, *jni::SeizeLocal(env, jsonPrimitive.Call(env, method))); -} - -double JsonPrimitive::getAsDouble(JNIEnv& env, jni::Object jsonPrimitive) { - static auto javaClass = jni::Class::Singleton(env); - static auto method = javaClass.GetMethod(env, "getAsDouble"); - return jsonPrimitive.Call(env, method); -} - void JsonPrimitive::registerNative(jni::JNIEnv &env) { jni::Class::Singleton(env); } diff --git a/platform/android/src/gson/json_primitive.hpp b/platform/android/src/gson/json_primitive.hpp index d9e90507f9..fb3eefc855 100644 --- a/platform/android/src/gson/json_primitive.hpp +++ b/platform/android/src/gson/json_primitive.hpp @@ -2,8 +2,6 @@ #include "json_element.hpp" -#include - #include namespace mbgl { @@ -12,21 +10,8 @@ namespace gson { class JsonPrimitive : public JsonElement { public: - using value = mapbox::util::variant; - static constexpr auto Name() { return "com/google/gson/JsonPrimitive"; }; - static jni::Object New(jni::JNIEnv&, const value&); - static value convert(JNIEnv&, jni::Object); - - static bool isBoolean(JNIEnv&, jni::Object); - static bool isString(JNIEnv&, jni::Object); - static bool isNumber(JNIEnv&, jni::Object); - - static bool getAsBoolean(JNIEnv&, jni::Object); - static std::string getAsString(JNIEnv&, jni::Object); - static double getAsDouble(JNIEnv&, jni::Object); - static void registerNative(jni::JNIEnv&); }; -- cgit v1.2.1