Improve Java binding.
GitOrigin-RevId: ec10cb32f546a1249f4fe5f309eaff7488c31182
This commit is contained in:
parent
224de03838
commit
8eb46f6715
@ -547,6 +547,15 @@ target_include_directories(tdcore PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURC
|
||||
target_include_directories(tdcore SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||
target_link_libraries(tdcore PUBLIC tdactor tdutils tdnet tddb PRIVATE ${OPENSSL_CRYPTO_LIBRARY})
|
||||
|
||||
if (TD_API_JAVA_PACKAGE AND NOT ANDROID) # jni is available by default on Android
|
||||
if (NOT JNI_FOUND)
|
||||
find_package(JNI REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Found JNI: ${JNI_INCLUDE_DIRS} ${JNI_LIBRARIES}")
|
||||
target_include_directories(tdcore PUBLIC ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
|
||||
target_link_libraries(tdcore PUBLIC ${JAVA_JVM_LIBRARY})
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_CROSSCOMPILING)
|
||||
add_dependencies(tdcore tl_generate_common)
|
||||
endif()
|
||||
@ -558,6 +567,11 @@ target_include_directories(tdclient PUBLIC
|
||||
)
|
||||
target_link_libraries(tdclient PRIVATE tdcore)
|
||||
|
||||
if (TD_API_JAVA_PACKAGE AND NOT ANDROID) # jni is available by default on Android
|
||||
target_include_directories(tdclient PUBLIC ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
|
||||
target_link_libraries(tdclient PUBLIC ${JAVA_JVM_LIBRARY})
|
||||
endif()
|
||||
|
||||
# tdc - TDLib interface in pure c.
|
||||
add_library(tdc STATIC ${TL_C_SCHEME_SOURCE} td/telegram/td_c_client.cpp td/telegram/td_c_client.h)
|
||||
target_include_directories(tdc PUBLIC
|
||||
@ -595,13 +609,21 @@ target_link_libraries(tdjson_static PRIVATE tdjson_private)
|
||||
target_compile_definitions(tdjson_static PUBLIC TDJSON_STATIC_DEFINE)
|
||||
target_include_directories(tdjson_static PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
|
||||
|
||||
set(BIGOBJ)
|
||||
if (WIN32 OR CYGWIN)
|
||||
if (MSVC)
|
||||
target_compile_options(tdcore PUBLIC "/bigobj")
|
||||
set(BIGOBJ "/bigobj")
|
||||
elseif (GCC)
|
||||
target_compile_options(tdcore PUBLIC "-Wa,-mbig-obj")
|
||||
set(BIGOBJ "-Wa,-mbig-obj")
|
||||
endif()
|
||||
endif()
|
||||
if (BIGOBJ)
|
||||
target_compile_options(tdc PUBLIC ${BIGOBJ})
|
||||
target_compile_options(tdcore PUBLIC ${BIGOBJ})
|
||||
target_compile_options(tdclient PUBLIC ${BIGOBJ})
|
||||
target_compile_options(tdjson PUBLIC ${BIGOBJ})
|
||||
target_compile_options(tdjson_static PUBLIC ${BIGOBJ})
|
||||
endif()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(TD_EMSCRIPTEN_SRC td/telegram/td_emscripten.cpp)
|
||||
@ -660,6 +682,9 @@ install(FILES ${TD_JSON_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/td/telegram/tdjson_
|
||||
install(FILES td/telegram/Client.h td/telegram/Log.h DESTINATION include/td/telegram)
|
||||
install(FILES td/tl/TlObject.h DESTINATION include/td/tl)
|
||||
install(FILES ${TL_TD_AUTO_INCLUDES}/td/telegram/td_api.h ${TL_TD_AUTO_INCLUDES}/td/telegram/td_api.hpp DESTINATION include/td/telegram)
|
||||
if (TD_API_JAVA_PACKAGE)
|
||||
install(FILES td/tl/tl_jni_object.h DESTINATION include/td/tl)
|
||||
endif()
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file("TdConfigVersion.cmake"
|
||||
|
@ -449,7 +449,7 @@ std::string TD_TL_writer_java::gen_store_function_begin(const std::string &store
|
||||
" protected " +
|
||||
storer_name + " appendLine(" + storer_name +
|
||||
" s, int shift) {\n"
|
||||
" s.append('\\n');\n"
|
||||
" s.append(System.lineSeparator());\n"
|
||||
" for (int i = 0; i < shift; i++) {\n"
|
||||
" s.append(' ');\n"
|
||||
" }\n"
|
||||
|
@ -77,113 +77,44 @@ std::string TD_TL_writer_jni_cpp::gen_vector_fetch(std::string field_name, const
|
||||
int parser_type) const {
|
||||
std::string vector_type = gen_type_name(t);
|
||||
|
||||
std::string type;
|
||||
std::string Type;
|
||||
|
||||
if (vector_type == "bool") {
|
||||
assert(false); // TODO
|
||||
}
|
||||
|
||||
std::string fetch_object = "jni::fetch_object(env, p, " + field_name + "fieldID)";
|
||||
std::string array_type;
|
||||
if (vector_type == "std::int32_t") {
|
||||
type = "int";
|
||||
Type = "Int";
|
||||
array_type = "jintArray";
|
||||
}
|
||||
if (vector_type == "std::int64_t") {
|
||||
type = "long";
|
||||
Type = "Long";
|
||||
array_type = "jlongArray";
|
||||
}
|
||||
if (vector_type == "double") {
|
||||
type = "double";
|
||||
Type = "Double";
|
||||
array_type = "jdoubleArray";
|
||||
}
|
||||
|
||||
std::string res_begin;
|
||||
std::string res_end;
|
||||
std::string fetch_object;
|
||||
if (field_name.empty()) {
|
||||
res_begin = "({ std::vector<" + vector_type + "> res_tmp_; ";
|
||||
field_name = "res_tmp_";
|
||||
res_end = " std::move(res_tmp_); })";
|
||||
fetch_object = "p; ";
|
||||
} else {
|
||||
fetch_object = "jni::fetch_object(env, p, " + field_name + "fieldID); ";
|
||||
}
|
||||
std::string resize_vector;
|
||||
if (!type.empty()) {
|
||||
resize_vector = field_name + ".resize(length_tmp_); ";
|
||||
} else {
|
||||
resize_vector = field_name + ".reserve(length_tmp_); ";
|
||||
if (!array_type.empty()) {
|
||||
return "jni::fetch_vector(env, (" + array_type + ")" + fetch_object + ");";
|
||||
}
|
||||
|
||||
std::string res;
|
||||
if (!type.empty()) {
|
||||
res =
|
||||
"{ "
|
||||
"j" +
|
||||
type + "Array arr_tmp_ = (j" + type + "Array)" + fetch_object +
|
||||
"if (arr_tmp_) { "
|
||||
"jsize length_tmp_ = env->GetArrayLength(arr_tmp_); " +
|
||||
resize_vector + "env->Get" + Type + "ArrayRegion(arr_tmp_, 0, length_tmp_, reinterpret_cast<j" + type +
|
||||
" *>(&" + field_name +
|
||||
"[0])); "
|
||||
"env->DeleteLocalRef(arr_tmp_); "
|
||||
"} }";
|
||||
} else if (vector_type == string_type) {
|
||||
res =
|
||||
"{ "
|
||||
"jobjectArray arr_tmp_ = (jobjectArray)" +
|
||||
fetch_object +
|
||||
"if (arr_tmp_) { "
|
||||
"jsize length_tmp_ = env->GetArrayLength(arr_tmp_); " +
|
||||
resize_vector +
|
||||
"for (jsize i_tmp_ = 0; i_tmp_ < length_tmp_; i_tmp_++) { "
|
||||
"jstring str_tmp_ = (jstring)env->GetObjectArrayElement(arr_tmp_, i_tmp_); " +
|
||||
field_name +
|
||||
".push_back(jni::from_jstring(env, str_tmp_)); "
|
||||
"env->DeleteLocalRef(str_tmp_); "
|
||||
"} "
|
||||
"env->DeleteLocalRef(arr_tmp_); "
|
||||
"} }";
|
||||
std::string template_type;
|
||||
if (vector_type == string_type) {
|
||||
template_type = "std::string";
|
||||
} else if (vector_type.compare(0, 11, "std::vector") == 0) {
|
||||
const tl::tl_tree_type *child = static_cast<const tl::tl_tree_type *>(t->children[0]);
|
||||
|
||||
res =
|
||||
"{ "
|
||||
"jobjectArray arr_tmp_ = (jobjectArray)" +
|
||||
fetch_object +
|
||||
"if (arr_tmp_) { "
|
||||
"jsize length_tmp_ = env->GetArrayLength(arr_tmp_); " +
|
||||
resize_vector +
|
||||
"for (jsize i_tmp_ = 0; i_tmp_ < length_tmp_; i_tmp_++) { "
|
||||
"jobject p = env->GetObjectArrayElement(arr_tmp_, i_tmp_); " +
|
||||
field_name + ".push_back(" + gen_vector_fetch("", child, vars, parser_type) +
|
||||
"); "
|
||||
"if (p) { env->DeleteLocalRef(p); "
|
||||
"} } "
|
||||
"env->DeleteLocalRef(arr_tmp_); "
|
||||
"} }";
|
||||
template_type = gen_type_name(child);
|
||||
if (template_type.compare(0, 10, "object_ptr") == 0) {
|
||||
template_type = gen_main_class_name(child->type);
|
||||
}
|
||||
template_type = "std::vector<" + template_type + ">";
|
||||
} else if (vector_type == bytes_type) {
|
||||
std::fprintf(stderr, "Vector of Bytes is not supported\n");
|
||||
assert(false);
|
||||
} else {
|
||||
assert(vector_type.compare(0, 10, "object_ptr") == 0);
|
||||
res =
|
||||
"{ "
|
||||
"jobjectArray arr_tmp_ = (jobjectArray)" +
|
||||
fetch_object +
|
||||
"if (arr_tmp_) { "
|
||||
"jsize length_tmp_ = env->GetArrayLength(arr_tmp_); " +
|
||||
resize_vector +
|
||||
"for (jsize i_tmp_ = 0; i_tmp_ < length_tmp_; i_tmp_++) { "
|
||||
"jobject o_ = env->GetObjectArrayElement(arr_tmp_, i_tmp_); " +
|
||||
field_name + ".push_back(" + gen_main_class_name(t->type) +
|
||||
"::fetch(env, o_)); "
|
||||
"if (o_) { env->DeleteLocalRef(o_); "
|
||||
"} } "
|
||||
"env->DeleteLocalRef(arr_tmp_); "
|
||||
"} }";
|
||||
template_type = gen_main_class_name(t->type);
|
||||
}
|
||||
return res_begin + res + res_end;
|
||||
return "jni::FetchVector<" + template_type + ">::fetch(env, (jobjectArray)" + fetch_object + ");";
|
||||
}
|
||||
|
||||
std::string TD_TL_writer_jni_cpp::gen_type_fetch(const std::string &field_name, const tl::tl_tree_type *tree_type,
|
||||
@ -229,7 +160,7 @@ std::string TD_TL_writer_jni_cpp::gen_type_fetch(const std::string &field_name,
|
||||
}
|
||||
|
||||
if (name == "Bool") {
|
||||
res = "env->GetBooleanField(p, " + field_name + "fieldID)";
|
||||
res = "(env->GetBooleanField(p, " + field_name + "fieldID) != 0)";
|
||||
} else if (name == "Int32") {
|
||||
res = "env->GetIntField(p, " + field_name + "fieldID)";
|
||||
} else if (name == "Int53" || name == "Int64") {
|
||||
@ -242,13 +173,13 @@ std::string TD_TL_writer_jni_cpp::gen_type_fetch(const std::string &field_name,
|
||||
res = "jni::from_bytes(env, (jbyteArray)jni::fetch_object(env, p, " + field_name + "fieldID))";
|
||||
} else if (name == "Vector") {
|
||||
const tl::tl_tree_type *child = static_cast<const tl::tl_tree_type *>(tree_type->children[0]);
|
||||
return gen_vector_fetch(field_name, child, vars, parser_type);
|
||||
res = gen_vector_fetch(field_name, child, vars, parser_type);
|
||||
} else {
|
||||
if (field_name == "") {
|
||||
return gen_main_class_name(tree_type->type) + "::fetch(env, p)";
|
||||
}
|
||||
res = "({jobject jobject_tmp_ = jni::fetch_object(env, p, " + field_name + "fieldID); " +
|
||||
gen_main_class_name(tree_type->type) + "::fetch(env, jobject_tmp_);})";
|
||||
res = "jni::fetch_tl_object<" + gen_main_class_name(tree_type->type) + ">(env, jni::fetch_object(env, p, " +
|
||||
field_name + "fieldID));";
|
||||
}
|
||||
return res_begin + res;
|
||||
}
|
||||
@ -523,7 +454,8 @@ std::string TD_TL_writer_jni_cpp::gen_store_function_begin(const std::string &st
|
||||
"void " +
|
||||
class_name + "::store(" + storer_name + " &s" +
|
||||
std::string(storer_type <= 0 ? "" : ", const char *field_name") + ") const {\n" +
|
||||
(storer_type <= 0 ? " if (!(s = env->AllocObject(Class))) { return; }\n"
|
||||
(storer_type <= 0 ? " s = env->AllocObject(Class);\n"
|
||||
" if (!s) { return; }\n"
|
||||
: " if (!LOG_IS_STRIPPED(ERROR)) {\n"
|
||||
" s.store_class_begin(field_name, \"" +
|
||||
get_pretty_class_name(class_name) + "\");\n");
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "td/utils/format.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
#include <type_traits>
|
||||
@ -245,8 +246,8 @@ void DeviceTokenManager::loop() {
|
||||
net_query = G()->net_query_creator().create(
|
||||
create_storer(telegram_api::account_unregisterDevice(token_type, info.token, std::move(other_user_ids))));
|
||||
} else {
|
||||
net_query = G()->net_query_creator().create(create_storer(
|
||||
telegram_api::account_registerDevice(token_type, info.token, info.is_app_sandbox, std::move(other_user_ids))));
|
||||
net_query = G()->net_query_creator().create(create_storer(telegram_api::account_registerDevice(
|
||||
token_type, info.token, info.is_app_sandbox, std::move(other_user_ids))));
|
||||
}
|
||||
info.net_query_id = net_query->id();
|
||||
G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this, token_type));
|
||||
|
@ -32,7 +32,7 @@ jmethodID DoubleGetValueMethodID;
|
||||
jclass get_jclass(JNIEnv *env, const char *class_name) {
|
||||
jclass clazz = env->FindClass(class_name);
|
||||
if (!clazz) {
|
||||
LOG(INFO, "Can't find class [%s]", class_name);
|
||||
LOG(INFO) << "Can't find class [" << class_name << "]";
|
||||
env->ExceptionClear();
|
||||
return clazz;
|
||||
}
|
||||
@ -41,7 +41,7 @@ jclass get_jclass(JNIEnv *env, const char *class_name) {
|
||||
env->DeleteLocalRef(clazz);
|
||||
|
||||
if (!clazz_global) {
|
||||
LOG(ERROR, "Can't create global reference to [%s]", class_name);
|
||||
LOG(ERROR) << "Can't create global reference to [" << class_name << "]";
|
||||
env->FatalError("Can't create global reference");
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char
|
||||
return res;
|
||||
}
|
||||
|
||||
LOG(ERROR, "Can't find method %s %s", name, sig);
|
||||
LOG(ERROR) << "Can't find method [" << name << "] with signature [" << sig << "]";
|
||||
env->FatalError("Can't find method");
|
||||
}
|
||||
return nullptr;
|
||||
@ -68,7 +68,7 @@ jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *s
|
||||
return res;
|
||||
}
|
||||
|
||||
LOG(ERROR, "Can't find field name=(%s) sig=(%s)", name, sig);
|
||||
LOG(ERROR) << "Can't find field [" << name << "] with signature [" << sig << "]";
|
||||
env->FatalError("Can't find field");
|
||||
return 0;
|
||||
}
|
||||
@ -229,8 +229,10 @@ std::string from_bytes(JNIEnv *env, jbyteArray arr) {
|
||||
std::string b;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
if (length != 0) {
|
||||
b.resize(narrow_cast<size_t>(length));
|
||||
env->GetByteArrayRegion(arr, 0, length, reinterpret_cast<jbyte *>(&b[0]));
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return b;
|
||||
@ -240,7 +242,7 @@ jbyteArray to_bytes(JNIEnv *env, const std::string &b) {
|
||||
static_assert(sizeof(char) == sizeof(jbyte), "Mismatched jbyte size");
|
||||
jsize length = narrow_cast<jsize>(b.size());
|
||||
jbyteArray arr = env->NewByteArray(length);
|
||||
if (arr != nullptr) {
|
||||
if (arr != nullptr && length != 0) {
|
||||
env->SetByteArrayRegion(arr, 0, length, reinterpret_cast<const jbyte *>(b.data()));
|
||||
}
|
||||
return arr;
|
||||
@ -250,7 +252,7 @@ jintArray store_vector(JNIEnv *env, const std::vector<std::int32_t> &v) {
|
||||
static_assert(sizeof(std::int32_t) == sizeof(jint), "Mismatched jint size");
|
||||
jsize length = narrow_cast<jsize>(v.size());
|
||||
jintArray arr = env->NewIntArray(length);
|
||||
if (arr) {
|
||||
if (arr != nullptr && length != 0) {
|
||||
env->SetIntArrayRegion(arr, 0, length, reinterpret_cast<const jint *>(&v[0]));
|
||||
}
|
||||
return arr;
|
||||
@ -260,7 +262,7 @@ jlongArray store_vector(JNIEnv *env, const std::vector<std::int64_t> &v) {
|
||||
static_assert(sizeof(std::int64_t) == sizeof(jlong), "Mismatched jlong size");
|
||||
jsize length = narrow_cast<jsize>(v.size());
|
||||
jlongArray arr = env->NewLongArray(length);
|
||||
if (arr) {
|
||||
if (arr != nullptr && length != 0) {
|
||||
env->SetLongArrayRegion(arr, 0, length, reinterpret_cast<const jlong *>(&v[0]));
|
||||
}
|
||||
return arr;
|
||||
@ -270,7 +272,7 @@ jdoubleArray store_vector(JNIEnv *env, const std::vector<double> &v) {
|
||||
static_assert(sizeof(double) == sizeof(jdouble), "Mismatched jdouble size");
|
||||
jsize length = narrow_cast<jsize>(v.size());
|
||||
jdoubleArray arr = env->NewDoubleArray(length);
|
||||
if (arr) {
|
||||
if (arr != nullptr && length != 0) {
|
||||
env->SetDoubleArrayRegion(arr, 0, length, reinterpret_cast<const jdouble *>(&v[0]));
|
||||
}
|
||||
return arr;
|
||||
@ -279,7 +281,7 @@ jdoubleArray store_vector(JNIEnv *env, const std::vector<double> &v) {
|
||||
jobjectArray store_vector(JNIEnv *env, const std::vector<std::string> &v) {
|
||||
jsize length = narrow_cast<jsize>(v.size());
|
||||
jobjectArray arr = env->NewObjectArray(length, StringClass, 0);
|
||||
if (arr) {
|
||||
if (arr != nullptr) {
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
jstring str = to_jstring(env, v[i]);
|
||||
if (str) {
|
||||
@ -291,5 +293,44 @@ jobjectArray store_vector(JNIEnv *env, const std::vector<std::string> &v) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
std::vector<std::int32_t> fetch_vector(JNIEnv *env, jintArray arr) {
|
||||
std::vector<std::int32_t> result;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
if (length != 0) {
|
||||
result.resize(length);
|
||||
env->GetIntArrayRegion(arr, 0, length, reinterpret_cast<jint *>(&result[0]));
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::int64_t> fetch_vector(JNIEnv *env, jlongArray arr) {
|
||||
std::vector<std::int64_t> result;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
if (length != 0) {
|
||||
result.resize(length);
|
||||
env->GetLongArrayRegion(arr, 0, length, reinterpret_cast<jlong *>(&result[0]));
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<double> fetch_vector(JNIEnv *env, jdoubleArray arr) {
|
||||
std::vector<double> result;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
if (length != 0) {
|
||||
result.resize(length);
|
||||
env->GetDoubleArrayRegion(arr, 0, length, reinterpret_cast<jdouble *>(&result[0]));
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
} // namespace td
|
||||
|
@ -74,7 +74,7 @@ template <class T>
|
||||
jobjectArray store_vector(JNIEnv *env, const std::vector<T> &v) {
|
||||
jint length = static_cast<jint>(v.size());
|
||||
jobjectArray arr = env->NewObjectArray(length, T::element_type::Class, jobject());
|
||||
if (arr) {
|
||||
if (arr != nullptr) {
|
||||
for (jint i = 0; i < length; i++) {
|
||||
if (v[i] != nullptr) {
|
||||
jobject stored_object;
|
||||
@ -114,7 +114,7 @@ template <class T>
|
||||
jobjectArray store_vector(JNIEnv *env, const std::vector<std::vector<T>> &v) {
|
||||
jint length = static_cast<jint>(v.size());
|
||||
jobjectArray arr = env->NewObjectArray(length, get_array_class<typename T::element_type>::get(), 0);
|
||||
if (arr) {
|
||||
if (arr != nullptr) {
|
||||
for (jint i = 0; i < length; i++) {
|
||||
auto stored_array = store_vector(env, v[i]);
|
||||
if (stored_array) {
|
||||
@ -126,5 +126,73 @@ jobjectArray store_vector(JNIEnv *env, const std::vector<std::vector<T>> &v) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto fetch_tl_object(JNIEnv *env, jobject obj) {
|
||||
decltype(T::fetch(env, obj)) result;
|
||||
if (obj != nullptr) {
|
||||
result = T::fetch(env, obj);
|
||||
env->DeleteLocalRef(obj);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::int32_t> fetch_vector(JNIEnv *env, jintArray arr);
|
||||
|
||||
std::vector<std::int64_t> fetch_vector(JNIEnv *env, jlongArray arr);
|
||||
|
||||
std::vector<double> fetch_vector(JNIEnv *env, jdoubleArray arr);
|
||||
|
||||
template <class T>
|
||||
struct FetchVector {
|
||||
static auto fetch(JNIEnv *env, jobjectArray arr) {
|
||||
std::vector<decltype(fetch_tl_object<T>(env, jobject()))> result;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
result.reserve(length);
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
result.push_back(fetch_tl_object<T>(env, env->GetObjectArrayElement(arr, i)));
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FetchVector<std::string> {
|
||||
static std::vector<std::string> fetch(JNIEnv *env, jobjectArray arr) {
|
||||
std::vector<std::string> result;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
result.reserve(length);
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
jstring str = (jstring)env->GetObjectArrayElement(arr, i);
|
||||
result.push_back(jni::from_jstring(env, str));
|
||||
if (str) {
|
||||
env->DeleteLocalRef(str);
|
||||
}
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct FetchVector<std::vector<T>> {
|
||||
static auto fetch(JNIEnv *env, jobjectArray arr) {
|
||||
std::vector<decltype(FetchVector<T>::fetch(env, jobjectArray()))> result;
|
||||
if (arr != nullptr) {
|
||||
jsize length = env->GetArrayLength(arr);
|
||||
result.reserve(length);
|
||||
for (jsize i = 0; i < length; i++) {
|
||||
result.push_back(FetchVector<T>::fetch(env, (jobjectArray)env->GetObjectArrayElement(arr, i)));
|
||||
}
|
||||
env->DeleteLocalRef(arr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jni
|
||||
} // namespace td
|
||||
|
@ -165,10 +165,6 @@ class DowncastHelper : public T {
|
||||
int32 get_id() const override {
|
||||
return constructor_;
|
||||
}
|
||||
void store(TlStorerUnsafe &s) const override {
|
||||
}
|
||||
void store(TlStorerCalcLength &s) const override {
|
||||
}
|
||||
void store(TlStorerToString &s, const char *field_name) const override {
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user