diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index e6605568ce..0948ce6574 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -56,6 +56,7 @@ if (is_ios || is_mac) { "objc/Framework/Classes/Common/RTCUIApplicationStatusObserver.m", "objc/Framework/Classes/Common/helpers.h", "objc/Framework/Classes/Common/helpers.mm", + "objc/Framework/Classes/Common/scoped_cftyperef.h", "objc/Framework/Headers/WebRTC/RTCDispatcher.h", "objc/Framework/Headers/WebRTC/RTCFieldTrials.h", "objc/Framework/Headers/WebRTC/RTCLogging.h", diff --git a/sdk/objc/Framework/Classes/Common/scoped_cftyperef.h b/sdk/objc/Framework/Classes/Common/scoped_cftyperef.h new file mode 100644 index 0000000000..cde7a9069c --- /dev/null +++ b/sdk/objc/Framework/Classes/Common/scoped_cftyperef.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + * + */ + +#ifndef WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_SCOPED_CFTYPEREF_H_ +#define WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_SCOPED_CFTYPEREF_H_ + +#include +namespace rtc { + +template +class ScopedCFTypeRef { + public: + // RETAIN: ScopedCFTypeRef should retain the object when it takes + // ownership. + // ASSUME: Assume the object already has already been retained. + // ScopedCFTypeRef takes over ownership. + enum class RetainPolicy { RETAIN, ASSUME }; + + ScopedCFTypeRef() : ptr_(nullptr) {} + explicit ScopedCFTypeRef(T ptr) : ptr_(ptr) {} + ScopedCFTypeRef(T ptr, RetainPolicy policy) : ScopedCFTypeRef(ptr) { + if (ptr_ && policy == RetainPolicy::RETAIN) + CFRetain(ptr_); + } + + ~ScopedCFTypeRef() { + if (ptr_) { + CFRelease(ptr_); + } + } + + T get() const { return ptr_; } + T operator->() const { return ptr_; } + explicit operator bool() const { return ptr_; } + + bool operator!() const { return !ptr_; } + + ScopedCFTypeRef& operator=(const T& rhs) { + if (ptr_) + CFRelease(ptr_); + ptr_ = rhs; + return *this; + } + + ScopedCFTypeRef& operator=(const ScopedCFTypeRef& rhs) { + reset(rhs.get(), RetainPolicy::RETAIN); + return *this; + } + + // This is intended to take ownership of objects that are + // created by pass-by-pointer initializers. + T* InitializeInto() { + RTC_DCHECK(!ptr_); + return &ptr_; + } + + void reset(T ptr, RetainPolicy policy = RetainPolicy::ASSUME) { + if (ptr && policy == RetainPolicy::RETAIN) + CFRetain(ptr); + if (ptr_) + CFRelease(ptr_); + ptr_ = ptr; + } + + T release() { + T temp = ptr_; + ptr_ = nullptr; + return temp; + } + + private: + T ptr_; +}; + +template +static ScopedCFTypeRef AdoptCF(T cftype) { + return ScopedCFTypeRef(cftype, RetainPolicy::RETAIN); +} + +template +static ScopedCFTypeRef ScopedCF(T cftype) { + return ScopedCFTypeRef(cftype); +} + +} // namespace rtc + +#endif // WEBRTC_SDK_OBJC_FRAMEWORK_CLASSES_COMMON_SCOPED_CFTYPEREF_H_