~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/bindings/javahl/native/jniwrapper/jni_env.hpp

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * @copyright
 
3
 * ====================================================================
 
4
 *    Licensed to the Apache Software Foundation (ASF) under one
 
5
 *    or more contributor license agreements.  See the NOTICE file
 
6
 *    distributed with this work for additional information
 
7
 *    regarding copyright ownership.  The ASF licenses this file
 
8
 *    to you under the Apache License, Version 2.0 (the
 
9
 *    "License"); you may not use this file except in compliance
 
10
 *    with the License.  You may obtain a copy of the License at
 
11
 *
 
12
 *      http://www.apache.org/licenses/LICENSE-2.0
 
13
 *
 
14
 *    Unless required by applicable law or agreed to in writing,
 
15
 *    software distributed under the License is distributed on an
 
16
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 
17
 *    KIND, either express or implied.  See the License for the
 
18
 *    specific language governing permissions and limitations
 
19
 *    under the License.
 
20
 * ====================================================================
 
21
 * @endcopyright
 
22
 */
 
23
 
 
24
#ifndef SVN_JAVAHL_JNIWRAPPER_ENV_HPP
 
25
#define SVN_JAVAHL_JNIWRAPPER_ENV_HPP
 
26
 
 
27
#include <jni.h>
 
28
#include <cstdarg>
 
29
#include <stdexcept>
 
30
 
 
31
#ifdef SVN_JAVAHL_DEBUG
 
32
#  ifndef SVN_JAVAHL_JNIWRAPPER_LOG
 
33
#    include <iostream>
 
34
#    define SVN_JAVAHL_JNIWRAPPER_LOG(expr)      \
 
35
       (std::cerr << expr << std::endl)
 
36
#  endif // SVN_JAVAHL_JNIWRAPPER_LOG
 
37
#else
 
38
#  define SVN_JAVAHL_JNIWRAPPER_LOG(expr)
 
39
#endif // SVN_JAVAHL_DEBUG
 
40
 
 
41
namespace Java {
 
42
 
 
43
/**
 
44
 * A C++ exception object for signalling that a Java exception has
 
45
 * been thrown.
 
46
 *
 
47
 * Thrown to unwind the stack while avoiding code clutter when a Java
 
48
 * exception is detected in the JNI environment.
 
49
 *
 
50
 * @since New in 1.9.
 
51
 */
 
52
class SignalExceptionThrown {};
 
53
 
 
54
/**
 
55
 * Auto-initializing proxy for the JNI method ID.
 
56
 *
 
57
 * Behaves like a @c jmethodID but automatically initializes to @c NULL.
 
58
 *
 
59
 * @since New in 1.9.
 
60
 */
 
61
class MethodID
 
62
{
 
63
public:
 
64
  MethodID()
 
65
    : m_mid(NULL)
 
66
    {}
 
67
 
 
68
  MethodID(jmethodID mid)
 
69
    : m_mid(mid)
 
70
    {}
 
71
 
 
72
  MethodID(const MethodID& that)
 
73
    : m_mid(that.m_mid)
 
74
    {}
 
75
 
 
76
  MethodID& operator=(jmethodID mid)
 
77
    {
 
78
      m_mid = mid;
 
79
      return *this;
 
80
    }
 
81
 
 
82
  MethodID& operator=(const MethodID& that)
 
83
    {
 
84
      m_mid = that.m_mid;
 
85
      return *this;
 
86
    }
 
87
 
 
88
  operator jmethodID() const
 
89
    {
 
90
      return m_mid;
 
91
    }
 
92
 
 
93
  operator bool() const
 
94
    {
 
95
      return (NULL != m_mid);
 
96
    }
 
97
 
 
98
private:
 
99
  jmethodID m_mid;
 
100
};
 
101
 
 
102
 
 
103
/**
 
104
 * Auto-initializing proxy for the JNI field ID.
 
105
 *
 
106
 * Behaves like a @c jfieldID but automatically initializes to @c NULL.
 
107
 *
 
108
 * @since New in 1.9.
 
109
 */
 
110
class FieldID
 
111
{
 
112
public:
 
113
  FieldID()
 
114
    : m_fid(NULL)
 
115
    {}
 
116
 
 
117
  FieldID(jfieldID mid)
 
118
    : m_fid(mid)
 
119
    {}
 
120
 
 
121
  FieldID(const FieldID& that)
 
122
    : m_fid(that.m_fid)
 
123
    {}
 
124
 
 
125
  FieldID& operator=(jfieldID fid)
 
126
    {
 
127
      m_fid = fid;
 
128
      return *this;
 
129
    }
 
130
 
 
131
  FieldID& operator=(const FieldID& that)
 
132
    {
 
133
      m_fid = that.m_fid;
 
134
      return *this;
 
135
    }
 
136
 
 
137
  operator jfieldID() const
 
138
    {
 
139
      return m_fid;
 
140
    }
 
141
 
 
142
  operator bool() const
 
143
    {
 
144
      return (NULL != m_fid);
 
145
    }
 
146
 
 
147
private:
 
148
  jfieldID m_fid;
 
149
};
 
150
 
 
151
/**
 
152
 * Encapsulation of a JNI environment reference.
 
153
 *
 
154
 * This class wraps all (relevant) JNI functions and checks for thrown
 
155
 * exceptions, so that call sites don't have to be cluttered with KNI
 
156
 * exception checks.
 
157
 *
 
158
 * @since New in 1.9.
 
159
 */
 
160
class Env
 
161
{
 
162
public:
 
163
  /**
 
164
   * Constructs an environment object, retrieving the JNI environment
 
165
   * reference from the global JVM reference.
 
166
   */
 
167
  explicit Env()
 
168
    : m_env(env_from_jvm())
 
169
    {}
 
170
 
 
171
  /**
 
172
   * Given a JNI renvironment reference, constructs an environment object.
 
173
   */
 
174
  explicit Env(::JNIEnv* env)
 
175
    : m_env(env)
 
176
    {}
 
177
 
 
178
  /**
 
179
   * Returns the wrapped JNI environment reference.
 
180
   *
 
181
   * This method is present for compatibility with the old-style
 
182
   * native implmentation that needs the raw pointer, and will be
 
183
   * removed presently. Do not use it in new-style code.
 
184
   */
 
185
  ::JNIEnv* get() const
 
186
    {
 
187
      SVN_JAVAHL_JNIWRAPPER_LOG("Warning: Direct access to JNIEnv at "
 
188
                                << __FILE__ << ":" << __LINE__);
 
189
      return m_env;
 
190
    }
 
191
 
 
192
  /** Wrapped JNI function. */
 
193
  jobject NewGlobalRef(jobject obj) const
 
194
    {
 
195
      jobject ret = m_env->NewGlobalRef(obj);
 
196
      check_java_exception();
 
197
      if (!ret)
 
198
        throw_java_out_of_memory(error_create_global_reference());
 
199
      return ret;
 
200
    }
 
201
 
 
202
  /** Wrapped JNI function. */
 
203
  void DeleteGlobalRef(jobject obj) const throw()
 
204
    {
 
205
      m_env->DeleteGlobalRef(obj);
 
206
    }
 
207
 
 
208
  /** Wrapped JNI function. */
 
209
  void PushLocalFrame(jint capacity) const
 
210
    {
 
211
      if (0 > m_env->PushLocalFrame(capacity))
 
212
        throw_java_exception();
 
213
    }
 
214
 
 
215
  /** Wrapped JNI function. */
 
216
  void PopLocalFrame() const throw()
 
217
    {
 
218
      m_env->PopLocalFrame(NULL);
 
219
    }
 
220
 
 
221
  /** Wrapped JNI function. */
 
222
  jint Throw(jthrowable exc) const throw()
 
223
    {
 
224
      return m_env->Throw(exc);
 
225
    }
 
226
 
 
227
  /** Wrapped JNI function. */
 
228
  jint ThrowNew(jclass cls, const char* message) const throw()
 
229
    {
 
230
      return m_env->ThrowNew(cls, message);
 
231
    }
 
232
 
 
233
  /** Wrapped JNI function. */
 
234
  jboolean ExceptionCheck() const throw()
 
235
    {
 
236
      return m_env->ExceptionCheck();
 
237
    }
 
238
 
 
239
  /** Wrapped JNI function. */
 
240
  jthrowable ExceptionOccurred() const throw()
 
241
    {
 
242
      return m_env->ExceptionOccurred();
 
243
    }
 
244
 
 
245
  /** Wrapped JNI function. */
 
246
  void ExceptionClear() const throw()
 
247
    {
 
248
      m_env->ExceptionClear();
 
249
    }
 
250
 
 
251
  /** Wrapped JNI function. */
 
252
  jclass FindClass(const char* name) const
 
253
    {
 
254
      jclass cls = m_env->FindClass(name);
 
255
      check_java_exception();
 
256
      return cls;
 
257
    }
 
258
 
 
259
  /** Wrapped JNI function. */
 
260
  jobject NewObject(jclass cls, jmethodID ctor, ...) const
 
261
    {
 
262
      std::va_list args;
 
263
      va_start(args, ctor);
 
264
      jobject obj = m_env->NewObjectV(cls, ctor, args);
 
265
      va_end(args);
 
266
      check_java_exception();
 
267
      return obj;
 
268
    }
 
269
 
 
270
  /** Wrapped JNI function. */
 
271
  jclass GetObjectClass(jobject obj) const
 
272
    {
 
273
      jclass cls = m_env->GetObjectClass(obj);
 
274
      check_java_exception();
 
275
      return cls;
 
276
    }
 
277
 
 
278
  /** Wrapped JNI function. */
 
279
  jboolean IsInstanceOf(jobject obj, jclass cls) const throw()
 
280
    {
 
281
      return m_env->IsInstanceOf(obj, cls);
 
282
    }
 
283
 
 
284
  /** Wrapped JNI function. */
 
285
  jmethodID GetMethodID(jclass cls, const char* name, const char* sig) const
 
286
    {
 
287
      jmethodID mid = m_env->GetMethodID(cls, name, sig);
 
288
      check_java_exception();
 
289
      return mid;
 
290
    }
 
291
 
 
292
  /** Wrapped JNI function. */
 
293
  jmethodID GetStaticMethodID(jclass cls, const char* name,
 
294
                              const char* sig) const
 
295
    {
 
296
      jmethodID mid = m_env->GetStaticMethodID(cls, name, sig);
 
297
      check_java_exception();
 
298
      return mid;
 
299
    }
 
300
 
 
301
  /** Wrapped JNI function. */
 
302
  jfieldID GetFieldID(jclass cls, const char* name, const char* sig) const
 
303
    {
 
304
      jfieldID fid = m_env->GetFieldID(cls, name, sig);
 
305
      check_java_exception();
 
306
      return fid;
 
307
    }
 
308
 
 
309
  /** Wrapped JNI function. */
 
310
  jfieldID GetStaticFieldID(jclass cls, const char* name,
 
311
                            const char* sig) const
 
312
    {
 
313
      jfieldID fid = m_env->GetStaticFieldID(cls, name, sig);
 
314
      check_java_exception();
 
315
      return fid;
 
316
    }
 
317
 
 
318
  /** Wrapped JNI function. */
 
319
  jstring NewStringUTF(const char* text) const
 
320
    {
 
321
      if (!text)
 
322
        return NULL;
 
323
 
 
324
      jstring str = m_env->NewStringUTF(text);
 
325
      check_java_exception();
 
326
      return str;
 
327
    }
 
328
 
 
329
  /** Wrapped JNI function. */
 
330
  jsize GetStringLength(jstring str) const
 
331
    {
 
332
      jsize len = m_env->GetStringLength(str);
 
333
      check_java_exception();
 
334
      return len;
 
335
    }
 
336
 
 
337
  /** Wrapped JNI function. */
 
338
  jsize GetStringUTFLength(jstring str) const
 
339
    {
 
340
      jsize len = m_env->GetStringUTFLength(str);
 
341
      check_java_exception();
 
342
      return len;
 
343
    }
 
344
 
 
345
  /** Wrapped JNI function. */
 
346
  const char* GetStringUTFChars(jstring str, jboolean* is_copy) const
 
347
    {
 
348
      if (!str)
 
349
        return NULL;
 
350
 
 
351
      const char* text = m_env->GetStringUTFChars(str, is_copy);
 
352
      check_java_exception();
 
353
      if (!text)
 
354
        throw_java_out_of_memory(error_get_contents_string());
 
355
      return text;
 
356
    }
 
357
 
 
358
  /** Wrapped JNI function. */
 
359
  void ReleaseStringUTFChars(jstring str, const char* new_text) const
 
360
    {
 
361
      if (!str)
 
362
        throw std::logic_error(error_release_null_string());
 
363
      m_env->ReleaseStringUTFChars(str, new_text);
 
364
    }
 
365
 
 
366
  /** Wrapped JNI function. */
 
367
  void CallVoidMethod(jobject obj, jmethodID mid, ...) const
 
368
    {
 
369
      std::va_list args;
 
370
      va_start(args, mid);
 
371
      m_env->CallObjectMethodV(obj, mid, args);
 
372
      va_end(args);
 
373
      check_java_exception();
 
374
    }
 
375
 
 
376
  /** Boilerplate generator for wrapped JNI functions. */
 
377
#define SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(T, N)               \
 
378
  T Call##N##Method(jobject obj, jmethodID mid, ...) const      \
 
379
    {                                                           \
 
380
      std::va_list args;                                        \
 
381
      va_start(args, mid);                                      \
 
382
      T ret = m_env->Call##N##MethodV(obj, mid, args);          \
 
383
      va_end(args);                                             \
 
384
      check_java_exception();                                   \
 
385
      return ret;                                               \
 
386
    }
 
387
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jobject, Object)
 
388
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jboolean, Boolean)
 
389
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jbyte, Byte)
 
390
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jchar, Char)
 
391
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jshort, Short)
 
392
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jint, Int)
 
393
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jlong, Long)
 
394
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jfloat, Float)
 
395
  SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD(jdouble, Double)
 
396
#undef SVN_JAVAHL_JNIWRAPPER_CALL_X_METHOD
 
397
 
 
398
  /** Boilerplate generator for wrapped JNI functions. */
 
399
#define SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(T, N)                \
 
400
  T CallStatic##N##Method(jclass obj, jmethodID mid, ...) const         \
 
401
    {                                                                   \
 
402
      std::va_list args;                                                \
 
403
      va_start(args, mid);                                              \
 
404
      T ret = m_env->CallStatic##N##MethodV(obj, mid, args);            \
 
405
      va_end(args);                                                     \
 
406
      check_java_exception();                                           \
 
407
      return ret;                                                       \
 
408
    }
 
409
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jobject, Object)
 
410
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jboolean, Boolean)
 
411
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jbyte, Byte)
 
412
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jchar, Char)
 
413
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jshort, Short)
 
414
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jint, Int)
 
415
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jlong, Long)
 
416
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jfloat, Float)
 
417
  SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD(jdouble, Double)
 
418
#undef SVN_JAVAHL_JNIWRAPPER_CALL_STATIC_X_METHOD
 
419
 
 
420
  /** Boilerplate generator for wrapped JNI functions. */
 
421
#define SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(T, N)                 \
 
422
  T Get##N##Field(jobject obj, jfieldID fid) const              \
 
423
    {                                                           \
 
424
      T ret = m_env->Get##N##Field(obj, fid);                   \
 
425
      check_java_exception();                                   \
 
426
      return ret;                                               \
 
427
    }
 
428
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jobject, Object)
 
429
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jboolean, Boolean)
 
430
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jbyte, Byte)
 
431
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jchar, Char)
 
432
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jshort, Short)
 
433
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jint, Int)
 
434
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jlong, Long)
 
435
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jfloat, Float)
 
436
  SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD(jdouble, Double)
 
437
#undef SVN_JAVAHL_JNIWRAPPER_GET_X_FIELD
 
438
 
 
439
  /** Boilerplate generator for wrapped JNI functions. */
 
440
#define SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(T, N)                 \
 
441
  void Set##N##Field(jobject obj, jfieldID fid, T val) const    \
 
442
    {                                                           \
 
443
      m_env->Set##N##Field(obj, fid, val);                      \
 
444
      check_java_exception();                                   \
 
445
    }
 
446
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jobject, Object)
 
447
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jboolean, Boolean)
 
448
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jbyte, Byte)
 
449
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jchar, Char)
 
450
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jshort, Short)
 
451
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jint, Int)
 
452
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jlong, Long)
 
453
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jfloat, Float)
 
454
  SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD(jdouble, Double)
 
455
#undef SVN_JAVAHL_JNIWRAPPER_SET_X_FIELD
 
456
 
 
457
  /** Boilerplate generator for wrapped JNI functions. */
 
458
#define SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(T, N)          \
 
459
  T GetStatic##N##Field(jclass cls, jfieldID fid) const         \
 
460
    {                                                           \
 
461
      T ret = m_env->GetStatic##N##Field(cls, fid);             \
 
462
      check_java_exception();                                   \
 
463
      return ret;                                               \
 
464
    }
 
465
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jobject, Object)
 
466
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jboolean, Boolean)
 
467
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jbyte, Byte)
 
468
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jchar, Char)
 
469
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jshort, Short)
 
470
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jint, Int)
 
471
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jlong, Long)
 
472
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jfloat, Float)
 
473
  SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD(jdouble, Double)
 
474
#undef SVN_JAVAHL_JNIWRAPPER_GET_STATIC_X_FIELD
 
475
 
 
476
  /** Boilerplate generator for wrapped JNI functions. */
 
477
#define SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(T, N)                  \
 
478
  void SetStatic##N##Field(jclass cls, jfieldID fid, T val) const       \
 
479
    {                                                                   \
 
480
      m_env->SetStatic##N##Field(cls, fid, val);                        \
 
481
      check_java_exception();                                           \
 
482
    }
 
483
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jobject, Object)
 
484
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jboolean, Boolean)
 
485
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jbyte, Byte)
 
486
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jchar, Char)
 
487
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jshort, Short)
 
488
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jint, Int)
 
489
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jlong, Long)
 
490
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jfloat, Float)
 
491
  SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD(jdouble, Double)
 
492
#undef SVN_JAVAHL_JNIWRAPPER_SET_STATIC_X_FIELD
 
493
 
 
494
  /** Wrapped JNI function. */
 
495
  jsize GetArrayLength(jarray array) const
 
496
    {
 
497
      if (!array)
 
498
        return 0;
 
499
      return m_env->GetArrayLength(array);
 
500
    }
 
501
 
 
502
  /** Wrapped JNI function. */
 
503
  jobjectArray NewObjectArray(jsize length, jclass cls, jobject init) const
 
504
    {
 
505
      jobjectArray array = m_env->NewObjectArray(length, cls, init);
 
506
      if (!array)
 
507
        throw_java_out_of_memory(error_create_object_array());
 
508
      return array;
 
509
    }
 
510
 
 
511
  /** Wrapped JNI function. */
 
512
  jobject GetObjectArrayElement(jobjectArray array, jsize index) const
 
513
    {
 
514
      jobject obj = m_env->GetObjectArrayElement(array, index);
 
515
      check_java_exception();
 
516
      return obj;
 
517
    }
 
518
 
 
519
  /** Wrapped JNI function. */
 
520
  void SetObjectArrayElement(jobjectArray array,
 
521
                             jsize index, jobject value) const
 
522
    {
 
523
      m_env->SetObjectArrayElement(array, index, value);
 
524
      check_java_exception();
 
525
    }
 
526
 
 
527
  /** Boilerplate generator for wrapped JNI functions. */
 
528
#define SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(T, N)                \
 
529
  T##Array New##N##Array(jsize length) const                            \
 
530
    {                                                                   \
 
531
      T##Array array = m_env->New##N##Array(length);                    \
 
532
      if (!array)                                                       \
 
533
        throw_java_out_of_memory(error_create_array(#T));               \
 
534
      return array;                                                     \
 
535
    }                                                                   \
 
536
  T* Get##N##ArrayElements(T##Array array, jboolean* is_copy) const     \
 
537
    {                                                                   \
 
538
      if (!array)                                                       \
 
539
        return NULL;                                                    \
 
540
                                                                        \
 
541
      T* data = m_env->Get##N##ArrayElements(array, is_copy);           \
 
542
      check_java_exception();                                           \
 
543
      if (!data)                                                        \
 
544
        throw_java_out_of_memory(error_get_contents_array(#N));         \
 
545
      return data;                                                      \
 
546
    }                                                                   \
 
547
  void Release##N##ArrayElements(T##Array array, T* data, jint mode) const \
 
548
    {                                                                   \
 
549
      if (!array)                                                       \
 
550
        throw std::logic_error(error_release_null_array(#T));           \
 
551
      m_env->Release##N##ArrayElements(array, data, mode);              \
 
552
    }
 
553
 
 
554
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jboolean, Boolean)
 
555
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jbyte, Byte)
 
556
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jchar, Char)
 
557
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jshort, Short)
 
558
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jint, Int)
 
559
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jlong, Long)
 
560
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jfloat, Float)
 
561
  SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY(jdouble, Double)
 
562
#undef SVN_JAVAHL_JNIWRAPPER_PRIMITIVE_TYPE_ARRAY
 
563
 
 
564
  /** Wrapped JNI function. */
 
565
  void* GetDirectBufferAddress(jobject buffer) const
 
566
    {
 
567
      void* const addr = m_env->GetDirectBufferAddress(buffer);
 
568
      check_java_exception();
 
569
      return addr;
 
570
    }
 
571
 
 
572
private:
 
573
  ::JNIEnv* m_env;
 
574
  static ::JavaVM* m_jvm;
 
575
  static ::JNIEnv* env_from_jvm();
 
576
 
 
577
  void throw_java_exception() const
 
578
    {
 
579
      throw SignalExceptionThrown();
 
580
    }
 
581
 
 
582
  void check_java_exception() const
 
583
    {
 
584
      if (m_env->ExceptionCheck())
 
585
        throw SignalExceptionThrown();
 
586
    }
 
587
 
 
588
  void throw_java_out_of_memory(const char* message) const;
 
589
 
 
590
  // We cannont use svn_private_config.h in a header, so we move the
 
591
  // actual message translations into the implementation file.
 
592
  static const char* error_create_global_reference() throw();
 
593
  static const char* error_get_contents_string() throw();
 
594
  static const char* error_release_null_string() throw();
 
595
 
 
596
  static const char* error_create_object_array() throw();
 
597
  static const char* error_create_array(const char* type) throw();
 
598
  static const char* error_get_contents_array(const char* type) throw();
 
599
  static const char* error_release_null_array(const char* type) throw();
 
600
 
 
601
public:
 
602
  // This static initializer must only be called by JNI_OnLoad
 
603
  static void static_init(::JavaVM*);
 
604
};
 
605
 
 
606
 
 
607
/**
 
608
 * Encapsulation of a JNI local frame.
 
609
 *
 
610
 * Used within loop bodies to limit the proliferation of local
 
611
 * references, or anywhere else where such references should be
 
612
 * pre-emptively discarded.
 
613
 *
 
614
 * @since New in 1.9.
 
615
 */
 
616
class LocalFrame
 
617
{
 
618
  static const jint DEFAULT_CAPACITY;
 
619
 
 
620
public:
 
621
  /**
 
622
   * Constructs a local frame, retrieving the JNI environment
 
623
   * reference from the global JVM reference.
 
624
   */
 
625
  explicit LocalFrame()
 
626
    : m_env(Env())
 
627
    {
 
628
      m_env.PushLocalFrame(DEFAULT_CAPACITY);
 
629
    }
 
630
 
 
631
  /**
 
632
   * Given a JNI renvironment reference, constructs a local frame.
 
633
   */
 
634
  explicit LocalFrame(Env env)
 
635
    : m_env(env)
 
636
    {
 
637
      m_env.PushLocalFrame(DEFAULT_CAPACITY);
 
638
    }
 
639
 
 
640
  /**
 
641
   * Constructs a local frame with the given initial @a capacity,
 
642
   * retrieving the JNI environment reference from the global JVM
 
643
   * reference.
 
644
   */
 
645
  explicit LocalFrame(jint capacity)
 
646
    : m_env(Env())
 
647
    {
 
648
      m_env.PushLocalFrame(capacity);
 
649
    }
 
650
 
 
651
  /**
 
652
   * Given a JNI renvironment reference, constructs a local frame with
 
653
   * the given initial @a capacity.
 
654
   */
 
655
  explicit LocalFrame(Env env, jint capacity)
 
656
    : m_env(env)
 
657
    {
 
658
      m_env.PushLocalFrame(capacity);
 
659
    }
 
660
 
 
661
  ~LocalFrame()
 
662
    {
 
663
      m_env.PopLocalFrame();
 
664
    }
 
665
 
 
666
  /**
 
667
   * Returns the stored enviromnent object.
 
668
   */
 
669
  Env get_env() const
 
670
    {
 
671
      return m_env;
 
672
    }
 
673
 
 
674
private:
 
675
  const Env m_env;
 
676
  LocalFrame(const LocalFrame&);
 
677
  LocalFrame& operator=(const LocalFrame&);
 
678
};
 
679
 
 
680
} // namespace Java
 
681
 
 
682
#endif // SVN_JAVAHL_JNIWRAPPER_ENV_HPP