lime
Lime is a C++ library implementing Open Whisper System Signal protocol
functions.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <jni/types.hpp>
4 #include <jni/errors.hpp>
5 #include <jni/wrapping.hpp>
6 #include <jni/ownership.hpp>
7 #include <jni/typed_methods.hpp>
8 #include <jni/arraylike.hpp>
9 
10 #include <type_traits>
11 #include <cstdlib>
12 
13 namespace jni
14  {
15  inline jint GetVersion(JNIEnv& env)
16  {
17  return env.GetVersion();
18  }
19 
20 
21  inline jclass& DefineClass(JNIEnv& env, const char* name, jobject& loader, const jbyte* buf, jsize size)
22  {
23  return *CheckJavaException(env,
24  Wrap<jclass*>(env.DefineClass(name, Unwrap(loader), buf, Unwrap(size))));
25  }
26 
27  template < class Array >
28  auto DefineClass(JNIEnv& env, const char* name, jobject& loader, const Array& buf)
29  -> std::enable_if_t< IsArraylike<Array>::value, jclass& >
30  {
31  return DefineClass(env, name, loader, ArraylikeData(buf), ArraylikeSize(buf));
32  }
33 
34  inline jclass& FindClass(JNIEnv& env, const char* name)
35  {
36  return *CheckJavaException(env, Wrap<jclass*>(env.FindClass(name)));
37  }
38 
39 
40  inline jmethodID* FromReflectedMethod(JNIEnv& env, jobject* obj)
41  {
42  return CheckJavaException(env,
43  Wrap<jmethodID*>(env.FromReflectedMethod(Unwrap(obj))));
44  }
45 
46  inline jfieldID* FromReflectedField(JNIEnv& env, jobject* obj)
47  {
48  return CheckJavaException(env,
49  Wrap<jfieldID*>(env.FromReflectedField(Unwrap(obj))));
50  }
51 
52  inline jobject& ToReflectedMethod(JNIEnv& env, jclass& clazz, jmethodID& method, bool isStatic)
53  {
54  return *CheckJavaException(env,
55  Wrap<jobject*>(env.ToReflectedMethod(Unwrap(clazz), Unwrap(method), isStatic)));
56  }
57 
58  inline jobject& ToReflectedField(JNIEnv& env, jclass& clazz, jfieldID& field, bool isStatic)
59  {
60  return *CheckJavaException(env,
61  Wrap<jobject*>(env.ToReflectedField(Unwrap(clazz), Unwrap(field), isStatic)));
62  }
63 
64 
65  inline jclass* GetSuperclass(JNIEnv& env, jclass& clazz)
66  {
67  return CheckJavaException(env,
68  Wrap<jclass*>(env.GetSuperclass(Unwrap(clazz))));
69  }
70 
71  inline bool IsAssignableFrom(JNIEnv& env, jclass& clazz1, jclass& clazz2)
72  {
73  return CheckJavaException(env,
74  env.IsAssignableFrom(Unwrap(clazz1), Unwrap(clazz2)));
75  }
76 
77 
78  [[noreturn]] inline void Throw(JNIEnv& env, jthrowable& obj)
79  {
80  CheckErrorCode(env.Throw(Unwrap(obj)));
81  throw PendingJavaException();
82  }
83 
84  [[noreturn]] inline void ThrowNew(JNIEnv& env, jclass& clazz, const char* msg = nullptr)
85  {
86  CheckErrorCode(env.ThrowNew(Unwrap(clazz), msg));
87  throw PendingJavaException();
88  }
89 
90  inline bool ExceptionCheck(JNIEnv& env)
91  {
92  return env.ExceptionCheck();
93  }
94 
95  inline jthrowable* ExceptionOccurred(JNIEnv& env)
96  {
97  return Wrap<jthrowable*>(env.ExceptionOccurred());
98  }
99 
100  inline void ExceptionDescribe(JNIEnv& env)
101  {
102  env.ExceptionDescribe();
103  }
104 
105  inline void ExceptionClear(JNIEnv& env)
106  {
107  env.ExceptionClear();
108  }
109 
110  [[noreturn]] inline void FatalError(JNIEnv& env, const char* msg)
111  {
112  env.FatalError(msg);
113  std::abort();
114  }
115 
116 
117  inline UniqueLocalFrame PushLocalFrame(JNIEnv& env, jint capacity)
118  {
119  CheckJavaExceptionThenErrorCode(env, env.PushLocalFrame(capacity));
120  return UniqueLocalFrame(&env, LocalFrameDeleter());
121  }
122 
123  inline jobject* PopLocalFrame(JNIEnv& env, UniqueLocalFrame&& frame, jobject* result = nullptr)
124  {
125  frame.release();
126  return CheckJavaException(env,
127  Wrap<jobject*>(env.PopLocalFrame(Unwrap(result))));
128  }
129 
130 
131  template < template < RefDeletionMethod > class Deleter, class T >
133  {
134  jobject* obj = Wrap<jobject*>(env.NewGlobalRef(Unwrap(t)));
135  CheckJavaException(env);
136  if (t && !obj)
137  throw std::bad_alloc();
138  return UniqueGlobalRef<T, Deleter>(reinterpret_cast<T*>(obj), Deleter<&JNIEnv::DeleteGlobalRef>(env));
139  }
140 
141  template < class T >
142  UniqueGlobalRef<T> NewGlobalRef(JNIEnv& env, T* t)
143  {
144  return NewGlobalRef<DefaultRefDeleter>(env, t);
145  }
146 
147  // Attempt to promote a weak reference to a strong one. Returns an empty result
148  // if the weak reference has expired.
149  template < template < RefDeletionMethod > class Deleter, class T, template < RefDeletionMethod > class WeakDeleter >
151  {
152  jobject* obj = Wrap<jobject*>(env.NewGlobalRef(Unwrap(t)));
153  CheckJavaException(env);
154  return UniqueGlobalRef<T, Deleter>(reinterpret_cast<T*>(obj), Deleter<&JNIEnv::DeleteGlobalRef>(env));
155  }
156 
157  template < class T, template < RefDeletionMethod > class WeakDeleter >
159  {
160  return NewGlobalRef<DefaultRefDeleter>(env, t);
161  }
162 
163  template < class T, template < RefDeletionMethod > class Deleter >
165  {
166  env.DeleteGlobalRef(Unwrap(ref.release()));
167  CheckJavaException(env);
168  }
169 
170 
171  template < class T >
172  UniqueLocalRef<T> NewLocalRef(JNIEnv& env, T* t)
173  {
174  jobject* obj = Wrap<jobject*>(env.NewLocalRef(Unwrap(t)));
175  CheckJavaException(env);
176  if (t && !obj)
177  throw std::bad_alloc();
178  return UniqueLocalRef<T>(reinterpret_cast<T*>(obj), DefaultRefDeleter<&JNIEnv::DeleteLocalRef>(env));
179  }
180 
181  // Attempt to promote a weak reference to a strong one. Returns an empty result
182  // if the weak reference has expired.
183  template < class T, template < RefDeletionMethod > class WeakDeleter >
185  {
186  jobject* obj = Wrap<jobject*>(env.NewLocalRef(Unwrap(t)));
187  CheckJavaException(env);
188  return UniqueLocalRef<T>(reinterpret_cast<T*>(obj), DefaultRefDeleter<&JNIEnv::DeleteLocalRef>(env));
189  }
190 
191  template < class T >
192  void DeleteLocalRef(JNIEnv& env, UniqueLocalRef<T>&& ref)
193  {
194  env.DeleteLocalRef(Unwrap(ref.release()));
195  CheckJavaException(env);
196  }
197 
198  inline void EnsureLocalCapacity(JNIEnv& env, jint capacity)
199  {
200  CheckJavaExceptionThenErrorCode(env, env.EnsureLocalCapacity(capacity));
201  }
202 
203 
204  template < template < RefDeletionMethod > class Deleter, class T >
206  {
207  jobject* obj = Wrap<jobject*>(env.NewWeakGlobalRef(Unwrap(t)));
208  CheckJavaException(env);
209  if (t && !obj)
210  throw std::bad_alloc();
211  return UniqueWeakGlobalRef<T, Deleter>(reinterpret_cast<T*>(obj), Deleter<&JNIEnv::DeleteWeakGlobalRef>(env));
212  }
213 
214  template < class T >
216  {
217  return NewWeakGlobalRef<DefaultRefDeleter>(env, t);
218  }
219 
220  template < class T, template < RefDeletionMethod > class Deleter >
222  {
223  env.DeleteWeakGlobalRef(Unwrap(ref.release()));
224  CheckJavaException(env);
225  }
226 
227 
228  inline bool IsSameObject(JNIEnv& env, jobject* ref1, jobject* ref2)
229  {
230  return CheckJavaException(env,
231  env.IsSameObject(Unwrap(ref1), Unwrap(ref2)));
232  }
233 
234  inline jobject& AllocObject(JNIEnv& env, jclass& clazz)
235  {
236  return *CheckJavaException(env,
237  Wrap<jobject*>(env.AllocObject(Unwrap(clazz))));
238  }
239 
240  template < class... Args >
241  jobject& NewObject(JNIEnv& env, jclass& clazz, jmethodID& method, Args&&... args)
242  {
243  return *CheckJavaException(env,
244  Wrap<jobject*>(env.NewObject(Unwrap(clazz), Unwrap(method), Unwrap(std::forward<Args>(args))...)));
245  }
246 
247  inline jclass& GetObjectClass(JNIEnv& env, jobject& obj)
248  {
249  return *CheckJavaException(env,
250  Wrap<jclass*>(env.GetObjectClass(Unwrap(obj))));
251  }
252 
253  inline bool IsInstanceOf(JNIEnv& env, jobject* obj, jclass& clazz)
254  {
255  return CheckJavaException(env,
256  env.IsInstanceOf(Unwrap(obj), Unwrap(clazz))) == JNI_TRUE;
257  }
258 
259 
260  inline jmethodID& GetMethodID(JNIEnv& env, jclass& clazz, const char* name, const char* sig)
261  {
262  return *CheckJavaException(env,
263  Wrap<jmethodID*>(env.GetMethodID(Unwrap(clazz), name, sig)));
264  }
265 
266  template < class R, class... Args >
267  std::enable_if_t<!std::is_void<R>::value, R>
268  CallMethod(JNIEnv& env, jobject* obj, jmethodID& method, Args&&... args)
269  {
270  return CheckJavaException(env,
271  Wrap<R>((env.*(TypedMethods<R>::CallMethod))(Unwrap(obj), Unwrap(method), Unwrap(std::forward<Args>(args))...)));
272  }
273 
274  template < class R, class... Args >
275  std::enable_if_t<std::is_void<R>::value, R>
276  CallMethod(JNIEnv& env, jobject* obj, jmethodID& method, Args&&... args)
277  {
278  env.CallVoidMethod(Unwrap(obj), Unwrap(method), Unwrap(std::forward<Args>(args))...);
279  CheckJavaException(env);
280  }
281 
282  template < class R, class... Args >
283  std::enable_if_t<!std::is_void<R>::value, R>
284  CallNonvirtualMethod(JNIEnv& env, jobject* obj, jclass& clazz, jmethodID& method, Args&&... args)
285  {
286  return CheckJavaException(env,
287  Wrap<R>((env.*(TypedMethods<R>::CallNonvirtualMethod))(Unwrap(obj), Unwrap(clazz), Unwrap(method), Unwrap(std::forward<Args>(args))...)));
288  }
289 
290  template < class R, class... Args >
291  std::enable_if_t<std::is_void<R>::value, R>
292  CallNonvirtualMethod(JNIEnv& env, jobject* obj, jclass& clazz, jmethodID& method, Args&&... args)
293  {
294  env.CallNonvirtualVoidMethod(Unwrap(obj), Unwrap(clazz), Unwrap(method), Unwrap(std::forward<Args>(args))...);
295  CheckJavaException(env);
296  }
297 
298 
299  inline jfieldID& GetFieldID(JNIEnv& env, jclass& clazz, const char* name, const char* sig)
300  {
301  return *CheckJavaException(env,
302  Wrap<jfieldID*>(env.GetFieldID(Unwrap(clazz), name, sig)));
303  }
304 
305  template < class T >
306  T GetField(JNIEnv& env, jobject* obj, jfieldID& field)
307  {
308  return CheckJavaException(env,
309  Wrap<T>((env.*(TypedMethods<T>::GetField))(Unwrap(obj), Unwrap(field))));
310  }
311 
312  template < class T >
313  void SetField(JNIEnv& env, jobject* obj, jfieldID& field, T value)
314  {
315  (env.*(TypedMethods<T>::SetField))(Unwrap(obj), Unwrap(field), Unwrap(value));
316  CheckJavaException(env);
317  }
318 
319 
320  inline jmethodID& GetStaticMethodID(JNIEnv& env, jclass& clazz, const char* name, const char* sig)
321  {
322  return *CheckJavaException(env,
323  Wrap<jmethodID*>(env.GetStaticMethodID(Unwrap(clazz), name, sig)));
324  }
325 
326  template < class R, class... Args >
327  std::enable_if_t<!std::is_void<R>::value, R>
328  CallStaticMethod(JNIEnv& env, jclass& clazz, jmethodID& method, Args&&... args)
329  {
330  return CheckJavaException(env,
331  Wrap<R>((env.*(TypedMethods<R>::CallStaticMethod))(Unwrap(clazz), Unwrap(method), Unwrap(std::forward<Args>(args))...)));
332  }
333 
334  template < class R, class... Args >
335  std::enable_if_t<std::is_void<R>::value, R>
336  CallStaticMethod(JNIEnv& env, jclass& clazz, jmethodID& method, Args&&... args)
337  {
338  env.CallStaticVoidMethod(Unwrap(clazz), Unwrap(method), Unwrap(std::forward<Args>(args))...);
339  CheckJavaException(env);
340  }
341 
342 
343  inline jfieldID& GetStaticFieldID(JNIEnv& env, jclass& clazz, const char* name, const char* sig)
344  {
345  return *CheckJavaException(env,
346  Wrap<jfieldID*>(env.GetStaticFieldID(Unwrap(clazz), name, sig)));
347  }
348 
349  template < class T >
350  T GetStaticField(JNIEnv& env, jclass& clazz, jfieldID& field)
351  {
352  return CheckJavaException(env,
353  Wrap<T>((env.*(TypedMethods<T>::GetStaticField))(Unwrap(clazz), Unwrap(field))));
354  }
355 
356  template < class T >
357  void SetStaticField(JNIEnv& env, jclass& clazz, jfieldID& field, T value)
358  {
359  (env.*(TypedMethods<T>::SetStaticField))(Unwrap(clazz), Unwrap(field), Unwrap(value));
360  CheckJavaException(env);
361  }
362 
363 
364  inline jstring& NewString(JNIEnv& env, const char16_t* chars, jsize len)
365  {
366  return *CheckJavaException(env,
367  Wrap<jstring*>(env.NewString(Unwrap(chars), Unwrap(len))));
368  }
369 
370  template < class Array >
371  auto NewString(JNIEnv& env, const Array& chars)
372  -> std::enable_if_t< IsArraylike<Array>::value, jstring& >
373  {
374  return NewString(env, ArraylikeData(chars), ArraylikeSize(chars));
375  }
376 
377  inline jsize GetStringLength(JNIEnv& env, jstring& string)
378  {
379  return CheckJavaException(env,
380  Wrap<jsize>(env.GetStringLength(Unwrap(string))));
381  }
382 
383  inline std::tuple<UniqueStringChars, bool> GetStringChars(JNIEnv& env, jstring& string)
384  {
385  ::jboolean isCopy = JNI_FALSE;
386  const char16_t* result = CheckJavaException(env,
387  Wrap<const char16_t*>(env.GetStringChars(Unwrap(string), &isCopy)));
388  return std::make_tuple(UniqueStringChars(result, StringCharsDeleter(env, string)), isCopy);
389  }
390 
391  inline void ReleaseStringChars(JNIEnv& env, jstring& string, UniqueStringChars&& chars)
392  {
393  env.ReleaseStringChars(Unwrap(string), Unwrap(chars.release()));
394  CheckJavaException(env);
395  }
396 
397  inline jstring& NewStringUTF(JNIEnv& env, const char* bytes)
398  {
399  return *CheckJavaException(env,
400  Wrap<jstring*>(env.NewStringUTF(bytes)));
401  }
402 
403  inline jsize GetStringUTFLength(JNIEnv& env, jstring& string)
404  {
405  return CheckJavaException(env,
406  Wrap<jsize>(env.GetStringUTFLength(Unwrap(string))));
407  }
408 
409  inline std::tuple<UniqueStringUTFChars, bool> GetStringUTFChars(JNIEnv& env, jstring& string)
410  {
411  ::jboolean isCopy = JNI_FALSE;
412  const char* result = CheckJavaException(env,
413  env.GetStringUTFChars(Unwrap(string), &isCopy));
414  return std::make_tuple(UniqueStringUTFChars(result, StringUTFCharsDeleter(env, string)), isCopy);
415  }
416 
417  inline void ReleaseStringUTFChars(JNIEnv& env, jstring& string, UniqueStringUTFChars&& chars)
418  {
419  env.ReleaseStringUTFChars(Unwrap(string), chars.release());
420  CheckJavaException(env);
421  }
422 
423  inline void GetStringRegion(JNIEnv& env, jstring& string, jsize start, jsize len, char16_t* buf)
424  {
425  env.GetStringRegion(Unwrap(string), Unwrap(start), Unwrap(len), Unwrap(buf));
426  CheckJavaException(env);
427  }
428 
429  template < class Array >
430  auto GetStringRegion(JNIEnv& env, jstring& string, jsize start, Array& buf)
431  -> std::enable_if_t< IsArraylike<Array>::value >
432  {
433  GetStringRegion(env, string, start, ArraylikeSize(buf), ArraylikeData(buf));
434  }
435 
436  inline void GetStringUTFRegion(JNIEnv& env, jstring& string, jsize start, jsize len, char* buf)
437  {
438  env.GetStringUTFRegion(Unwrap(string), Unwrap(start), Unwrap(len), buf);
439  CheckJavaException(env);
440  }
441 
442  template < class Array >
443  auto GetStringUTFRegion(JNIEnv& env, jstring& string, jsize start, Array& buf)
444  -> std::enable_if_t< IsArraylike<Array>::value >
445  {
446  GetStringUTFRegion(env, string, start, ArraylikeSize(buf), ArraylikeData(buf));
447  }
448 
449  inline std::tuple<UniqueStringCritical, bool> GetStringCritical(JNIEnv& env, jstring& string)
450  {
451  ::jboolean isCopy = JNI_FALSE;
452  const char16_t* result = CheckJavaException(env,
453  Wrap<const char16_t*>(env.GetStringCritical(Unwrap(string), &isCopy)));
454  return std::make_tuple(UniqueStringCritical(result, StringCriticalDeleter(env, string)), isCopy);
455  }
456 
457  inline void ReleaseStringCritical(JNIEnv& env, jstring& string, UniqueStringCritical&& chars)
458  {
459  env.ReleaseStringCritical(Unwrap(string), Unwrap(chars.release()));
460  CheckJavaException(env);
461  }
462 
463 
464  template < class E >
465  jsize GetArrayLength(JNIEnv& env, jarray<E>& array)
466  {
467  return CheckJavaException(env,
468  Wrap<jsize>(env.GetArrayLength(Unwrap(array))));
469  }
470 
471  template < class E >
472  jarray<E>& NewArray(JNIEnv& env, jsize length)
473  {
474  return *CheckJavaException(env,
475  Wrap<jarray<E>*>((env.*(TypedMethods<E>::NewArray))(Unwrap(length))));
476  }
477 
478  template < class E >
479  std::tuple<UniqueArrayElements<E>, bool> GetArrayElements(JNIEnv& env, jarray<E>& array)
480  {
481  ::jboolean isCopy = JNI_FALSE;
482  E* result = CheckJavaException(env,
483  (env.*(TypedMethods<E>::GetArrayElements))(Unwrap(array), &isCopy));
484  return std::make_tuple(UniqueArrayElements<E>(result, ArrayElementsDeleter<E>(env, array)), isCopy);
485  }
486 
487  template < class E >
488  void ReleaseArrayElements(JNIEnv& env, jarray<E>& array, E* elems)
489  {
490  (env.*(TypedMethods<E>::ReleaseArrayElements))(Unwrap(array), elems, JNI_COMMIT);
491  CheckJavaException(env);
492  }
493 
494  template < class E >
495  void ReleaseArrayElements(JNIEnv& env, jarray<E>& array, UniqueArrayElements<E>&& elems)
496  {
497  (env.*(TypedMethods<E>::ReleaseArrayElements))(Unwrap(array), elems.release(), 0);
498  CheckJavaException(env);
499  }
500 
501  template < class E >
502  std::tuple<UniquePrimitiveArrayCritical<E>, bool> GetPrimitiveArrayCritical(JNIEnv& env, jarray<E>& array)
503  {
504  ::jboolean isCopy = JNI_FALSE;
505  void* result = CheckJavaException(env,
506  env.GetPrimitiveArrayCritical(Unwrap(array), &isCopy));
507  return std::make_tuple(UniquePrimitiveArrayCritical<E>(result, PrimitiveArrayCriticalDeleter<E>(env, array)), isCopy);
508  }
509 
510  template < class E >
511  void ReleasePrimitiveArrayCritical(JNIEnv& env, jarray<E>& array, void* carray)
512  {
513  env.ReleasePrimitiveArrayCritical(Unwrap(array), carray, 0);
514  CheckJavaException(env);
515  }
516 
517  template < class E >
519  {
520  env.ReleasePrimitiveArrayCritical(Unwrap(array), carray.release(), JNI_COMMIT);
521  CheckJavaException(env);
522  }
523 
524  template < class T >
525  void GetArrayRegion(JNIEnv& env, jarray<T>& array, jsize start, jsize len, T* buf)
526  {
527  (env.*(TypedMethods<T>::GetArrayRegion))(Unwrap(array), Unwrap(start), Unwrap(len), buf);
528  CheckJavaException(env);
529  }
530 
531  template < class T, class Array >
532  auto GetArrayRegion(JNIEnv& env, jarray<T>& array, jsize start, Array& buf)
533  -> std::enable_if_t< IsArraylike<Array>::value >
534  {
535  GetArrayRegion(env, array, start, ArraylikeSize(buf), ArraylikeData(buf));
536  }
537 
538  template < class T >
539  void SetArrayRegion(JNIEnv& env, jarray<T>& array, jsize start, jsize len, const T* buf)
540  {
541  (env.*(TypedMethods<T>::SetArrayRegion))(Unwrap(array), Unwrap(start), Unwrap(len), buf);
542  CheckJavaException(env);
543  }
544 
545  template < class T, class Array >
546  auto SetArrayRegion(JNIEnv& env, jarray<T>& array, jsize start, const Array& buf)
547  -> std::enable_if_t< IsArraylike<Array>::value >
548  {
549  SetArrayRegion(env, array, start, ArraylikeSize(buf), ArraylikeData(buf));
550  }
551 
552 
553  inline jarray<jobject>& NewObjectArray(JNIEnv& env, jsize length, jclass& elementClass, jobject* initialElement = nullptr)
554  {
555  return *CheckJavaException(env,
556  Wrap<jarray<jobject>*>(env.NewObjectArray(Unwrap(length), Unwrap(elementClass), Unwrap(initialElement))));
557  }
558 
559  inline jobject* GetObjectArrayElement(JNIEnv& env, jarray<jobject>& array, jsize index)
560  {
561  return CheckJavaException(env,
562  Wrap<jobject*>(env.GetObjectArrayElement(Unwrap(array), Unwrap(index))));
563  }
564 
565  inline void SetObjectArrayElement(JNIEnv& env, jarray<jobject>& array, jsize index, jobject* value)
566  {
567  env.SetObjectArrayElement(Unwrap(array), Unwrap(index), Unwrap(value));
568  CheckJavaException(env);
569  }
570 
571 
572  template < class... Methods >
573  inline void RegisterNatives(JNIEnv& env, jclass& clazz, const Methods&... methods)
574  {
575  ::JNINativeMethod unwrapped[sizeof...(methods)] = { Unwrap(methods)... };
577  env.RegisterNatives(Unwrap(clazz), unwrapped, sizeof...(methods)));
578  }
579 
580  inline void UnregisterNatives(JNIEnv& env, jclass& clazz)
581  {
582  CheckJavaExceptionThenErrorCode(env, env.UnregisterNatives(Unwrap(clazz)));
583  }
584 
585 
586  inline UniqueMonitor MonitorEnter(JNIEnv& env, jobject* obj)
587  {
588  CheckJavaExceptionThenErrorCode(env, env.MonitorEnter(Unwrap(obj)));
589  return UniqueMonitor(obj, MonitorDeleter(env));
590  }
591 
592  inline void MonitorExit(JNIEnv& env, UniqueMonitor&& monitor)
593  {
594  CheckJavaExceptionThenErrorCode(env, env.MonitorExit(Unwrap(monitor.release())));
595  }
596 
597 
598  inline JavaVM& GetJavaVM(JNIEnv& env)
599  {
600  JavaVM* result = nullptr;
601  CheckJavaExceptionThenErrorCode(env, env.GetJavaVM(&result));
602  return *result;
603  }
604 
605 
606  inline jobject& NewDirectByteBuffer(JNIEnv& env, void* address, jlong capacity)
607  {
608  return *CheckJavaException(env,
609  Wrap<jobject*>(env.NewDirectByteBuffer(address, Unwrap(capacity))));
610  }
611 
612  inline void* GetDirectBufferAddress(JNIEnv& env, jobject& buf)
613  {
614  return CheckJavaException(env,
615  env.GetDirectBufferAddress(Unwrap(buf)));
616  }
617 
618  inline jlong GetDirectBufferCapacity(JNIEnv& env, jobject& buf)
619  {
620  return CheckJavaException(env,
621  env.GetDirectBufferCapacity(Unwrap(buf)));
622  }
623 
624 
625  inline jobjectRefType GetObjectRefType(JNIEnv& env, jobject* obj)
626  {
627  return env.GetObjectRefType(Unwrap(obj));
628  }
629 
630 
631  inline UniqueEnv AttachCurrentThread(JavaVM& vm)
632  {
633  // Some implementations type the parameter as JNIEnv**, others as void**.
634  // See https://bugs.openjdk.java.net/browse/JDK-6569899
635  struct JNIEnvCast
636  {
637  void** operator()(JNIEnv** env, jint (JavaVM::*)(void**, void*))
638  {
639  return reinterpret_cast<void**>(env);
640  }
641 
642  JNIEnv** operator()(JNIEnv** env, jint (JavaVM::*)(JNIEnv**, void*))
643  {
644  return env;
645  }
646  };
647 
648  JNIEnv* result;
649  CheckErrorCode(vm.AttachCurrentThread(JNIEnvCast()(&result, &JavaVM::AttachCurrentThread), nullptr));
650  return UniqueEnv(result, JNIEnvDeleter(vm));
651  }
652 
653  inline void DetachCurrentThread(JavaVM& vm, UniqueEnv&& env)
654  {
655  env.release();
656  CheckErrorCode(vm.DetachCurrentThread());
657  }
658 
659  inline JNIEnv& GetEnv(JavaVM& vm, version version = jni_version_1_1)
660  {
661  JNIEnv* env = nullptr;
662  CheckErrorCode(vm.GetEnv(reinterpret_cast<void**>(&env), Unwrap(version)));
663  return *env;
664  }
665  }
version
Definition: types.hpp:82
jobject * PopLocalFrame(JNIEnv &env, UniqueLocalFrame &&frame, jobject *result=nullptr)
Definition: functions.hpp:123
UniqueLocalRef< T > NewLocalRef(JNIEnv &env, T *t)
Definition: functions.hpp:172
std::unique_ptr< T, DefaultRefDeleter<&JNIEnv::DeleteLocalRef > > UniqueLocalRef
Definition: ownership.hpp:55
std::unique_ptr< JNIEnv, LocalFrameDeleter > UniqueLocalFrame
Definition: ownership.hpp:20
jsize GetStringUTFLength(JNIEnv &env, jstring &string)
Definition: functions.hpp:403
void SetField(JNIEnv &env, jobject *obj, jfieldID &field, T value)
Definition: functions.hpp:313
Definition: errors.hpp:58
std::unique_ptr< jobject, MonitorDeleter > UniqueMonitor
Definition: ownership.hpp:201
void CheckJavaExceptionThenErrorCode(JNIEnv &env, jint err)
Definition: errors.hpp:72
UniqueGlobalRef< T, Deleter > NewGlobalRef(JNIEnv &env, T *t)
Definition: functions.hpp:132
void DetachCurrentThread(JavaVM &vm, UniqueEnv &&env)
Definition: functions.hpp:653
jclass & GetObjectClass(JNIEnv &env, jobject &obj)
Definition: functions.hpp:247
UniqueEnv AttachCurrentThread(JavaVM &vm)
Definition: functions.hpp:631
Definition: ownership.hpp:157
std::tuple< UniqueStringCritical, bool > GetStringCritical(JNIEnv &env, jstring &string)
Definition: functions.hpp:449
Definition: ownership.hpp:9
void MonitorExit(JNIEnv &env, UniqueMonitor &&monitor)
Definition: functions.hpp:592
void ExceptionClear(JNIEnv &env)
Definition: functions.hpp:105
std::unique_ptr< const char16_t, StringCharsDeleter > UniqueStringChars
Definition: ownership.hpp:79
void SetArrayRegion(JNIEnv &env, jarray< T > &array, jsize start, jsize len, const T *buf)
Definition: functions.hpp:539
jstring & NewStringUTF(JNIEnv &env, const char *bytes)
Definition: functions.hpp:397
jint GetVersion(JNIEnv &env)
Definition: functions.hpp:15
Definition: types.hpp:84
void ThrowNew(JNIEnv &env, jclass &clazz, const char *msg=nullptr)
Definition: functions.hpp:84
std::enable_if_t<!std::is_void< R >::value, R > CallStaticMethod(JNIEnv &env, jclass &clazz, jmethodID &method, Args &&... args)
Definition: functions.hpp:328
std::unique_ptr< const char16_t, StringCriticalDeleter > UniqueStringCritical
Definition: ownership.hpp:127
jlong GetDirectBufferCapacity(JNIEnv &env, jobject &buf)
Definition: functions.hpp:618
std::enable_if_t<!std::is_void< R >::value, R > CallMethod(JNIEnv &env, jobject *obj, jmethodID &method, Args &&... args)
Definition: functions.hpp:268
bool IsAssignableFrom(JNIEnv &env, jclass &clazz1, jclass &clazz2)
Definition: functions.hpp:71
UniqueLocalFrame PushLocalFrame(JNIEnv &env, jint capacity)
Definition: functions.hpp:117
void SetObjectArrayElement(JNIEnv &env, jarray< jobject > &array, jsize index, jobject *value)
Definition: functions.hpp:565
void GetArrayRegion(JNIEnv &env, jarray< T > &array, jsize start, jsize len, T *buf)
Definition: functions.hpp:525
void ReleaseStringChars(JNIEnv &env, jstring &string, UniqueStringChars &&chars)
Definition: functions.hpp:391
Definition: array.hpp:11
void CheckErrorCode(jint err)
Definition: errors.hpp:43
jarray< jobject > & NewObjectArray(JNIEnv &env, jsize length, jclass &elementClass, jobject *initialElement=nullptr)
Definition: functions.hpp:553
E * ArraylikeData(E(&a)[n])
Definition: arraylike.hpp:28
bool IsSameObject(JNIEnv &env, jobject *ref1, jobject *ref2)
Definition: functions.hpp:228
void SetStaticField(JNIEnv &env, jclass &clazz, jfieldID &field, T value)
Definition: functions.hpp:357
std::tuple< UniqueStringUTFChars, bool > GetStringUTFChars(JNIEnv &env, jstring &string)
Definition: functions.hpp:409
std::enable_if_t<!std::is_void< R >::value, R > CallNonvirtualMethod(JNIEnv &env, jobject *obj, jclass &clazz, jmethodID &method, Args &&... args)
Definition: functions.hpp:284
std::unique_ptr< const char, StringUTFCharsDeleter > UniqueStringUTFChars
Definition: ownership.hpp:103
Definition: ownership.hpp:26
bool ExceptionCheck(JNIEnv &env)
Definition: functions.hpp:90
void UnregisterNatives(JNIEnv &env, jclass &clazz)
Definition: functions.hpp:580
void * GetDirectBufferAddress(JNIEnv &env, jobject &buf)
Definition: functions.hpp:612
auto Wrap(U &&u)
Definition: wrapping.hpp:16
jobject * GetObjectArrayElement(JNIEnv &env, jarray< jobject > &array, jsize index)
Definition: functions.hpp:559
void ReleaseStringCritical(JNIEnv &env, jstring &string, UniqueStringCritical &&chars)
Definition: functions.hpp:457
jobject & NewObject(JNIEnv &env, jclass &clazz, jmethodID &method, Args &&... args)
Definition: functions.hpp:241
void EnsureLocalCapacity(JNIEnv &env, jint capacity)
Definition: functions.hpp:198
jarray< E > & NewArray(JNIEnv &env, jsize length)
Definition: functions.hpp:472
std::tuple< UniqueArrayElements< E >, bool > GetArrayElements(JNIEnv &env, jarray< E > &array)
Definition: functions.hpp:479
jmethodID * FromReflectedMethod(JNIEnv &env, jobject *obj)
Definition: functions.hpp:40
Definition: advanced_ownership.hpp:5
jsize GetStringLength(JNIEnv &env, jstring &string)
Definition: functions.hpp:377
std::unique_ptr< T, Deleter<&JNIEnv::DeleteGlobalRef > > UniqueGlobalRef
Definition: ownership.hpp:47
std::size_t ArraylikeSize(E(&)[n])
Definition: arraylike.hpp:37
jstring & NewString(JNIEnv &env, const char16_t *chars, jsize len)
Definition: functions.hpp:364
Definition: ownership.hpp:204
bool IsInstanceOf(JNIEnv &env, jobject *obj, jclass &clazz)
Definition: functions.hpp:253
void DeleteWeakGlobalRef(JNIEnv &env, UniqueWeakGlobalRef< T, Deleter > &&ref)
Definition: functions.hpp:221
std::size_t jsize
Definition: types.hpp:28
std::unique_ptr< T, Deleter<&JNIEnv::DeleteWeakGlobalRef > > UniqueWeakGlobalRef
Definition: ownership.hpp:50
Definition: ownership.hpp:82
jobject & NewDirectByteBuffer(JNIEnv &env, void *address, jlong capacity)
Definition: functions.hpp:606
Definition: ownership.hpp:58
auto Unwrap(W &&w)
Definition: wrapping.hpp:22
jmethodID & GetMethodID(JNIEnv &env, jclass &clazz, const char *name, const char *sig)
Definition: functions.hpp:260
void ReleaseArrayElements(JNIEnv &env, jarray< E > &array, E *elems)
Definition: functions.hpp:488
UniqueWeakGlobalRef< T, Deleter > NewWeakGlobalRef(JNIEnv &env, T *t)
Definition: functions.hpp:205
jthrowable * ExceptionOccurred(JNIEnv &env)
Definition: functions.hpp:95
std::tuple< UniquePrimitiveArrayCritical< E >, bool > GetPrimitiveArrayCritical(JNIEnv &env, jarray< E > &array)
Definition: functions.hpp:502
jmethodID & GetStaticMethodID(JNIEnv &env, jclass &clazz, const char *name, const char *sig)
Definition: functions.hpp:320
Definition: typed_methods.hpp:7
std::unique_ptr< JNIEnv, JNIEnvDeleter > UniqueEnv
Definition: ownership.hpp:223
std::tuple< UniqueStringChars, bool > GetStringChars(JNIEnv &env, jstring &string)
Definition: functions.hpp:383
void DeleteGlobalRef(JNIEnv &env, UniqueGlobalRef< T, Deleter > &&ref)
Definition: functions.hpp:164
std::unique_ptr< void, PrimitiveArrayCriticalDeleter< E > > UniquePrimitiveArrayCritical
Definition: ownership.hpp:179
std::pointer_traits< ::jmethodID >::element_type jmethodID
Definition: types.hpp:56
Definition: ownership.hpp:106
jsize GetArrayLength(JNIEnv &env, jarray< E > &array)
Definition: functions.hpp:465
void RegisterNatives(JNIEnv &env, jclass &clazz, const Methods &... methods)
Definition: functions.hpp:573
jfieldID * FromReflectedField(JNIEnv &env, jobject *obj)
Definition: functions.hpp:46
void Throw(JNIEnv &env, jthrowable &obj)
Definition: functions.hpp:78
void ReleaseStringUTFChars(JNIEnv &env, jstring &string, UniqueStringUTFChars &&chars)
Definition: functions.hpp:417
Definition: ownership.hpp:182
jclass & FindClass(JNIEnv &env, const char *name)
Definition: functions.hpp:34
Definition: types.hpp:64
R CheckJavaException(JNIEnv &env, R &&r)
Definition: errors.hpp:61
std::unique_ptr< E, ArrayElementsDeleter< E > > UniqueArrayElements
Definition: ownership.hpp:153
jobject & ToReflectedField(JNIEnv &env, jclass &clazz, jfieldID &field, bool isStatic)
Definition: functions.hpp:58
jclass & DefineClass(JNIEnv &env, const char *name, jobject &loader, const jbyte *buf, jsize size)
Definition: functions.hpp:21
T GetStaticField(JNIEnv &env, jclass &clazz, jfieldID &field)
Definition: functions.hpp:350
JNIEnv & GetEnv(JavaVM &vm, version version=jni_version_1_1)
Definition: functions.hpp:659
JavaVM & GetJavaVM(JNIEnv &env)
Definition: functions.hpp:598
T GetField(JNIEnv &env, jobject *obj, jfieldID &field)
Definition: functions.hpp:306
Definition: types.hpp:38
jobjectRefType GetObjectRefType(JNIEnv &env, jobject *obj)
Definition: functions.hpp:625
Definition: types.hpp:39
std::pointer_traits< ::jfieldID >::element_type jfieldID
Definition: types.hpp:55
void ExceptionDescribe(JNIEnv &env)
Definition: functions.hpp:100
jfieldID & GetFieldID(JNIEnv &env, jclass &clazz, const char *name, const char *sig)
Definition: functions.hpp:299
void GetStringRegion(JNIEnv &env, jstring &string, jsize start, jsize len, char16_t *buf)
Definition: functions.hpp:423
Definition: types.hpp:40
jclass * GetSuperclass(JNIEnv &env, jclass &clazz)
Definition: functions.hpp:65
void DeleteLocalRef(JNIEnv &env, UniqueLocalRef< T > &&ref)
Definition: functions.hpp:192
void GetStringUTFRegion(JNIEnv &env, jstring &string, jsize start, jsize len, char *buf)
Definition: functions.hpp:436
jobject & AllocObject(JNIEnv &env, jclass &clazz)
Definition: functions.hpp:234
jfieldID & GetStaticFieldID(JNIEnv &env, jclass &clazz, const char *name, const char *sig)
Definition: functions.hpp:343
void FatalError(JNIEnv &env, const char *msg)
Definition: functions.hpp:110
Definition: types.hpp:30
jobject & ToReflectedMethod(JNIEnv &env, jclass &clazz, jmethodID &method, bool isStatic)
Definition: functions.hpp:52
void ReleasePrimitiveArrayCritical(JNIEnv &env, jarray< E > &array, void *carray)
Definition: functions.hpp:511
Definition: ownership.hpp:131
UniqueMonitor MonitorEnter(JNIEnv &env, jobject *obj)
Definition: functions.hpp:586