MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
jtie_tconv_ptrbyval_impl.hpp
1 /*
2  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 /*
18  * jtie_tconv_ptrbyval_impl.hpp
19  */
20 
21 #ifndef jtie_tconv_ptrbyval_impl_hpp
22 #define jtie_tconv_ptrbyval_impl_hpp
23 
24 #include <assert.h> // not using namespaces yet
25 #include <jni.h>
26 
27 #include "jtie_tconv_ptrbyval.hpp"
28 #include "jtie_tconv_impl.hpp"
29 #include "jtie_tconv_array_impl.hpp"
30 #include "jtie_tconv_utils_impl.hpp"
31 #include "helpers.hpp"
32 
33 // ---------------------------------------------------------------------------
34 // ArrayPtrParam, ArrayPtrResult
35 // ---------------------------------------------------------------------------
36 
37 // Returns zero if an array has a min size; otherwise, an exception is pending.
38 template< jlong N >
39 inline cstatus
40 ensureMinArraySize(jarray ja, JNIEnv * env) {
41  assert(ja != NULL);
42 
43  // init return value to error
44  cstatus s = -1;
45 
46  // check the array's length
47  jsize n = env->GetArrayLength(ja);
48  if (env->ExceptionCheck() != JNI_OK) {
49  // exception pending
50  assert(false); // coding error: argument not valid
51  } else {
52  if (n < N) {
53  const char * c = "java/lang/IllegalArgumentException";
54  const char * m = ("JTie: the Java array's length is too small for"
55  " the mapped parameter (file: " __FILE__ ")");
56  registerException(env, c, m);
57  } else {
58  // ok
59  s = 0;
60  }
61  }
62  return s;
63 }
64 
65 // Implements the mapping of arrays to pointer parameters.
66 template< typename J, typename C >
67 struct ArrayPtrParam {
68  static C *
69  convert(cstatus & s, typename J::JA_t * j, JNIEnv * env) {
70  TRACE("C * ArrayPtrParam.convert(cstatus &, typename J::JA_t *, JNIEnv *)");
71  // init return value and status to error
72  s = -1;
73  C * c = NULL;
74 
75  if (j == NULL) {
76  // ok
77  s = 0;
78  } else {
79  if (ensureMinArraySize< J::length >(j, env) != 0) {
80  // exception pending
81  } else {
82  assert(env->GetArrayLength(j) >= J::length);
83 
84  // get a C array, to be released by releaseArrayElements()
85  // ignore whether C array is pinned or a copy of Java array
87  ::getArrayElements(env, j, NULL));
88  if (c == NULL) {
89  // exception pending
90  } else {
91  // ok
92  s = 0;
93  }
94  }
95  }
96  return c;
97  }
98 
99  static void
100  release(C * c, typename J::JA_t * j, JNIEnv * env) {
101  TRACE("void ArrayPtrParam.release(C *, typename J::JA_t *, JNIEnv *)");
102 
103  // compile-time flag whether to copy back any possible changes to the
104  // Java array; tradeoff between
105  // - minor performance gains for non-mutable types (const C *)
106  // - observable data differences for C functions that modify an array
107  // argument by casting away its constness
108  //
109  // the settings below reflect this semantics: for
110  // - mutable types (C *):
111  // ==> all changes to the C array are reflected in the Java array
112  // - non-mutable types (const C *) and
113  // - C functions that modify the array despite its constness and
114  // - a JVM that returns a pointer to the pinned, original array
115  // ==> all changes are reflected in the Java array
116  // - a JVM that choses to return a copy of the original array
117  // ==> any change to the C array is lost
118  const jint copyBackMode
120  ? 0 // copy back content if needed and free buffer
121  : JNI_ABORT); // free the buffer without copying back
122 
123  if (c == NULL) {
124  assert(j == NULL); // corresponding convert() succeeded (!)
125  // ok
126  } else {
127  assert(j != NULL);
128  // release the C array allocated by getArrayElements()
130  ::releaseArrayElements(env, j, c, copyBackMode));
131  }
132  }
133 };
134 
135 // Implements the mapping of arrays to pointer results.
136 template< typename J, typename C >
138  static J *
139  convert(C * c, JNIEnv * env) {
140  TRACE("J * ArrayPtrResult.convert(C *, JNIEnv *)");
141 
142  // init return value to error
143  J * j = NULL;
144 
145  if (c == NULL) {
146  // ok
147  } else {
149  ::newArray(env, J::length, c));
150  J * ja = static_cast< J * >(jja);
151  if (ja == NULL) {
152  // exception pending
153  } else {
154  assert(env->GetArrayLength(ja) == J::length);
155  // ok
156  j = ja;
157  }
158  }
159  return j;
160  }
161 };
162 
163 // ---------------------------------------------------------------------------
164 // Specializations for pointer type conversions
165 // ---------------------------------------------------------------------------
166 
167 // Avoid mapping types by broad, generic rules, which easily results in
168 // template instantiation ambiguities for non-primitive types. Therefore,
169 // we enumerate all specicializations for primitive type pointers.
170 
171 // extend array param specializations to const pointers
172 template< typename C >
173 struct Param< _jbooleanArray *, C * const >
175 template< typename C >
176 struct Param< _jbyteArray *, C * const >
178 template< typename C >
179 struct Param< _jshortArray *, C * const >
181 template< typename C >
182 struct Param< _jintArray *, C * const >
184 template< typename C >
185 struct Param< _jlongArray *, C * const >
187 template< typename C >
188 struct Param< _jfloatArray *, C * const >
190 template< typename C >
191 struct Param< _jdoubleArray *, C * const >
193 
194 // extend result array specializations to const pointers
195 template< typename C >
196 struct Result< _jbooleanArray *, C * const >
198 template< typename C >
199 struct Result< _jbyteArray *, C * const >
201 template< typename C >
202 struct Result< _jshortArray *, C * const >
204 template< typename C >
205 struct Result< _jintArray *, C * const >
207 template< typename C >
208 struct Result< _jlongArray *, C * const >
210 template< typename C >
211 struct Result< _jfloatArray *, C * const >
213 template< typename C >
214 struct Result< _jdoubleArray *, C * const >
216 
217 // extend BoundedArrays specializations to const pointers
218 template< typename J, typename C >
219 struct Param< _jtie_j_ArrayMapper< J > *, C * const >
220  : Param< _jtie_j_ArrayMapper< J > *, C * > {};
221 template< typename J, typename C >
222 struct Result< _jtie_j_ArrayMapper< J > *, C * const >
223  : Result< _jtie_j_ArrayMapper< J > *, C * > {};
224 
225 // specialize BoundedArrays mapped to pointers/arrays:
226 // - params: require a minimum array length given by the BoundedArray's
227 // static data member
228 // - results: allocate array with a length given by the BoundedArray's
229 // static data member
230 template< typename J, typename C >
231 struct Param< _jtie_j_ArrayMapper< J > *, C * >
233 template< typename J, typename C >
234 struct Result< _jtie_j_ArrayMapper< J > *, C * >
236 
237 // specialize arrays mapped to pointers/arrays:
238 // - params: do not require a minimum buffer capacity, for size may be zero
239 // when just passing an address
240 // - results: allocate buffer with a capacity of zero, since the size is
241 // unknown (i.e., just returning an address)
242 #define JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING( J, C ) \
243  template<> \
244  struct Param< J *, C * > \
245  : ArrayPtrParam< _jtie_j_BoundedArray< J, 0 >, C > {}; \
246  template<> \
247  struct Param< J *, const C * > \
248  : ArrayPtrParam< _jtie_j_BoundedArray< J, 0 >, const C > {}; \
249  template<> \
250  struct Result< J *, C * > \
251  : ArrayPtrResult< _jtie_j_BoundedArray< J, 0 >, C > {}; \
252  template<> \
253  struct Result< J *, const C * > \
254  : ArrayPtrResult< _jtie_j_BoundedArray< J, 0 >, const C > {};
255 
256 // ---------------------------------------------------------------------------
257 // Specializations for pointer to exact-width primitive type conversions
258 // ---------------------------------------------------------------------------
259 
260 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jbooleanArray, bool)
261 
262 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jbyteArray, char)
263 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jbyteArray, signed char)
264 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jbyteArray, unsigned char)
265 
266 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jfloatArray, float)
267 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jdoubleArray, double)
268 
269 // ---------------------------------------------------------------------------
270 // Specializations for pointer to variable-width primitive type conversions
271 // ---------------------------------------------------------------------------
272 
273 // jshort in LP32, ILP32, LP64, ILP64, LLP64
274 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jshortArray, signed short)
275 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jshortArray, unsigned short)
276 
277 // jshort in LP32
278 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jshortArray, signed int)
279 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jshortArray, unsigned int)
280 
281 // jint in ILP32, LP64, LLP64
282 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jintArray, signed int)
283 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jintArray, unsigned int)
284 
285 // jint in LP32, ILP32, LLP64
286 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jintArray, signed long)
287 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jintArray, unsigned long)
288 
289 // jlong in ILP64
290 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jlongArray, signed int)
291 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jlongArray, unsigned int)
292 
293 // jlong in LP64, ILP64
294 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jlongArray, signed long)
295 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jlongArray, unsigned long)
296 
297 // jlong in LLP64
298 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jlongArray, signed long long)
299 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jlongArray, unsigned long long)
300 
301 // jdouble
302 JTIE_SPECIALIZE_ARRAY_TYPE_MAPPING(_jdoubleArray, long double)
303 
304 // ---------------------------------------------------------------------------
305 
306 #endif // jtie_tconv_ptrbyval_impl_hpp