1 /* 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 26 namespace 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 89 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jboolean, Boolean); 90 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jbyte, Byte); 91 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jchar, Char); 92 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jdouble, Double); 93 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jfloat, Float); 94 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jint, Int); 95 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jlong, Long); 96 INSTANTIATE_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 139 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jboolean, Boolean); 140 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jbyte, Byte); 141 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jchar, Char); 142 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jdouble, Double); 143 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jfloat, Float); 144 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jint, Int); 145 INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jlong, Long); 146 INSTANTIATE_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_ 155