xref: /aosp_15_r20/external/libtextclassifier/native/utils/java/jni-helper.cc (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "utils/java/jni-helper.h"
18 
19 #include "utils/base/status_macros.h"
20 
21 namespace libtextclassifier3 {
22 
FindClass(JNIEnv * env,const char * class_name)23 StatusOr<ScopedLocalRef<jclass>> JniHelper::FindClass(JNIEnv* env,
24                                                       const char* class_name) {
25   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
26   ScopedLocalRef<jclass> result(env->FindClass(class_name), env);
27   TC3_NO_EXCEPTION_OR_RETURN;
28   TC3_NOT_NULL_OR_RETURN;
29   return result;
30 }
31 
GetObjectClass(JNIEnv * env,jobject object)32 StatusOr<ScopedLocalRef<jclass>> JniHelper::GetObjectClass(JNIEnv* env,
33                                                            jobject object) {
34   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
35   ScopedLocalRef<jclass> result(env->GetObjectClass(object), env);
36   TC3_NO_EXCEPTION_OR_RETURN;
37   TC3_NOT_NULL_OR_RETURN;
38   return result;
39 }
40 
GetMethodID(JNIEnv * env,jclass clazz,const char * method_name,const char * signature)41 StatusOr<jmethodID> JniHelper::GetMethodID(JNIEnv* env, jclass clazz,
42                                            const char* method_name,
43                                            const char* signature) {
44   jmethodID result = env->GetMethodID(clazz, method_name, signature);
45   TC3_NO_EXCEPTION_OR_RETURN;
46   TC3_NOT_NULL_OR_RETURN;
47   return result;
48 }
49 
GetStaticMethodID(JNIEnv * env,jclass clazz,const char * method_name,const char * signature)50 StatusOr<jmethodID> JniHelper::GetStaticMethodID(JNIEnv* env, jclass clazz,
51                                                  const char* method_name,
52                                                  const char* signature) {
53   jmethodID result = env->GetStaticMethodID(clazz, method_name, signature);
54   TC3_NO_EXCEPTION_OR_RETURN;
55   TC3_NOT_NULL_OR_RETURN;
56   return result;
57 }
58 
GetFieldID(JNIEnv * env,jclass clazz,const char * field_name,const char * signature)59 StatusOr<jfieldID> JniHelper::GetFieldID(JNIEnv* env, jclass clazz,
60                                          const char* field_name,
61                                          const char* signature) {
62   jfieldID result = env->GetFieldID(clazz, field_name, signature);
63   TC3_NO_EXCEPTION_OR_RETURN;
64   TC3_NOT_NULL_OR_RETURN;
65   return result;
66 }
67 
GetStaticFieldID(JNIEnv * env,jclass clazz,const char * field_name,const char * signature)68 StatusOr<jfieldID> JniHelper::GetStaticFieldID(JNIEnv* env, jclass clazz,
69                                                const char* field_name,
70                                                const char* signature) {
71   jfieldID result = env->GetStaticFieldID(clazz, field_name, signature);
72   TC3_NO_EXCEPTION_OR_RETURN;
73   TC3_NOT_NULL_OR_RETURN;
74   return result;
75 }
76 
GetStaticObjectField(JNIEnv * env,jclass class_name,jfieldID field_id)77 StatusOr<ScopedLocalRef<jobject>> JniHelper::GetStaticObjectField(
78     JNIEnv* env, jclass class_name, jfieldID field_id) {
79   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
80   ScopedLocalRef<jobject> result(
81       env->GetStaticObjectField(class_name, field_id), env);
82   TC3_NO_EXCEPTION_OR_RETURN;
83   TC3_NOT_NULL_OR_RETURN;
84   return result;
85 }
86 
GetStaticIntField(JNIEnv * env,jclass class_name,jfieldID field_id)87 StatusOr<jint> JniHelper::GetStaticIntField(JNIEnv* env, jclass class_name,
88                                             jfieldID field_id) {
89   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
90   jint result = env->GetStaticIntField(class_name, field_id);
91   TC3_NO_EXCEPTION_OR_RETURN;
92   return result;
93 }
94 
NewByteArray(JNIEnv * env,jsize length)95 StatusOr<ScopedLocalRef<jbyteArray>> JniHelper::NewByteArray(JNIEnv* env,
96                                                              jsize length) {
97   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
98   ScopedLocalRef<jbyteArray> result(env->NewByteArray(length), env);
99   TC3_NO_EXCEPTION_OR_RETURN;
100   TC3_NOT_NULL_OR_RETURN;
101   return result;
102 }
103 
CallVoidMethod(JNIEnv * env,jobject object,jmethodID method_id,...)104 Status JniHelper::CallVoidMethod(JNIEnv* env, jobject object,
105                                  jmethodID method_id, ...) {
106   va_list args;
107   va_start(args, method_id);
108   env->CallVoidMethodV(object, method_id, args);
109   va_end(args);
110 
111   TC3_NO_EXCEPTION_OR_RETURN;
112   return Status::OK;
113 }
114 
CallBooleanMethod(JNIEnv * env,jobject object,jmethodID method_id,...)115 StatusOr<bool> JniHelper::CallBooleanMethod(JNIEnv* env, jobject object,
116                                             jmethodID method_id, ...) {
117   va_list args;
118   va_start(args, method_id);
119   bool result = env->CallBooleanMethodV(object, method_id, args);
120   va_end(args);
121 
122   TC3_NO_EXCEPTION_OR_RETURN;
123   return result;
124 }
125 
CallIntMethod(JNIEnv * env,jobject object,jmethodID method_id,...)126 StatusOr<int32> JniHelper::CallIntMethod(JNIEnv* env, jobject object,
127                                          jmethodID method_id, ...) {
128   va_list args;
129   va_start(args, method_id);
130   jint result = env->CallIntMethodV(object, method_id, args);
131   va_end(args);
132 
133   TC3_NO_EXCEPTION_OR_RETURN;
134   return result;
135 }
136 
CallLongMethod(JNIEnv * env,jobject object,jmethodID method_id,...)137 StatusOr<int64> JniHelper::CallLongMethod(JNIEnv* env, jobject object,
138                                           jmethodID method_id, ...) {
139   va_list args;
140   va_start(args, method_id);
141   jlong result = env->CallLongMethodV(object, method_id, args);
142   va_end(args);
143 
144   TC3_NO_EXCEPTION_OR_RETURN;
145   return result;
146 }
147 
CallFloatMethod(JNIEnv * env,jobject object,jmethodID method_id,...)148 StatusOr<float> JniHelper::CallFloatMethod(JNIEnv* env, jobject object,
149                                            jmethodID method_id, ...) {
150   va_list args;
151   va_start(args, method_id);
152   jfloat result = env->CallFloatMethodV(object, method_id, args);
153   va_end(args);
154 
155   TC3_NO_EXCEPTION_OR_RETURN;
156   return result;
157 }
158 
CallDoubleMethod(JNIEnv * env,jobject object,jmethodID method_id,...)159 StatusOr<double> JniHelper::CallDoubleMethod(JNIEnv* env, jobject object,
160                                              jmethodID method_id, ...) {
161   va_list args;
162   va_start(args, method_id);
163   jdouble result = env->CallDoubleMethodV(object, method_id, args);
164   va_end(args);
165 
166   TC3_NO_EXCEPTION_OR_RETURN;
167   return result;
168 }
169 
NewIntArray(JNIEnv * env,jsize length)170 StatusOr<ScopedLocalRef<jintArray>> JniHelper::NewIntArray(JNIEnv* env,
171                                                            jsize length) {
172   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
173   ScopedLocalRef<jintArray> result(env->NewIntArray(length), env);
174   TC3_NO_EXCEPTION_OR_RETURN;
175   TC3_NOT_NULL_OR_RETURN;
176   return result;
177 }
178 
NewFloatArray(JNIEnv * env,jsize length)179 StatusOr<ScopedLocalRef<jfloatArray>> JniHelper::NewFloatArray(JNIEnv* env,
180                                                                jsize length) {
181   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
182   ScopedLocalRef<jfloatArray> result(env->NewFloatArray(length), env);
183   TC3_NO_EXCEPTION_OR_RETURN;
184   TC3_NOT_NULL_OR_RETURN;
185   return result;
186 }
187 
SetObjectArrayElement(JNIEnv * env,jobjectArray array,jsize index,jobject val)188 Status JniHelper::SetObjectArrayElement(JNIEnv* env, jobjectArray array,
189                                         jsize index, jobject val) {
190   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
191   env->SetObjectArrayElement(array, index, val);
192   TC3_NO_EXCEPTION_OR_RETURN;
193   return Status::OK;
194 }
195 
GetArrayLength(JNIEnv * env,jarray array)196 StatusOr<jsize> JniHelper::GetArrayLength(JNIEnv* env, jarray array) {
197   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
198   jsize result = env->GetArrayLength(array);
199   TC3_NO_EXCEPTION_OR_RETURN;
200   return result;
201 }
202 
GetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize len,jbyte * buf)203 Status JniHelper::GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start,
204                                      jsize len, jbyte* buf) {
205   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
206   env->GetByteArrayRegion(array, start, len, buf);
207   TC3_NO_EXCEPTION_OR_RETURN;
208   return Status::OK;
209 }
210 
SetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize len,const jbyte * buf)211 Status JniHelper::SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start,
212                                      jsize len, const jbyte* buf) {
213   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
214   env->SetByteArrayRegion(array, start, len, buf);
215   TC3_NO_EXCEPTION_OR_RETURN;
216   return Status::OK;
217 }
218 
SetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize len,const jint * buf)219 Status JniHelper::SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start,
220                                     jsize len, const jint* buf) {
221   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
222   env->SetIntArrayRegion(array, start, len, buf);
223   TC3_NO_EXCEPTION_OR_RETURN;
224   return Status::OK;
225 }
226 
SetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize len,const jfloat * buf)227 Status JniHelper::SetFloatArrayRegion(JNIEnv* env, jfloatArray array,
228                                       jsize start, jsize len,
229                                       const jfloat* buf) {
230   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
231   env->SetFloatArrayRegion(array, start, len, buf);
232   TC3_NO_EXCEPTION_OR_RETURN;
233   return Status::OK;
234 }
235 
NewObjectArray(JNIEnv * env,jsize length,jclass element_class,jobject initial_element)236 StatusOr<ScopedLocalRef<jobjectArray>> JniHelper::NewObjectArray(
237     JNIEnv* env, jsize length, jclass element_class, jobject initial_element) {
238   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
239   ScopedLocalRef<jobjectArray> result(
240       env->NewObjectArray(length, element_class, initial_element), env);
241   TC3_NO_EXCEPTION_OR_RETURN;
242   TC3_NOT_NULL_OR_RETURN;
243   return result;
244 }
245 
NewStringUTF(JNIEnv * env,const char * bytes)246 StatusOr<ScopedLocalRef<jstring>> JniHelper::NewStringUTF(JNIEnv* env,
247                                                           const char* bytes) {
248   TC3_ENSURE_LOCAL_CAPACITY_OR_RETURN;
249   ScopedLocalRef<jstring> result(env->NewStringUTF(bytes), env);
250   TC3_NO_EXCEPTION_OR_RETURN;
251   TC3_NOT_NULL_OR_RETURN;
252   return result;
253 }
254 
JByteArrayToString(JNIEnv * env,jbyteArray array)255 StatusOr<std::string> JByteArrayToString(JNIEnv* env, jbyteArray array) {
256   std::string result;
257   TC3_ASSIGN_OR_RETURN(const int array_length,
258                        JniHelper::GetArrayLength(env, array));
259   result.resize(array_length);
260   TC3_RETURN_IF_ERROR(JniHelper::GetByteArrayRegion(
261       env, array, 0, array_length,
262       reinterpret_cast<jbyte*>(const_cast<char*>(result.data()))));
263   return result;
264 }
265 
JStringToUtf8String(JNIEnv * env,jstring jstr)266 StatusOr<std::string> JStringToUtf8String(JNIEnv* env, jstring jstr) {
267   if (jstr == nullptr) {
268     return "";
269   }
270 
271   TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jclass> string_class,
272                        JniHelper::FindClass(env, "java/lang/String"));
273   TC3_ASSIGN_OR_RETURN(
274       jmethodID get_bytes_id,
275       JniHelper::GetMethodID(env, string_class.get(), "getBytes",
276                              "(Ljava/lang/String;)[B"));
277 
278   TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jstring> encoding,
279                        JniHelper::NewStringUTF(env, "UTF-8"));
280 
281   TC3_ASSIGN_OR_RETURN(ScopedLocalRef<jbyteArray> array,
282                        JniHelper::CallObjectMethod<jbyteArray>(
283                            env, jstr, get_bytes_id, encoding.get()));
284 
285   return JByteArrayToString(env, array.get());
286 }
287 
288 }  // namespace libtextclassifier3
289