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 SCOPED_LOCAL_REF_H_ 18 #define SCOPED_LOCAL_REF_H_ 19 20 #include <cstddef> 21 22 #include "jni.h" 23 #include "nativehelper_utils.h" 24 25 // A smart pointer that deletes a JNI local reference when it goes out of scope. 26 template <typename T> 27 class ScopedLocalRef { 28 public: ScopedLocalRef(JNIEnv * env,T localRef)29 ScopedLocalRef(JNIEnv* env, T localRef) : mEnv(env), mLocalRef(localRef) {} 30 ~ScopedLocalRef()31 ~ScopedLocalRef() { reset(); } 32 33 void reset(T ptr = NULL) { 34 if (ptr != mLocalRef) { 35 if (mLocalRef != NULL) { 36 mEnv->DeleteLocalRef(mLocalRef); 37 } 38 mLocalRef = ptr; 39 } 40 } 41 release()42 T release() __attribute__((warn_unused_result)) { 43 T localRef = mLocalRef; 44 mLocalRef = NULL; 45 return localRef; 46 } 47 get()48 T get() const { return mLocalRef; } 49 50 // Some better C++11 support. 51 #if __cplusplus >= 201103L 52 // Move constructor. ScopedLocalRef(ScopedLocalRef && s)53 ScopedLocalRef(ScopedLocalRef&& s) : mEnv(s.mEnv), mLocalRef(s.release()) {} 54 ScopedLocalRef(JNIEnv * env)55 explicit ScopedLocalRef(JNIEnv* env) : mEnv(env), mLocalRef(nullptr) {} 56 57 // We do not expose an empty constructor as it can easily lead to errors 58 // using common idioms, e.g.: 59 // ScopedLocalRef<...> ref; 60 // ref.reset(...); 61 62 // Move assignment operator. 63 ScopedLocalRef& operator=(ScopedLocalRef&& s) { 64 reset(s.release()); 65 mEnv = s.mEnv; 66 return *this; 67 } 68 69 // Allows "if (scoped_ref == nullptr)" 70 bool operator==(std::nullptr_t) const { return mLocalRef == nullptr; } 71 72 // Allows "if (scoped_ref != nullptr)" 73 bool operator!=(std::nullptr_t) const { return mLocalRef != nullptr; } 74 #endif 75 76 private: 77 JNIEnv* mEnv; 78 T mLocalRef; 79 80 DISALLOW_COPY_AND_ASSIGN(ScopedLocalRef); 81 }; 82 83 #endif // SCOPED_LOCAL_REF_H_ 84