From d8f13abb2c57919df75af302fbb158eac315c48e Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 21 Jan 2018 14:45:24 +0300 Subject: [PATCH] Make JNI-bindings package-agnostic. GitOrigin-RevId: a3a66de7561cf0ea9a3faf0b26bda1c34de7d317 --- CMake/iOS.cmake | 4 ++-- CMakeLists.txt | 15 ++++++++----- td/generate/CMakeLists.txt | 12 +++++++--- td/generate/generate_common.cpp | 37 +++++++++++++------------------ td/generate/tl_writer_jni_cpp.cpp | 36 +++++++++++++++++++++--------- td/generate/tl_writer_jni_cpp.h | 9 ++------ td/generate/tl_writer_jni_h.cpp | 4 ++-- tdutils/td/utils/Variant.h | 1 + 8 files changed, 67 insertions(+), 51 deletions(-) diff --git a/CMake/iOS.cmake b/CMake/iOS.cmake index 7a365871d..c83a2f2a8 100644 --- a/CMake/iOS.cmake +++ b/CMake/iOS.cmake @@ -189,10 +189,10 @@ else() endif() message (STATUS ${IOS_ARCH}) -set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS") +set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS") # Set the find root to the iOS developer roots and to user defined paths -set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root") +set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE STRING "iOS find search path root") # default to searching for frameworks first set (CMAKE_FIND_FRAMEWORK FIRST) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54d1f1a65..5b20204c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR) project(TDLib VERSION 1.0.4 LANGUAGES CXX C) +option(TD_ENABLE_JNI "Use \"ON\" to enable JNI-compatible TDLib API.") + if (NOT DEFINED CMAKE_MODULE_PATH) set(CMAKE_MODULE_PATH "") endif() @@ -240,7 +242,7 @@ endif() #SOURCE SETS set_source_files_properties(${TL_TD_AUTO} PROPERTIES GENERATED TRUE) -if (TD_API_JAVA_PACKAGE) +if (TD_ENABLE_JNI) set(TL_JNI_OBJECT td/tl/tl_jni_object.cpp td/tl/tl_jni_object.h @@ -547,7 +549,7 @@ target_include_directories(tdcore PUBLIC $ #include +template static void generate_cpp(const std::string &directory, const std::string &tl_name, const std::string &string_type, const std::string &bytes_type, const std::vector &ext_cpp_includes, const std::vector &ext_h_includes) { std::string path = directory + "/" + tl_name; td::tl::tl_config config = td::tl::read_tl_config_from_file("scheme/" + tl_name + ".tlo"); - td::tl::write_tl_to_file(config, path + ".cpp", - td::TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_cpp_includes)); - td::tl::write_tl_to_file(config, path + ".h", td::TD_TL_writer_h(tl_name, string_type, bytes_type, ext_h_includes)); - td::tl::write_tl_to_file(config, path + ".hpp", td::TD_TL_writer_hpp(tl_name, string_type, bytes_type)); + td::tl::write_tl_to_file(config, path + ".cpp", WriterCpp(tl_name, string_type, bytes_type, ext_cpp_includes)); + td::tl::write_tl_to_file(config, path + ".h", WriterH(tl_name, string_type, bytes_type, ext_h_includes)); + td::tl::write_tl_to_file(config, path + ".hpp", WriterHpp(tl_name, string_type, bytes_type)); } int main() { - generate_cpp("auto/td/telegram", "telegram_api", "std::string", "BufferSlice", - {"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""}); + generate_cpp<>("auto/td/telegram", "telegram_api", "std::string", "BufferSlice", + {"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""}); - generate_cpp("auto/td/telegram", "secret_api", "std::string", "BufferSlice", - {"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""}); + generate_cpp<>("auto/td/telegram", "secret_api", "std::string", "BufferSlice", + {"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""}); - generate_cpp("auto/td/mtproto", "mtproto_api", "Slice", "Slice", - {"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/Slice.h\""}); + generate_cpp<>("auto/td/mtproto", "mtproto_api", "Slice", "Slice", + {"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/Slice.h\""}); -#ifdef TD_API_JAVA_PACKAGE - td::tl::tl_config config = td::tl::read_tl_config_from_file("scheme/td_api.tlo"); - std::string path = "auto/td/telegram/td_api"; - std::string package = TD_API_JAVA_PACKAGE; - std::replace(package.begin(), package.end(), '/', '.'); - td::tl::write_tl_to_file( - config, path + ".cpp", - td::TD_TL_writer_jni_cpp("td_api", "std::string", "std::string", {"\"td/tl/tl_jni_object.h\""}, package)); - td::tl::write_tl_to_file(config, path + ".h", - td::TD_TL_writer_jni_h("td_api", "std::string", "std::string", {""})); - td::tl::write_tl_to_file(config, path + ".hpp", td::TD_TL_writer_hpp("td_api", "std::string", "std::string")); +#ifdef TD_ENABLE_JNI + generate_cpp( + "auto/td/telegram", "td_api", "std::string", "std::string", {"\"td/tl/tl_jni_object.h\""}, {""}); #else - generate_cpp("auto/td/telegram", "td_api", "std::string", "std::string", {}, {""}); + generate_cpp<>("auto/td/telegram", "td_api", "std::string", "std::string", {}, {""}); #endif } diff --git a/td/generate/tl_writer_jni_cpp.cpp b/td/generate/tl_writer_jni_cpp.cpp index 31de1bddc..a3f0edd45 100644 --- a/td/generate/tl_writer_jni_cpp.cpp +++ b/td/generate/tl_writer_jni_cpp.cpp @@ -518,7 +518,7 @@ std::string TD_TL_writer_jni_cpp::gen_basic_java_class_name(std::string name) co } std::string TD_TL_writer_jni_cpp::gen_java_class_name(std::string name) const { - return package_name + "/" + "TdApi" + "$" + gen_basic_java_class_name(name); + return "(PSLICE() << package_name << \"/TdApi$" + gen_basic_java_class_name(name) + "\").c_str()"; } std::string TD_TL_writer_jni_cpp::gen_type_signature(const tl::tl_tree_type *tree_type) const { @@ -543,7 +543,7 @@ std::string TD_TL_writer_jni_cpp::gen_type_signature(const tl::tl_tree_type *tre const tl::tl_tree_type *child = static_cast(tree_type->children[0]); return "[" + gen_type_signature(child); } else { - return "L" + gen_java_class_name(gen_main_class_name(t)) + ";"; + return "L%PACKAGE_NAME%/TdApi$" + gen_basic_java_class_name(gen_main_class_name(t)) + ";"; } assert(false); return ""; @@ -558,9 +558,9 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun "\n" "void " + class_name + "::" + function_name + - "(JNIEnv *env) {\n" + "(JNIEnv *env, const char *package_name) {\n" " " + - class_name_class + " = jni::get_jclass(env, \"" + gen_java_class_name(gen_class_name(t->name)) + "\");\n"; + class_name_class + " = jni::get_jclass(env, " + gen_java_class_name(gen_class_name(t->name)) + ");\n"; if (t->args.size()) { res += @@ -577,8 +577,24 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun assert(field_name.size()); std::string java_field_name = gen_java_field_name(std::string(field_name, 0, field_name.size() - 1)); + std::string type_signature = gen_type_signature(tree_type); + if (type_signature.find("%PACKAGE_NAME%") == std::string::npos) { + type_signature = '"' + type_signature + '"'; + } else { + std::string new_type_signature = "(PSLICE()"; + std::size_t pos = type_signature.find("%PACKAGE_NAME%"); + while (pos != std::string::npos) { + new_type_signature += " << \"" + type_signature.substr(0, pos) + "\" << package_name"; + type_signature = type_signature.substr(pos + 14); + pos = type_signature.find("%PACKAGE_NAME%"); + } + if (!type_signature.empty()) { + new_type_signature += " << \"" + type_signature + "\""; + } + type_signature = new_type_signature + ").c_str()"; + } res += " " + field_name + "fieldID = jni::get_field_id(env, " + class_name_class + ", \"" + java_field_name + - "\", \"" + gen_type_signature(tree_type) + "\");\n"; + "\", " + type_signature + ");\n"; } res += " }\n"; @@ -596,9 +612,9 @@ std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_begin(const std: return "\n" "void " + class_name + "::" + function_name + - "(JNIEnv *env) {\n" - " Class = jni::get_jclass(env, \"" + - gen_java_class_name(class_name) + "\");\n"; + "(JNIEnv *env, const char *package_name) {\n" + " Class = jni::get_jclass(env, " + + gen_java_class_name(class_name) + ");\n"; } std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std::string &function_name, @@ -606,7 +622,7 @@ std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std:: const std::string &class_name, int arity) const { assert(function_name == "init_jni_vars"); assert(arity == 0); - return " " + class_name + "::" + function_name + "(env);\n"; + return " " + class_name + "::" + function_name + "(env, package_name);\n"; } std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std::string &function_name, @@ -615,7 +631,7 @@ std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std:: bool is_function) const { assert(function_name == "init_jni_vars"); assert(arity == 0); - return " " + gen_class_name(t->name) + "::" + function_name + "(env);\n"; + return " " + gen_class_name(t->name) + "::" + function_name + "(env, package_name);\n"; } std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_end(const std::string &function_name, diff --git a/td/generate/tl_writer_jni_cpp.h b/td/generate/tl_writer_jni_cpp.h index 372990830..414cb4c64 100644 --- a/td/generate/tl_writer_jni_cpp.h +++ b/td/generate/tl_writer_jni_cpp.h @@ -38,13 +38,8 @@ class TD_TL_writer_jni_cpp : public TD_TL_writer_cpp { public: TD_TL_writer_jni_cpp(const std::string &tl_name, const std::string &string_type, const std::string &bytes_type, - const std::vector &ext_include, const std::string &package_name_) - : TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_include), package_name(package_name_) { - for (std::size_t i = 0; i < package_name.size(); i++) { - if (package_name[i] == '.') { - package_name[i] = '/'; - } - } + const std::vector &ext_include) + : TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_include) { } bool is_built_in_simple_type(const std::string &name) const override; diff --git a/td/generate/tl_writer_jni_h.cpp b/td/generate/tl_writer_jni_h.cpp index 5fe7abc98..94d9b288b 100644 --- a/td/generate/tl_writer_jni_h.cpp +++ b/td/generate/tl_writer_jni_h.cpp @@ -141,7 +141,7 @@ std::string TD_TL_writer_jni_h::gen_additional_function(const std::string &funct if (function_name == "init_jni_vars") { return "\n" " static void " + - function_name + "(JNIEnv *env);\n"; + function_name + "(JNIEnv *env, const char *package_name);\n"; } return TD_TL_writer_h::gen_additional_function(function_name, t, is_function); @@ -154,7 +154,7 @@ std::string TD_TL_writer_jni_h::gen_additional_proxy_function_begin(const std::s if (function_name == "init_jni_vars") { return "\n" " static void " + - function_name + "(JNIEnv *env);\n"; + function_name + "(JNIEnv *env, const char *package_name);\n"; } return TD_TL_writer_h::gen_additional_proxy_function_begin(function_name, type, class_name, arity, is_function); diff --git a/tdutils/td/utils/Variant.h b/tdutils/td/utils/Variant.h index f70242cbb..9b6e0561c 100644 --- a/tdutils/td/utils/Variant.h +++ b/tdutils/td/utils/Variant.h @@ -236,6 +236,7 @@ class Variant { int32 get_offset() const { return offset_; } + private: union { int64 align_;