xref: /aosp_15_r20/art/test/ti-agent/scoped_primitive_array.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_TEST_TI_AGENT_SCOPED_PRIMITIVE_ARRAY_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_TEST_TI_AGENT_SCOPED_PRIMITIVE_ARRAY_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "jni.h"
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "android-base/macros.h"
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #include "jni_helper.h"
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker namespace art {
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker #ifdef POINTER_TYPE
29*795d594fSAndroid Build Coastguard Worker #error POINTER_TYPE is defined.
30*795d594fSAndroid Build Coastguard Worker #else
31*795d594fSAndroid Build Coastguard Worker #define POINTER_TYPE(T) T*  /* NOLINT */
32*795d594fSAndroid Build Coastguard Worker #endif
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker #ifdef REFERENCE_TYPE
35*795d594fSAndroid Build Coastguard Worker #error REFERENCE_TYPE is defined.
36*795d594fSAndroid Build Coastguard Worker #else
37*795d594fSAndroid Build Coastguard Worker #define REFERENCE_TYPE(T) T&  /* NOLINT */
38*795d594fSAndroid Build Coastguard Worker #endif
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker // ScopedBooleanArrayRO, ScopedByteArrayRO, ScopedCharArrayRO, ScopedDoubleArrayRO,
41*795d594fSAndroid Build Coastguard Worker // ScopedFloatArrayRO, ScopedIntArrayRO, ScopedLongArrayRO, and ScopedShortArrayRO provide
42*795d594fSAndroid Build Coastguard Worker // convenient read-only access to Java arrays from JNI code. This is cheaper than read-write
43*795d594fSAndroid Build Coastguard Worker // access and should be used by default.
44*795d594fSAndroid Build Coastguard Worker #define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(PRIMITIVE_TYPE, NAME) \
45*795d594fSAndroid Build Coastguard Worker     class Scoped ## NAME ## ArrayRO { \
46*795d594fSAndroid Build Coastguard Worker      public: \
47*795d594fSAndroid Build Coastguard Worker         explicit Scoped ## NAME ## ArrayRO(JNIEnv* env) \
48*795d594fSAndroid Build Coastguard Worker         : mEnv(env), mJavaArray(nullptr), mRawArray(nullptr), mSize(0) {} \
49*795d594fSAndroid Build Coastguard Worker         Scoped ## NAME ## ArrayRO(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \
50*795d594fSAndroid Build Coastguard Worker         : mEnv(env) { \
51*795d594fSAndroid Build Coastguard Worker             if (javaArray == nullptr) { \
52*795d594fSAndroid Build Coastguard Worker                 mJavaArray = nullptr; \
53*795d594fSAndroid Build Coastguard Worker                 mSize = 0; \
54*795d594fSAndroid Build Coastguard Worker                 mRawArray = nullptr; \
55*795d594fSAndroid Build Coastguard Worker                 JniThrowNullPointerException(env, nullptr); \
56*795d594fSAndroid Build Coastguard Worker             } else { \
57*795d594fSAndroid Build Coastguard Worker                 reset(javaArray); \
58*795d594fSAndroid Build Coastguard Worker             } \
59*795d594fSAndroid Build Coastguard Worker         } \
60*795d594fSAndroid Build Coastguard Worker         ~Scoped ## NAME ## ArrayRO() { \
61*795d594fSAndroid Build Coastguard Worker             if (mRawArray != nullptr && mRawArray != mBuffer) { \
62*795d594fSAndroid Build Coastguard Worker                 mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, JNI_ABORT); \
63*795d594fSAndroid Build Coastguard Worker             } \
64*795d594fSAndroid Build Coastguard Worker         } \
65*795d594fSAndroid Build Coastguard Worker         void reset(PRIMITIVE_TYPE ## Array javaArray) { \
66*795d594fSAndroid Build Coastguard Worker             mJavaArray = javaArray; \
67*795d594fSAndroid Build Coastguard Worker             mSize = mEnv->GetArrayLength(mJavaArray); \
68*795d594fSAndroid Build Coastguard Worker             if (mSize <= kBufferSize) { \
69*795d594fSAndroid Build Coastguard Worker                 mEnv->Get ## NAME ## ArrayRegion(mJavaArray, 0, mSize, mBuffer); \
70*795d594fSAndroid Build Coastguard Worker                 mRawArray = mBuffer; \
71*795d594fSAndroid Build Coastguard Worker             } else { \
72*795d594fSAndroid Build Coastguard Worker                 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, nullptr); \
73*795d594fSAndroid Build Coastguard Worker             } \
74*795d594fSAndroid Build Coastguard Worker         } \
75*795d594fSAndroid Build Coastguard Worker         const PRIMITIVE_TYPE* get() const { return mRawArray; } \
76*795d594fSAndroid Build Coastguard Worker         PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
77*795d594fSAndroid Build Coastguard Worker         const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
78*795d594fSAndroid Build Coastguard Worker         size_t size() const { return mSize; } \
79*795d594fSAndroid Build Coastguard Worker      private: \
80*795d594fSAndroid Build Coastguard Worker         static constexpr jsize kBufferSize = 1024; \
81*795d594fSAndroid Build Coastguard Worker         JNIEnv* const mEnv; \
82*795d594fSAndroid Build Coastguard Worker         PRIMITIVE_TYPE ## Array mJavaArray; \
83*795d594fSAndroid Build Coastguard Worker         POINTER_TYPE(PRIMITIVE_TYPE) mRawArray; \
84*795d594fSAndroid Build Coastguard Worker         jsize mSize; \
85*795d594fSAndroid Build Coastguard Worker         PRIMITIVE_TYPE mBuffer[kBufferSize]; \
86*795d594fSAndroid Build Coastguard Worker         DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRO); \
87*795d594fSAndroid Build Coastguard Worker     }
88*795d594fSAndroid Build Coastguard Worker 
89*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jboolean, Boolean);
90*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jbyte, Byte);
91*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jchar, Char);
92*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jdouble, Double);
93*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jfloat, Float);
94*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jint, Int);
95*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jlong, Long);
96*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO(jshort, Short);
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker #undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RO
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker // ScopedBooleanArrayRW, ScopedByteArrayRW, ScopedCharArrayRW, ScopedDoubleArrayRW,
101*795d594fSAndroid Build Coastguard Worker // ScopedFloatArrayRW, ScopedIntArrayRW, ScopedLongArrayRW, and ScopedShortArrayRW provide
102*795d594fSAndroid Build Coastguard Worker // convenient read-write access to Java arrays from JNI code. These are more expensive,
103*795d594fSAndroid Build Coastguard Worker // since they entail a copy back onto the Java heap, and should only be used when necessary.
104*795d594fSAndroid Build Coastguard Worker #define INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(PRIMITIVE_TYPE, NAME) \
105*795d594fSAndroid Build Coastguard Worker     class Scoped ## NAME ## ArrayRW { \
106*795d594fSAndroid Build Coastguard Worker      public: \
107*795d594fSAndroid Build Coastguard Worker         explicit Scoped ## NAME ## ArrayRW(JNIEnv* env) \
108*795d594fSAndroid Build Coastguard Worker         : mEnv(env), mJavaArray(nullptr), mRawArray(nullptr) {} \
109*795d594fSAndroid Build Coastguard Worker         Scoped ## NAME ## ArrayRW(JNIEnv* env, PRIMITIVE_TYPE ## Array javaArray) \
110*795d594fSAndroid Build Coastguard Worker         : mEnv(env), mJavaArray(javaArray), mRawArray(nullptr) { \
111*795d594fSAndroid Build Coastguard Worker             if (mJavaArray == nullptr) { \
112*795d594fSAndroid Build Coastguard Worker                 JniThrowNullPointerException(env, nullptr); \
113*795d594fSAndroid Build Coastguard Worker             } else { \
114*795d594fSAndroid Build Coastguard Worker                 mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, nullptr); \
115*795d594fSAndroid Build Coastguard Worker             } \
116*795d594fSAndroid Build Coastguard Worker         } \
117*795d594fSAndroid Build Coastguard Worker         ~Scoped ## NAME ## ArrayRW() { \
118*795d594fSAndroid Build Coastguard Worker             if (mRawArray) { \
119*795d594fSAndroid Build Coastguard Worker                 mEnv->Release ## NAME ## ArrayElements(mJavaArray, mRawArray, 0); \
120*795d594fSAndroid Build Coastguard Worker             } \
121*795d594fSAndroid Build Coastguard Worker         } \
122*795d594fSAndroid Build Coastguard Worker         void reset(PRIMITIVE_TYPE ## Array javaArray) { \
123*795d594fSAndroid Build Coastguard Worker             mJavaArray = javaArray; \
124*795d594fSAndroid Build Coastguard Worker             mRawArray = mEnv->Get ## NAME ## ArrayElements(mJavaArray, nullptr); \
125*795d594fSAndroid Build Coastguard Worker         } \
126*795d594fSAndroid Build Coastguard Worker         const PRIMITIVE_TYPE* get() const { return mRawArray; } \
127*795d594fSAndroid Build Coastguard Worker         PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
128*795d594fSAndroid Build Coastguard Worker         const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
129*795d594fSAndroid Build Coastguard Worker         POINTER_TYPE(PRIMITIVE_TYPE) get() { return mRawArray; }  \
130*795d594fSAndroid Build Coastguard Worker         REFERENCE_TYPE(PRIMITIVE_TYPE) operator[](size_t n) { return mRawArray[n]; } \
131*795d594fSAndroid Build Coastguard Worker         size_t size() const { return mEnv->GetArrayLength(mJavaArray); } \
132*795d594fSAndroid Build Coastguard Worker      private: \
133*795d594fSAndroid Build Coastguard Worker         JNIEnv* const mEnv; \
134*795d594fSAndroid Build Coastguard Worker         PRIMITIVE_TYPE ## Array mJavaArray; \
135*795d594fSAndroid Build Coastguard Worker         POINTER_TYPE(PRIMITIVE_TYPE) mRawArray; \
136*795d594fSAndroid Build Coastguard Worker         DISALLOW_COPY_AND_ASSIGN(Scoped ## NAME ## ArrayRW); \
137*795d594fSAndroid Build Coastguard Worker     }
138*795d594fSAndroid Build Coastguard Worker 
139*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jboolean, Boolean);
140*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jbyte, Byte);
141*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jchar, Char);
142*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jdouble, Double);
143*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jfloat, Float);
144*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jint, Int);
145*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jlong, Long);
146*795d594fSAndroid Build Coastguard Worker INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW(jshort, Short);
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker #undef INSTANTIATE_SCOPED_PRIMITIVE_ARRAY_RW
149*795d594fSAndroid Build Coastguard Worker #undef POINTER_TYPE
150*795d594fSAndroid Build Coastguard Worker #undef REFERENCE_TYPE
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker }  // namespace art
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker #endif  // ART_TEST_TI_AGENT_SCOPED_PRIMITIVE_ARRAY_H_
155