diff options
Diffstat (limited to 'platform/android/src/gson')
| -rw-r--r-- | platform/android/src/gson/json_array.cpp | 40 | ||||
| -rw-r--r-- | platform/android/src/gson/json_array.hpp | 25 | ||||
| -rw-r--r-- | platform/android/src/gson/json_element.cpp | 62 | ||||
| -rw-r--r-- | platform/android/src/gson/json_element.hpp | 33 | ||||
| -rw-r--r-- | platform/android/src/gson/json_object.cpp | 64 | ||||
| -rw-r--r-- | platform/android/src/gson/json_object.hpp | 11 | ||||
| -rw-r--r-- | platform/android/src/gson/json_primitive.cpp | 66 | ||||
| -rw-r--r-- | platform/android/src/gson/json_primitive.hpp | 39 |
8 files changed, 339 insertions, 1 deletions
diff --git a/platform/android/src/gson/json_array.cpp b/platform/android/src/gson/json_array.cpp new file mode 100644 index 0000000000..d91e323ac9 --- /dev/null +++ b/platform/android/src/gson/json_array.cpp @@ -0,0 +1,40 @@ +#include "json_array.hpp" + +#include "json_element.hpp" + +namespace mbgl { +namespace android { +namespace gson { + +std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv &env, jni::Object<JsonArray> jsonArray) { + std::vector<mapbox::geometry::value> values; + + if (jsonArray) { + static auto getMethod = JsonArray::javaClass.GetMethod<jni::Object<JsonElement> (jni::jint)>(env, "get"); + static auto sizeMethod = JsonArray::javaClass.GetMethod<jni::jint ()>(env, "size"); + + int size = jsonArray.Call(env, sizeMethod); + values.reserve(uint(size)); + + for (int i = 0; i < size; i++) { + auto entry = jsonArray.Call(env, getMethod, i); + if (entry) { + values.push_back(JsonElement::convert(env, entry)); + } + jni::DeleteLocalRef(env, entry); + } + } + + return values; +} + +void JsonArray::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<JsonArray>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<JsonArray> JsonArray::javaClass; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_array.hpp b/platform/android/src/gson/json_array.hpp new file mode 100644 index 0000000000..8571ad5dba --- /dev/null +++ b/platform/android/src/gson/json_array.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include <mapbox/geometry.hpp> +#include <mbgl/util/noncopyable.hpp> + +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { +namespace gson { + +class JsonArray : private mbgl::util::noncopyable { +public: + static constexpr auto Name() { return "com/google/gson/JsonArray"; }; + + static std::vector<mapbox::geometry::value> convert(JNIEnv&, jni::Object<JsonArray>); + + static jni::Class<JsonArray> javaClass; + + static void registerNative(jni::JNIEnv&); +}; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_element.cpp b/platform/android/src/gson/json_element.cpp new file mode 100644 index 0000000000..060b1e0fe2 --- /dev/null +++ b/platform/android/src/gson/json_element.cpp @@ -0,0 +1,62 @@ +#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 { + +mapbox::geometry::value JsonElement::convert(jni::JNIEnv &env, jni::Object<JsonElement> jsonElement) { + mapbox::geometry::value value; + + 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)); + } else { + value = mapbox::geometry::null_value; + } + } + 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> JsonElement::javaClass; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_element.hpp b/platform/android/src/gson/json_element.hpp new file mode 100644 index 0000000000..7619350617 --- /dev/null +++ b/platform/android/src/gson/json_element.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include <mapbox/geometry.hpp> +#include <mbgl/util/noncopyable.hpp> + +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { +namespace gson { + +class JsonElement : private mbgl::util::noncopyable { +public: + static constexpr auto Name() { return "com/google/gson/JsonElement"; }; + + static mapbox::geometry::value convert(JNIEnv&, jni::Object<JsonElement>); + + static bool isJsonObject(JNIEnv&, jni::Object<JsonElement>); + + static bool isJsonArray(JNIEnv&, jni::Object<JsonElement>); + + static bool isJsonPrimitive(JNIEnv&, jni::Object<JsonElement>); + + static bool isJsonNull(JNIEnv&, jni::Object<JsonElement>); + + static jni::Class<JsonElement> javaClass; + + static void registerNative(jni::JNIEnv&); +}; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_object.cpp b/platform/android/src/gson/json_object.cpp new file mode 100644 index 0000000000..a704dae9dd --- /dev/null +++ b/platform/android/src/gson/json_object.cpp @@ -0,0 +1,64 @@ +#include "json_object.hpp" + +#include "json_element.hpp" + +#include "../java/util.hpp" + +namespace mbgl { +namespace android { +namespace gson { + + +template <typename F> // void (jni::String, jni::Object<gson::JsonElement>) +static void iterateEntrySet(jni::JNIEnv& env, jni::Object<JsonObject> jsonObject, F callback) { + // Get Set<Map.Entry<String, JsonElement>> + static auto method = JsonObject::javaClass.GetMethod<jni::Object<java::util::Set> ()>(env, "entrySet"); + auto entrySet = jsonObject.Call(env, method); + jni::Array<jni::Object<java::util::Map::Entry>> entryArray = java::util::Set::toArray<java::util::Map::Entry>(env, entrySet); + + size_t size = entryArray.Length(env); + for (size_t i = 0; i < size; i++) { + auto entry = entryArray.Get(env, i); + if (entry) { + // Convert + auto jKey = java::util::Map::Entry::getKey<jni::ObjectTag>(env, entry); + auto jKeyString = jni::String(reinterpret_cast<jni::jstring*>(jKey.Get())); + auto jValue = java::util::Map::Entry::getValue<gson::JsonElement>(env, entry); + + // Callback + callback(jKeyString, jValue); + + // Cleanup + // Skip jKey as it points to the same as jKeyString + jni::DeleteLocalRef(env, jKeyString); + jni::DeleteLocalRef(env, jValue); + } + jni::DeleteLocalRef(env, entry); + } + + jni::DeleteLocalRef(env, entrySet); + jni::DeleteLocalRef(env, entryArray); +} + +mapbox::geometry::property_map JsonObject::convert(jni::JNIEnv &env, jni::Object<JsonObject> jsonObject) { + mapbox::geometry::property_map map; + + if (jsonObject) { + iterateEntrySet(env, jsonObject, [&map, &env](jni::String jId, jni::Object<gson::JsonElement> jsonElement) { + map[jni::Make<std::string>(env, jId)] = JsonElement::convert(env, jsonElement); + }); + } + + return map; +} + +void JsonObject::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<JsonObject>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<JsonObject> JsonObject::javaClass; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_object.hpp b/platform/android/src/gson/json_object.hpp index a7de0b1978..aba8e40415 100644 --- a/platform/android/src/gson/json_object.hpp +++ b/platform/android/src/gson/json_object.hpp @@ -1,16 +1,25 @@ #pragma once +#include <mapbox/geometry.hpp> #include <mbgl/util/noncopyable.hpp> +#include <jni/jni.hpp> + namespace mbgl { namespace android { +namespace gson { class JsonObject : private mbgl::util::noncopyable { public: static constexpr auto Name() { return "com/google/gson/JsonObject"; }; -}; + static mapbox::geometry::property_map convert(JNIEnv&, jni::Object<JsonObject>); + static jni::Class<JsonObject> javaClass; + + static void registerNative(jni::JNIEnv&); +}; +} // namespace gson } // namespace android } // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_primitive.cpp b/platform/android/src/gson/json_primitive.cpp new file mode 100644 index 0000000000..58d0b45fe7 --- /dev/null +++ b/platform/android/src/gson/json_primitive.cpp @@ -0,0 +1,66 @@ +#include "json_primitive.hpp" + +namespace mbgl { +namespace android { +namespace gson { + +JsonPrimitive::value JsonPrimitive::convert(jni::JNIEnv &env, jni::Object<JsonPrimitive> 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> jsonPrimitive) { + static auto method = JsonPrimitive::javaClass.GetMethod<jni::jboolean ()>(env, "isBoolean"); + return jsonPrimitive.Call(env, method); +} + +bool JsonPrimitive::isString(JNIEnv& env, jni::Object<JsonPrimitive> jsonPrimitive) { + static auto method = JsonPrimitive::javaClass.GetMethod<jni::jboolean ()>(env, "isString"); + return jsonPrimitive.Call(env, method); +} + +bool JsonPrimitive::isNumber(JNIEnv& env, jni::Object<JsonPrimitive> jsonPrimitive) { + static auto method = JsonPrimitive::javaClass.GetMethod<jni::jboolean ()>(env, "isNumber"); + return jsonPrimitive.Call(env, method); +} + +bool JsonPrimitive::getAsBoolean(JNIEnv& env, jni::Object<JsonPrimitive> jsonPrimitive) { + static auto method = JsonPrimitive::javaClass.GetMethod<jni::jboolean ()>(env, "getAsBoolean"); + return jsonPrimitive.Call(env, method); +} + +std::string JsonPrimitive::getAsString(JNIEnv& env, jni::Object<JsonPrimitive> jsonPrimitive) { + static auto method = JsonPrimitive::javaClass.GetMethod<jni::String ()>(env, "getAsString"); + auto jString = jsonPrimitive.Call(env, method); + auto string = jni::Make<std::string>(env, jString); + jni::DeleteLocalRef(env, jString); + return string; +} + +double JsonPrimitive::getAsDouble(JNIEnv& env, jni::Object<JsonPrimitive> jsonPrimitive) { + static auto method = JsonPrimitive::javaClass.GetMethod<jni::jdouble ()>(env, "getAsDouble"); + return jsonPrimitive.Call(env, method); +} + +void JsonPrimitive::registerNative(jni::JNIEnv &env) { + // Lookup the class + javaClass = *jni::Class<JsonPrimitive>::Find(env).NewGlobalRef(env).release(); +} + +jni::Class<JsonPrimitive> JsonPrimitive::javaClass; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/gson/json_primitive.hpp b/platform/android/src/gson/json_primitive.hpp new file mode 100644 index 0000000000..5fc8a2b485 --- /dev/null +++ b/platform/android/src/gson/json_primitive.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include <mapbox/geometry.hpp> +#include <mbgl/util/noncopyable.hpp> + +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { +namespace gson { + +class JsonPrimitive : private mbgl::util::noncopyable { +public: + using value = mapbox::util::variant<mapbox::geometry::null_value_t, bool, uint64_t, int64_t, double, std::string>; + + static constexpr auto Name() { return "com/google/gson/JsonPrimitive"; }; + + static value convert(JNIEnv&, jni::Object<JsonPrimitive>); + + static bool isBoolean(JNIEnv&, jni::Object<JsonPrimitive>); + + static bool isString(JNIEnv&, jni::Object<JsonPrimitive>); + + static bool isNumber(JNIEnv&, jni::Object<JsonPrimitive>); + + static bool getAsBoolean(JNIEnv&, jni::Object<JsonPrimitive>); + + static std::string getAsString(JNIEnv&, jni::Object<JsonPrimitive>); + + static double getAsDouble(JNIEnv&, jni::Object<JsonPrimitive>); + + static jni::Class<JsonPrimitive> javaClass; + + static void registerNative(jni::JNIEnv&); +}; + +} // namespace gson +} // namespace android +} // namespace mbgl
\ No newline at end of file |
