blob: 1649ed997adf75176da88174c3bd084cf69c0734 [file] [log] [blame]
Andreas Gampe027444b2017-03-31 12:49:07 -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 ART_TEST_TI_AGENT_SCOPED_PRIMITIVE_ARRAY_H_
18#define ART_TEST_TI_AGENT_SCOPED_PRIMITIVE_ARRAY_H_
19
20#include "jni.h"
21
22#include "android-base/macros.h"
23
24#include "jni_helper.h"
25
26namespace art {
27
28#ifdef POINTER_TYPE
29#error POINTER_TYPE is defined.
30#else
31#define POINTER_TYPE(T) T* /* NOLINT */
32#endif
33
34#ifdef REFERENCE_TYPE
35#error REFERENCE_TYPE is defined.
36#else
37#define REFERENCE_TYPE(T) T& /* NOLINT */
38#endif
39
40// ScopedBooleanArrayRO, ScopedByteArrayRO, ScopedCharArrayRO, ScopedDoubleArrayRO,
41// ScopedFloatArrayRO, ScopedIntArrayRO, ScopedLongArrayRO, and ScopedShortArrayRO provide
42// convenient read-only access to Java arrays from JNI code. This is cheaper than read-write
43// access and should be used by default.
44#define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(PRIMITIVE_TYPE, NAME) \
45 class Scoped ## NAME ## ArrayRO { \
46 public: \
47 explicit Scoped ## NAME ## ArrayRO(JNIEnv* env) \
48 : mEnv(env), mJavaArray(nullptr), mRawArray(nullptr), mSize(0) {} \
49 Scoped ## NAME ## ArrayRO(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \
50 : mEnv(env) { \
51 if (javaArray == nullptr) { \
52 mJavaArray = nullptr; \
53 mSize = 0; \
54 mRawArray = nullptr; \
55 JniThrowNullPointerException(env, nullptr); \
56 } else { \
57 reset(javaArray); \
58 } \
59 } \
60 ~Scoped ## NAME ## ArrayRO() { \
61 if (mRawArray != nullptr && mRawArray != mBuffer) { \
62 mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, JNI_ABORT); \
63 } \
64 } \
65 void reset(PRIMITIVE_TYPE ## Array javaArray) { \
66 mJavaArray = javaArray; \
67 mSize = mEnv->GetArrayLength(mJavaArray); \
68 if (mSize <= kBufferSize) { \
69 mEnv->Get ## NAME ## ArrayRegion(mJavaArray, 0, mSize, mBuffer); \
70 mRawArray = mBuffer; \
71 } else { \
72 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, nullptr); \
73 } \
74 } \
75 const PRIMITIVE_TYPE* get() const { return mRawArray; } \
76 PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
77 const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
78 size_t size() const { return mSize; } \
79 private: \
80 static constexpr jsize kBufferSize = 1024; \
81 JNIEnv* const mEnv; \
82 PRIMITIVE_TYPE ## Array mJavaArray; \
83 POINTER_TYPE(PRIMITIVE_TYPE) mRawArray; \
84 jsize mSize; \
85 PRIMITIVE_TYPE mBuffer[kBufferSize]; \
86 DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRO); \
87 }
88
89INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jboolean, Boolean);
90INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jbyte, Byte);
91INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jchar, Char);
92INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jdouble, Double);
93INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jfloat, Float);
94INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jint, Int);
95INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jlong, Long);
96INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jshort, Short);
97
98#undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO
99
100// ScopedBooleanArrayRW, ScopedByteArrayRW, ScopedCharArrayRW, ScopedDoubleArrayRW,
101// ScopedFloatArrayRW, ScopedIntArrayRW, ScopedLongArrayRW, and ScopedShortArrayRW provide
102// convenient read-write access to Java arrays from JNI code. These are more expensive,
103// since they entail a copy back onto the Java heap, and should only be used when necessary.
104#define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(PRIMITIVE_TYPE, NAME) \
105 class Scoped ## NAME ## ArrayRW { \
106 public: \
107 explicit Scoped ## NAME ## ArrayRW(JNIEnv* env) \
108 : mEnv(env), mJavaArray(nullptr), mRawArray(nullptr) {} \
109 Scoped ## NAME ## ArrayRW(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \
110 : mEnv(env), mJavaArray(javaArray), mRawArray(nullptr) { \
111 if (mJavaArray == nullptr) { \
112 JniThrowNullPointerException(env, nullptr); \
113 } else { \
114 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, nullptr); \
115 } \
116 } \
117 ~Scoped ## NAME ## ArrayRW() { \
118 if (mRawArray) { \
119 mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, 0); \
120 } \
121 } \
122 void reset(PRIMITIVE_TYPE ## Array javaArray) { \
123 mJavaArray = javaArray; \
124 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, nullptr); \
125 } \
126 const PRIMITIVE_TYPE* get() const { return mRawArray; } \
127 PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
128 const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
129 POINTER_TYPE(PRIMITIVE_TYPE) get() { return mRawArray; } \
130 REFERENCE_TYPE(PRIMITIVE_TYPE) operator[](size_t n) { return mRawArray[n]; } \
131 size_t size() const { return mEnv->GetArrayLength(mJavaArray); } \
132 private: \
133 JNIEnv* const mEnv; \
134 PRIMITIVE_TYPE ## Array mJavaArray; \
135 POINTER_TYPE(PRIMITIVE_TYPE) mRawArray; \
136 DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRW); \
137 }
138
139INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jboolean, Boolean);
140INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jbyte, Byte);
141INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jchar, Char);
142INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jdouble, Double);
143INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jfloat, Float);
144INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jint, Int);
145INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jlong, Long);
146INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jshort, Short);
147
148#undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW
149#undef POINTER_TYPE
150#undef REFERENCE_TYPE
151
152} // namespace art
153
154#endif // ART_TEST_TI_AGENT_SCOPED_PRIMITIVE_ARRAY_H_