Home | History | Annotate | Download | only in ti-agent
      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