blob: 46f1786a3e614dc80e8cd0b453d70c8c759bdb86 [file] [log] [blame]
Brian Carlstrom3d9d2142013-05-10 14:09:30 -07001/*
2 * Copyright (C) 2010 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#ifndef SCOPED_PRIMITIVE_ARRAY_H_included
18#define SCOPED_PRIMITIVE_ARRAY_H_included
19
20#include "JNIHelp.h"
21
Chih-Hung Hsieh83c71692016-06-10 14:24:36 -070022#ifdef POINTER_TYPE
23#error POINTER_TYPE is defined.
24#else
25#define POINTER_TYPE(T) T* /* NOLINT */
26#endif
27
28#ifdef REFERENCE_TYPE
29#error REFERENCE_TYPE is defined.
30#else
31#define REFERENCE_TYPE(T) T& /* NOLINT */
32#endif
33
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070034// ScopedBooleanArrayRO, ScopedByteArrayRO, ScopedCharArrayRO, ScopedDoubleArrayRO,
35// ScopedFloatArrayRO, ScopedIntArrayRO, ScopedLongArrayRO, and ScopedShortArrayRO provide
36// convenient read-only access to Java arrays from JNI code. This is cheaper than read-write
37// access and should be used by default.
38#define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(PRIMITIVE_TYPE, NAME) \
39 class Scoped ## NAME ## ArrayRO { \
40 public: \
Kenny Root389e0882013-05-17 08:14:02 -070041 explicit Scoped ## NAME ## ArrayRO(JNIEnv* env) \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070042 : mEnv(env), mJavaArray(NULL), mRawArray(NULL), mSize(0) {} \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070043 Scoped ## NAME ## ArrayRO(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070044 : mEnv(env) { \
45 if (javaArray == NULL) { \
46 mJavaArray = NULL; \
47 mSize = 0; \
48 mRawArray = NULL; \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070049 jniThrowNullPointerException(mEnv, NULL); \
50 } else { \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070051 reset(javaArray); \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070052 } \
53 } \
54 ~Scoped ## NAME ## ArrayRO() { \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070055 if (mRawArray != NULL && mRawArray != mBuffer) { \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070056 mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, JNI_ABORT); \
57 } \
58 } \
Kenny Root389e0882013-05-17 08:14:02 -070059 void reset(PRIMITIVE_TYPE ## Array javaArray) { \
60 mJavaArray = javaArray; \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070061 mSize = mEnv->GetArrayLength(mJavaArray); \
62 if (mSize <= buffer_size) { \
63 mEnv->Get ## NAME ## ArrayRegion(mJavaArray, 0, mSize, mBuffer); \
64 mRawArray = mBuffer; \
65 } else { \
66 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, NULL); \
67 } \
Kenny Root389e0882013-05-17 08:14:02 -070068 } \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070069 const PRIMITIVE_TYPE* get() const { return mRawArray; } \
70 PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
71 const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070072 size_t size() const { return mSize; } \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070073 private: \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070074 static const jsize buffer_size = 1024; \
Ian Rogers8288dde2014-11-04 11:42:02 -080075 JNIEnv* const mEnv; \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070076 PRIMITIVE_TYPE ## Array mJavaArray; \
Chih-Hung Hsieh83c71692016-06-10 14:24:36 -070077 POINTER_TYPE(PRIMITIVE_TYPE) mRawArray; \
Mathieu Chartiere7fc23d2015-09-04 16:37:38 -070078 jsize mSize; \
79 PRIMITIVE_TYPE mBuffer[buffer_size]; \
Ian Rogers8288dde2014-11-04 11:42:02 -080080 DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRO); \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -070081 }
82
83INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jboolean, Boolean);
84INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jbyte, Byte);
85INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jchar, Char);
86INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jdouble, Double);
87INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jfloat, Float);
88INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jint, Int);
89INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jlong, Long);
90INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jshort, Short);
91
92#undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO
93
94// ScopedBooleanArrayRW, ScopedByteArrayRW, ScopedCharArrayRW, ScopedDoubleArrayRW,
95// ScopedFloatArrayRW, ScopedIntArrayRW, ScopedLongArrayRW, and ScopedShortArrayRW provide
96// convenient read-write access to Java arrays from JNI code. These are more expensive,
97// since they entail a copy back onto the Java heap, and should only be used when necessary.
98#define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(PRIMITIVE_TYPE, NAME) \
99 class Scoped ## NAME ## ArrayRW { \
100 public: \
Kenny Root389e0882013-05-17 08:14:02 -0700101 explicit Scoped ## NAME ## ArrayRW(JNIEnv* env) \
102 : mEnv(env), mJavaArray(NULL), mRawArray(NULL) {} \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -0700103 Scoped ## NAME ## ArrayRW(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \
104 : mEnv(env), mJavaArray(javaArray), mRawArray(NULL) { \
105 if (mJavaArray == NULL) { \
106 jniThrowNullPointerException(mEnv, NULL); \
107 } else { \
108 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, NULL); \
109 } \
110 } \
111 ~Scoped ## NAME ## ArrayRW() { \
112 if (mRawArray) { \
113 mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, 0); \
114 } \
115 } \
Kenny Root389e0882013-05-17 08:14:02 -0700116 void reset(PRIMITIVE_TYPE ## Array javaArray) { \
117 mJavaArray = javaArray; \
118 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, NULL); \
119 } \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -0700120 const PRIMITIVE_TYPE* get() const { return mRawArray; } \
121 PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
122 const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
Chih-Hung Hsieh83c71692016-06-10 14:24:36 -0700123 POINTER_TYPE(PRIMITIVE_TYPE) get() { return mRawArray; } \
124 REFERENCE_TYPE(PRIMITIVE_TYPE) operator[](size_t n) { return mRawArray[n]; } \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -0700125 size_t size() const { return mEnv->GetArrayLength(mJavaArray); } \
126 private: \
Ian Rogers8288dde2014-11-04 11:42:02 -0800127 JNIEnv* const mEnv; \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -0700128 PRIMITIVE_TYPE ## Array mJavaArray; \
Chih-Hung Hsieh83c71692016-06-10 14:24:36 -0700129 POINTER_TYPE(PRIMITIVE_TYPE) mRawArray; \
Ian Rogers8288dde2014-11-04 11:42:02 -0800130 DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRW); \
Brian Carlstrom3d9d2142013-05-10 14:09:30 -0700131 }
132
133INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jboolean, Boolean);
134INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jbyte, Byte);
135INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jchar, Char);
136INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jdouble, Double);
137INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jfloat, Float);
138INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jint, Int);
139INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jlong, Long);
140INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jshort, Short);
141
142#undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW
Chih-Hung Hsieh83c71692016-06-10 14:24:36 -0700143#undef POINTER_TYPE
144#undef REFERENCE_TYPE
Brian Carlstrom3d9d2142013-05-10 14:09:30 -0700145
146#endif // SCOPED_PRIMITIVE_ARRAY_H_included