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