1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 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 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /* -*- c++ -*- */ 19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 20 21 // O S C L _ M E M _ A U T O _ P T R 22 23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 24 25 /*! \addtogroup osclmemory OSCL Memory 26 * 27 * @{ 28 */ 29 30 31 /** 32 * @file oscl_mem_auto_ptr.h 33 * @brief This file defines the oscl_mem_auto_ptr template class. This class is 34 * used to avoid any potential memory leaks that may arise while returning 35 * from methods in case of error. 36 * 37 */ 38 39 #ifndef OSCL_MEM_AUTO_PTR_H 40 #define OSCL_MEM_AUTO_PTR_H 41 42 #ifndef OSCLCONFIG_MEMORY_H_INCLUDED 43 #include "osclconfig_memory.h" 44 #endif 45 46 #ifndef OSCL_MEM_H_INCLUDED 47 #include "oscl_mem.h" 48 #endif 49 50 #define OSCL_DISABLE_WARNING_TRUNCATE_DEBUG_MESSAGE 51 #define OSCL_DISABLE_WARNING_RETURN_TYPE_NOT_UDT 52 #include "osclconfig_compiler_warnings.h" 53 /** 54 * @brief The oscl_auto_ptr class is a template class that defines a pointer 55 * like object intended to be assigned an address obtanined (directly or 56 * or indirectly) by new. When the oscl_auto_ptr expires, its destructor 57 * uses delete to free the memory. 58 * 59 * The purpose of this class is to provide a way to prevent accidental memory 60 * leaks in a class or a method, due to "not remembering to delete" variables 61 * allocated on the heap. Thus if you assign an address returned by new to an 62 * oscl_auto_ptr object, you don't have to remember to free the memory later, 63 * it will be freed automatically when the object goes out of scope. 64 * The oscl_auto_ptr is an example of a smart pointer, an object that acts like 65 * a pointer, but with additional features. The class is defined so that it acts 66 * like a regular pointer in most respects 67 * 68 */ 69 70 template < class T, class _Allocator = Oscl_TAlloc<T, OsclMemAllocator> > class OSCLMemAutoPtr 71 { 72 private: 73 T* _Ptr; 74 75 76 public: 77 bool _Ownership; 78 79 80 /** 81 * @brief Default constructor 82 * Initializes the pointer and takes ownership. 83 */ _Ptr(inPtr)84 explicit OSCLMemAutoPtr(T* inPtr = 0) : _Ptr(inPtr), _Ownership(inPtr != 0) {}; 85 86 /** 87 * @brief Copy constructor 88 * 89 * Initializes the pointer and takes ownership from another oscl_auto_ptr. 90 * Note that the other class does NOT own the pointer any longer, and 91 * hence it is NOT its responsibility to free it. 92 */ OSCLMemAutoPtr(const OSCLMemAutoPtr<T> & _Y)93 OSCLMemAutoPtr(const OSCLMemAutoPtr<T>& _Y): _Ownership(_Y._Ownership), 94 _Ptr(_Y.release()) {}; 95 96 97 /** 98 * @brief Assignment operator from an another oscl_auto_ptr 99 * 100 * @param _Y The value parameter should be another oscl_auto_ptr 101 * @returns Returns a reference to this oscl_auto_ptr instance with 102 * pointer initialized. 103 * @pre The input class should be non-null and should point to 104 * a valid pointer. 105 * 106 * This assignment operator initializes the class to the contents 107 * of the oscl_auto_ptr given as the input parameter. The ownership 108 * of the pointer is transferred. 109 */ 110 OSCLMemAutoPtr<T, _Allocator>& operator=(const OSCLMemAutoPtr<T, _Allocator>& _Y) 111 { 112 if (this != &_Y) 113 { 114 if (_Ptr != _Y.get()) 115 { 116 if (_Ownership) 117 { 118 _Allocator alloc; 119 alloc.destroy(_Ptr); 120 alloc.deallocate(_Ptr, 1); 121 } 122 _Ownership = _Y._Ownership; 123 } 124 else if (_Y._Ownership) 125 { 126 _Ownership = true; 127 } 128 _Ptr = _Y.release(); 129 } 130 return (*this); 131 } 132 133 /** 134 * @brief Destructor 135 * 136 * The pointer is deleted in case this class still has ownership 137 */ ~OSCLMemAutoPtr()138 ~OSCLMemAutoPtr() 139 { 140 if (_Ownership) 141 { 142 _Allocator alloc; 143 alloc.destroy(_Ptr); 144 alloc.deallocate(_Ptr, 1); 145 } 146 } 147 148 /** 149 * @brief The indirection operator (*) accesses a value indirectly, 150 * through a pointer 151 * 152 * This operator ensures that the OSCLMemAutoPtr can be used like the 153 * regular pointer that it was initialized with. 154 */ 155 T& operator*() const 156 { 157 return (*get()); 158 } 159 160 /** 161 * @brief The indirection operator (->) accesses a value indirectly, 162 * through a pointer 163 * 164 * This operator ensures that the OSCLMemAutoPtr can be used like the 165 * regular pointer that it was initialized with. 166 */ 167 T *operator->() const 168 { 169 return (get()); 170 } 171 172 173 /** 174 * @brief The takeOwnership function assigns the value with ownership. 175 * 176 * 177 */ takeOwnership(T * ptr)178 void takeOwnership(T* ptr) 179 { 180 if (_Ptr != ptr) 181 { 182 if (_Ownership) 183 { 184 _Allocator alloc; 185 alloc.destroy(_Ptr); 186 alloc.deallocate(_Ptr, 1); 187 } 188 _Ptr = ptr; 189 } 190 191 if (_Ptr) 192 { 193 _Ownership = true; 194 } 195 } 196 deallocate(T * ptr)197 static void deallocate(T* ptr) 198 { 199 _Allocator alloc; 200 alloc.destroy(ptr); 201 alloc.deallocate(ptr, 1); 202 } 203 allocate(oscl_memsize_t size)204 void allocate(oscl_memsize_t size) 205 { 206 _Allocator alloc; 207 if (_Ptr && _Ownership) 208 { 209 alloc.destroy(_Ptr); 210 alloc.deallocate(_Ptr, 1); 211 } 212 _Ptr = alloc.ALLOCATE(size); 213 _Ownership = true; 214 } 215 216 /** 217 * @brief The takeOwnership function assigns the value with ownership. 218 * 219 * 220 */ setWithoutOwnership(T * ptr)221 void setWithoutOwnership(T* ptr) 222 { 223 if (_Ptr != ptr) 224 { 225 if (_Ownership) 226 { 227 _Allocator alloc; 228 alloc.destroy(_Ptr); 229 alloc.deallocate(_Ptr, 1); 230 } 231 _Ptr = ptr; 232 } 233 234 _Ownership = false; 235 } 236 237 /** 238 * @brief get() method returns the pointer, currently owned by the class. 239 * 240 */ get()241 T *get() const 242 { 243 return (_Ptr); 244 } 245 246 /** 247 * @brief release() method releases ownership of the pointer, currently owned 248 * by the class. It returns the pointer as well. 249 * 250 */ release()251 T *release() const 252 { 253 ((OSCLMemAutoPtr<T> *)this)->_Ownership = false; 254 return (_Ptr); 255 } 256 257 }; 258 259 #endif //OSCL_MEM_AUTO_PTR_H 260 261 /*! @} */ 262