lime
Lime is a C++ library implementing Open Whisper System Signal protocol
wrapping.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstddef>
4 #include <cassert>
5 #include <limits>
6 #include <memory>
7 #include <utility>
8 
9 #include <jni.h>
10 
11 namespace jni
12  {
13  template < class W > struct Wrapper;
14 
15  template < class W, class U >
16  auto Wrap(U&& u)
17  {
18  return Wrapper<W>().Wrap(std::forward<U>(u));
19  }
20 
21  template < class W >
22  auto Unwrap(W&& w)
23  {
24  return Wrapper<typename std::decay<W>::type>().Unwrap(std::forward<W>(w));
25  }
26 
27  template < class T >
28  using UnwrappedType = decltype(Unwrap<T>(std::declval<T>()));
29 
30 
31  template < class T >
33  {
34  T Wrap(T t) const { return t; }
35  T Unwrap(T t) const { return t; }
36  };
37 
38  template <> struct Wrapper< jboolean > : PrimitiveTypeWrapper< jboolean > {};
39  template <> struct Wrapper< jbyte > : PrimitiveTypeWrapper< jbyte > {};
40  template <> struct Wrapper< jchar > : PrimitiveTypeWrapper< jchar > {};
41  template <> struct Wrapper< jshort > : PrimitiveTypeWrapper< jshort > {};
42  template <> struct Wrapper< jint > : PrimitiveTypeWrapper< jint > {};
43  template <> struct Wrapper< jlong > : PrimitiveTypeWrapper< jlong > {};
44  template <> struct Wrapper< jfloat > : PrimitiveTypeWrapper< jfloat > {};
45  template <> struct Wrapper< jdouble > : PrimitiveTypeWrapper< jdouble > {};
46 
47 
48  template <>
49  struct Wrapper<const char16_t*>
50  {
51  const char16_t* Wrap(const jchar* s) const { return reinterpret_cast<const char16_t*>(s); }
52  const jchar* Unwrap(const char16_t* s) const { return reinterpret_cast<const jchar*>(s); }
53  };
54 
55  template <>
56  struct Wrapper<char16_t*>
57  {
58  char16_t* Wrap(jchar* s) const { return reinterpret_cast<char16_t*>(s); }
59  jchar* Unwrap(char16_t* s) const { return reinterpret_cast<jchar*>(s); }
60  };
61 
62 
63  template <>
64  struct Wrapper<jsize>
65  {
66  jsize Wrap(::jsize s) const
67  {
68  if (s < 0)
69  throw std::range_error("::jsize < 0");
70  return static_cast<jsize>(s);
71  }
72 
73  ::jsize Unwrap(jsize s) const
74  {
75  if (s > std::numeric_limits<::jsize>::max())
76  throw std::range_error("jsize > max");
77  return static_cast<::jsize>(s);
78  }
79  };
80 
81 
82  template < class W, class U >
84  {
85  W* Wrap(U u) const { return reinterpret_cast<W*>(u); }
86  U Unwrap(W* w) const { return reinterpret_cast<U>(w); }
87  };
88 
93 
95  template <> struct Wrapper< jarray< jboolean >* > : ReferenceTypeWrapper< jarray< jboolean >, ::jbooleanArray > {};
96  template <> struct Wrapper< jarray< jbyte >* > : ReferenceTypeWrapper< jarray< jbyte >, ::jbyteArray > {};
97  template <> struct Wrapper< jarray< jchar >* > : ReferenceTypeWrapper< jarray< jchar >, ::jcharArray > {};
98  template <> struct Wrapper< jarray< jshort >* > : ReferenceTypeWrapper< jarray< jshort >, ::jshortArray > {};
99  template <> struct Wrapper< jarray< jint >* > : ReferenceTypeWrapper< jarray< jint >, ::jintArray > {};
100  template <> struct Wrapper< jarray< jlong >* > : ReferenceTypeWrapper< jarray< jlong >, ::jlongArray > {};
101  template <> struct Wrapper< jarray< jfloat >* > : ReferenceTypeWrapper< jarray< jfloat >, ::jfloatArray > {};
102  template <> struct Wrapper< jarray< jdouble >* > : ReferenceTypeWrapper< jarray< jdouble >, ::jdoubleArray > {};
103 
106 
107 
108  // Allow references to be unwrapped to pointers to the underlying type, but not the
109  // reverse, because dereferences should be explicit, with null checks where necessary.
110 
111  template < class W, class U >
113  {
114  U Unwrap(W& w) const { return reinterpret_cast<U>(&w); }
115  };
116 
117  template <> struct Wrapper< jobject > : ReferenceTypeUnwrapper< jobject, ::jobject > {};
118  template <> struct Wrapper< jclass > : ReferenceTypeUnwrapper< jclass, ::jclass > {};
119  template <> struct Wrapper< jstring > : ReferenceTypeUnwrapper< jstring, ::jstring > {};
120  template <> struct Wrapper< jthrowable > : ReferenceTypeUnwrapper< jthrowable, ::jthrowable > {};
121 
122  template <> struct Wrapper< jarray< jobject > > : ReferenceTypeUnwrapper< jarray< jobject >, ::jobjectArray > {};
123  template <> struct Wrapper< jarray< jboolean > > : ReferenceTypeUnwrapper< jarray< jboolean >, ::jbooleanArray > {};
124  template <> struct Wrapper< jarray< jbyte > > : ReferenceTypeUnwrapper< jarray< jbyte >, ::jbyteArray > {};
125  template <> struct Wrapper< jarray< jchar > > : ReferenceTypeUnwrapper< jarray< jchar >, ::jcharArray > {};
126  template <> struct Wrapper< jarray< jshort > > : ReferenceTypeUnwrapper< jarray< jshort >, ::jshortArray > {};
127  template <> struct Wrapper< jarray< jint > > : ReferenceTypeUnwrapper< jarray< jint >, ::jintArray > {};
128  template <> struct Wrapper< jarray< jlong > > : ReferenceTypeUnwrapper< jarray< jlong >, ::jlongArray > {};
129  template <> struct Wrapper< jarray< jfloat > > : ReferenceTypeUnwrapper< jarray< jfloat >, ::jfloatArray > {};
130  template <> struct Wrapper< jarray< jdouble > > : ReferenceTypeUnwrapper< jarray< jdouble >, ::jdoubleArray > {};
131 
132  template <> struct Wrapper< jfieldID > : ReferenceTypeUnwrapper< jfieldID, ::jfieldID > {};
133  template <> struct Wrapper< jmethodID > : ReferenceTypeUnwrapper< jmethodID, ::jmethodID > {};
134 
135 
136  template < class T, class R, class... Args >
137  struct Wrapper< JNINativeMethod< R (JNIEnv*, T*, Args...) > >
138  {
139  ::JNINativeMethod Unwrap(JNINativeMethod<R (JNIEnv*, T*, Args...)> method) const
140  {
141  return { const_cast<char*>(method.name), const_cast<char*>(method.signature), reinterpret_cast<void*>(method.fnPtr) };
142  }
143  };
144 
145 
146  template <>
147  struct Wrapper<version>
148  {
149  version Wrap(::jint v) const { return static_cast<version>(v); }
150  ::jint Unwrap(version v) const { return static_cast<::jint>(v); }
151  };
152  }
::jsize Unwrap(jsize s) const
Definition: wrapping.hpp:73
version
Definition: types.hpp:82
::jint Unwrap(version v) const
Definition: wrapping.hpp:150
U Unwrap(W *w) const
Definition: wrapping.hpp:86
Definition: types.hpp:43
::JNINativeMethod Unwrap(JNINativeMethod< R(JNIEnv *, T *, Args...)> method) const
Definition: wrapping.hpp:139
auto Wrap(U &&u)
Definition: wrapping.hpp:16
T Unwrap(T t) const
Definition: wrapping.hpp:35
Definition: advanced_ownership.hpp:5
W * Wrap(U u) const
Definition: wrapping.hpp:85
decltype(Unwrap< T >(std::declval< T >())) UnwrappedType
Definition: wrapping.hpp:28
std::size_t jsize
Definition: types.hpp:28
auto Unwrap(W &&w)
Definition: wrapping.hpp:22
jchar * Unwrap(char16_t *s) const
Definition: wrapping.hpp:59
char16_t * Wrap(jchar *s) const
Definition: wrapping.hpp:58
Definition: wrapping.hpp:83
const char16_t * Wrap(const jchar *s) const
Definition: wrapping.hpp:51
std::pointer_traits< ::jmethodID >::element_type jmethodID
Definition: types.hpp:56
version Wrap(::jint v) const
Definition: wrapping.hpp:149
Definition: wrapping.hpp:13
Definition: wrapping.hpp:32
jsize Wrap(::jsize s) const
Definition: wrapping.hpp:66
Definition: types.hpp:64
const jchar * Unwrap(const char16_t *s) const
Definition: wrapping.hpp:52
Definition: types.hpp:38
std::pointer_traits< ::jfieldID >::element_type jfieldID
Definition: types.hpp:55
Definition: types.hpp:39
Definition: types.hpp:40
T Wrap(T t) const
Definition: wrapping.hpp:34
U Unwrap(W &w) const
Definition: wrapping.hpp:114
Definition: types.hpp:30
Definition: wrapping.hpp:112