tdlib-obf API
Reference documentation for the public tdlib-obf API, generated from TDLib schemas and public headers
Loading...
Searching...
No Matches
tl_jni_object.h
1//
2// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2026
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7#pragma once
8
9#include <jni.h>
10
11#include <cstdint>
12#include <memory>
13#include <string>
14#include <vector>
15
16namespace td {
17namespace td_api {
18class keyboardButton;
19class inlineKeyboardButton;
20class pageBlockTableCell;
21} // namespace td_api
22
23namespace jni {
24
25extern thread_local bool parse_error;
26
27extern jclass ArrayKeyboardButtonClass;
28extern jclass ArrayInlineKeyboardButtonClass;
29extern jclass ArrayPageBlockTableCellClass;
30extern jmethodID GetConstructorID;
31extern jmethodID BooleanGetValueMethodID;
32extern jmethodID IntegerGetValueMethodID;
33extern jmethodID LongGetValueMethodID;
34extern jmethodID DoubleGetValueMethodID;
35
36void set_fatal_error(JNIEnv *env, const std::string &error);
37
38jclass get_jclass(JNIEnv *env, const char *class_name);
39
40jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name, const char *signature);
41
42jfieldID get_field_id(JNIEnv *env, jclass clazz, const char *name, const char *signature);
43
44jfieldID get_static_field_id(JNIEnv *env, jclass clazz, const char *name, const char *signature);
45
46void register_native_method(JNIEnv *env, jclass clazz, std::string name, std::string signature, void *function_ptr);
47
49 JavaVM *java_vm_;
50
51 void detach() {
52 if (java_vm_ != nullptr) {
53 java_vm_->DetachCurrentThread();
54 java_vm_ = nullptr;
55 }
56 }
57
58 public:
59 explicit JvmThreadDetacher(JavaVM *java_vm) : java_vm_(java_vm) {
60 }
61
62 JvmThreadDetacher(const JvmThreadDetacher &) = delete;
63 JvmThreadDetacher &operator=(const JvmThreadDetacher &) = delete;
64 JvmThreadDetacher(JvmThreadDetacher &&other) noexcept : java_vm_(other.java_vm_) {
65 other.java_vm_ = nullptr;
66 }
67 JvmThreadDetacher &operator=(JvmThreadDetacher &&) = delete;
69 detach();
70 }
71
72 void operator()(JNIEnv *env) {
73 detach();
74 }
75};
76
77std::unique_ptr<JNIEnv, JvmThreadDetacher> get_jni_env(JavaVM *java_vm, jint jni_version);
78
79std::string fetch_string(JNIEnv *env, jobject o, jfieldID id);
80
81std::string fetch_static_string(JNIEnv *env, jclass clazz, jfieldID id);
82
83inline jobject fetch_object(JNIEnv *env, const jobject &o, const jfieldID &id) {
84 // null return object is implicitly allowed
85 return env->GetObjectField(o, id);
86}
87
88inline bool have_parse_error() {
89 return parse_error;
90}
91
92inline void reset_parse_error() {
93 parse_error = false;
94}
95
96std::string from_jstring(JNIEnv *env, jstring s);
97
98jstring to_jstring(JNIEnv *env, const std::string &s);
99
100std::string from_bytes(JNIEnv *env, jbyteArray arr);
101
102jbyteArray to_bytes(JNIEnv *env, const std::string &b);
103
104void init_vars(JNIEnv *env, const char *td_api_java_package);
105
106jintArray store_vector(JNIEnv *env, const std::vector<std::int32_t> &v);
107
108jlongArray store_vector(JNIEnv *env, const std::vector<std::int64_t> &v);
109
110jdoubleArray store_vector(JNIEnv *env, const std::vector<double> &v);
111
112jobjectArray store_vector(JNIEnv *env, const std::vector<std::string> &v);
113
114template <class T>
115jobjectArray store_vector(JNIEnv *env, const std::vector<T> &v) {
116 auto length = static_cast<jint>(v.size());
117 T::element_type::init_jni_vars(env);
118 jobjectArray arr = env->NewObjectArray(length, T::element_type::Class, jobject());
119 if (arr != nullptr) {
120 for (jint i = 0; i < length; i++) {
121 if (v[i] != nullptr) {
122 jobject stored_object;
123 v[i]->store(env, stored_object);
124 if (stored_object) {
125 env->SetObjectArrayElement(arr, i, stored_object);
126 env->DeleteLocalRef(stored_object);
127 }
128 }
129 }
130 }
131 return arr;
132}
133
134template <class T>
136 static jclass get();
137};
138
139template <>
140class get_array_class<td_api::keyboardButton> {
141 public:
142 static jclass get() {
143 return ArrayKeyboardButtonClass;
144 }
145};
146
147template <>
148class get_array_class<td_api::inlineKeyboardButton> {
149 public:
150 static jclass get() {
151 return ArrayInlineKeyboardButtonClass;
152 }
153};
154
155template <>
156class get_array_class<td_api::pageBlockTableCell> {
157 public:
158 static jclass get() {
159 return ArrayPageBlockTableCellClass;
160 }
161};
162
163template <class T>
164jobjectArray store_vector(JNIEnv *env, const std::vector<std::vector<T>> &v) {
165 auto length = static_cast<jint>(v.size());
166 jobjectArray arr = env->NewObjectArray(length, get_array_class<typename T::element_type>::get(), 0);
167 if (arr != nullptr) {
168 for (jint i = 0; i < length; i++) {
169 auto stored_array = store_vector(env, v[i]);
170 if (stored_array) {
171 env->SetObjectArrayElement(arr, i, stored_array);
172 env->DeleteLocalRef(stored_array);
173 }
174 }
175 }
176 return arr;
177}
178
179template <class T>
180auto fetch_tl_object(JNIEnv *env, jobject obj) {
181 decltype(T::fetch(env, obj)) result;
182 if (obj != nullptr) {
183 result = T::fetch(env, obj);
184 env->DeleteLocalRef(obj);
185 }
186 return result;
187}
188
189std::vector<std::int32_t> fetch_vector(JNIEnv *env, jintArray arr);
190
191std::vector<std::int64_t> fetch_vector(JNIEnv *env, jlongArray arr);
192
193std::vector<double> fetch_vector(JNIEnv *env, jdoubleArray arr);
194
195template <class T>
197 static auto fetch(JNIEnv *env, jobjectArray arr) {
198 std::vector<decltype(fetch_tl_object<T>(env, jobject()))> result;
199 if (arr != nullptr) {
200 jsize length = env->GetArrayLength(arr);
201 result.reserve(length);
202 for (jsize i = 0; i < length; i++) {
203 result.push_back(fetch_tl_object<T>(env, env->GetObjectArrayElement(arr, i)));
204 }
205 env->DeleteLocalRef(arr);
206 }
207 return result;
208 }
209};
210
211template <>
212struct FetchVector<std::string> {
213 static std::vector<std::string> fetch(JNIEnv *env, jobjectArray arr) {
214 std::vector<std::string> result;
215 if (arr != nullptr) {
216 jsize length = env->GetArrayLength(arr);
217 result.reserve(length);
218 for (jsize i = 0; i < length; i++) {
219 jstring str = (jstring)env->GetObjectArrayElement(arr, i);
220 result.push_back(from_jstring(env, str));
221 if (str) {
222 env->DeleteLocalRef(str);
223 }
224 }
225 env->DeleteLocalRef(arr);
226 }
227 return result;
228 }
229};
230
231template <>
232struct FetchVector<jbyteArray> {
233 static std::vector<std::string> fetch(JNIEnv *env, jobjectArray arr) {
234 std::vector<std::string> result;
235 if (arr != nullptr) {
236 jsize length = env->GetArrayLength(arr);
237 result.reserve(length);
238 for (jsize i = 0; i < length; i++) {
239 jbyteArray bytes = (jbyteArray)env->GetObjectArrayElement(arr, i);
240 result.push_back(from_bytes(env, bytes));
241 if (bytes) {
242 env->DeleteLocalRef(bytes);
243 }
244 }
245 env->DeleteLocalRef(arr);
246 }
247 return result;
248 }
249};
250
251template <class T>
252struct FetchVector<std::vector<T>> {
253 static auto fetch(JNIEnv *env, jobjectArray arr) {
254 std::vector<decltype(FetchVector<T>::fetch(env, jobjectArray()))> result;
255 if (arr != nullptr) {
256 jsize length = env->GetArrayLength(arr);
257 result.reserve(length);
258 for (jsize i = 0; i < length; i++) {
259 result.push_back(FetchVector<T>::fetch(env, (jobjectArray)env->GetObjectArrayElement(arr, i)));
260 }
261 env->DeleteLocalRef(arr);
262 }
263 return result;
264 }
265};
266
267} // namespace jni
268} // namespace td