• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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