1c2c66affSColin Finck /* 2c2c66affSColin Finck * ReactOS ATL 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 2009 Andrew Hill <ash77@reactos.org> 5c2c66affSColin Finck * Copyright 2016 Mark Jansen 6c2c66affSColin Finck * 7c2c66affSColin Finck * This library is free software; you can redistribute it and/or 8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 9c2c66affSColin Finck * License as published by the Free Software Foundation; either 10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 11c2c66affSColin Finck * 12c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15c2c66affSColin Finck * Lesser General Public License for more details. 16c2c66affSColin Finck * 17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 18c2c66affSColin Finck * License along with this library; if not, write to the Free Software 19c2c66affSColin Finck * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20c2c66affSColin Finck */ 21c2c66affSColin Finck 22c2c66affSColin Finck #pragma once 23c2c66affSColin Finck 24c2c66affSColin Finck class CCRTAllocator 25c2c66affSColin Finck { 26c2c66affSColin Finck public: Allocate(_In_ size_t size)27c2c66affSColin Finck static void* Allocate(_In_ size_t size) 28c2c66affSColin Finck { 29c2c66affSColin Finck return malloc(size); 30c2c66affSColin Finck } 31c2c66affSColin Finck Reallocate(_In_opt_ void * ptr,_In_ size_t size)32c2c66affSColin Finck static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) 33c2c66affSColin Finck { 34c2c66affSColin Finck return realloc(ptr, size); 35c2c66affSColin Finck } 36c2c66affSColin Finck Free(_In_opt_ void * ptr)37c2c66affSColin Finck static void Free(_In_opt_ void* ptr) 38c2c66affSColin Finck { 39c2c66affSColin Finck free(ptr); 40c2c66affSColin Finck } 41c2c66affSColin Finck }; 42c2c66affSColin Finck 43c2c66affSColin Finck class CLocalAllocator 44c2c66affSColin Finck { 45c2c66affSColin Finck public: Allocate(_In_ size_t size)46c2c66affSColin Finck static void* Allocate(_In_ size_t size) 47c2c66affSColin Finck { 48c2c66affSColin Finck return ::LocalAlloc(LMEM_FIXED, size); 49c2c66affSColin Finck } 50c2c66affSColin Finck Reallocate(_In_opt_ void * ptr,_In_ size_t size)51c2c66affSColin Finck static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) 52c2c66affSColin Finck { 53c2c66affSColin Finck if (!ptr) 54c2c66affSColin Finck return Allocate(size); 55c2c66affSColin Finck if (size == 0) 56c2c66affSColin Finck { 57c2c66affSColin Finck Free(ptr); 58c2c66affSColin Finck return NULL; 59c2c66affSColin Finck } 60c2c66affSColin Finck return ::LocalReAlloc(ptr, size, 0); 61c2c66affSColin Finck } 62c2c66affSColin Finck Free(_In_opt_ void * ptr)63c2c66affSColin Finck static void Free(_In_opt_ void* ptr) 64c2c66affSColin Finck { 65c2c66affSColin Finck ::LocalFree(ptr); 66c2c66affSColin Finck } 67c2c66affSColin Finck }; 68c2c66affSColin Finck 69c2c66affSColin Finck class CGlobalAllocator 70c2c66affSColin Finck { 71c2c66affSColin Finck public: Allocate(_In_ size_t size)72c2c66affSColin Finck static void* Allocate(_In_ size_t size) 73c2c66affSColin Finck { 74c2c66affSColin Finck return ::GlobalAlloc(GMEM_FIXED, size); 75c2c66affSColin Finck } 76c2c66affSColin Finck Reallocate(_In_opt_ void * ptr,_In_ size_t size)77c2c66affSColin Finck static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) 78c2c66affSColin Finck { 79c2c66affSColin Finck if (!ptr) 80c2c66affSColin Finck return Allocate(size); 81c2c66affSColin Finck if (size == 0) 82c2c66affSColin Finck { 83c2c66affSColin Finck Free(ptr); 84c2c66affSColin Finck return NULL; 85c2c66affSColin Finck } 86c2c66affSColin Finck return ::GlobalReAlloc(ptr, size, 0); 87c2c66affSColin Finck } 88c2c66affSColin Finck Free(_In_opt_ void * ptr)89c2c66affSColin Finck static void Free(_In_opt_ void* ptr) 90c2c66affSColin Finck { 91c2c66affSColin Finck GlobalFree(ptr); 92c2c66affSColin Finck } 93c2c66affSColin Finck }; 94c2c66affSColin Finck 95c2c66affSColin Finck 96c2c66affSColin Finck template<class T, class Allocator = CCRTAllocator> 97c2c66affSColin Finck class CHeapPtr 98c2c66affSColin Finck { 99c2c66affSColin Finck public: CHeapPtr()100c2c66affSColin Finck CHeapPtr() : 101*45d33582SMark Jansen m_pData(NULL) 102c2c66affSColin Finck { 103c2c66affSColin Finck } 104c2c66affSColin Finck CHeapPtr(T * lp)105c2c66affSColin Finck explicit CHeapPtr(T *lp) : 106*45d33582SMark Jansen m_pData(lp) 107c2c66affSColin Finck { 108c2c66affSColin Finck } 109c2c66affSColin Finck CHeapPtr(CHeapPtr<T,Allocator> & lp)110c2c66affSColin Finck explicit CHeapPtr(CHeapPtr<T, Allocator> &lp) 111c2c66affSColin Finck { 112*45d33582SMark Jansen m_pData = lp.Detach(); 113c2c66affSColin Finck } 114c2c66affSColin Finck ~CHeapPtr()115c2c66affSColin Finck ~CHeapPtr() 116c2c66affSColin Finck { 117c2c66affSColin Finck Free(); 118c2c66affSColin Finck } 119c2c66affSColin Finck 120c2c66affSColin Finck CHeapPtr<T, Allocator>& operator = (CHeapPtr<T, Allocator> &lp) 121c2c66affSColin Finck { 122*45d33582SMark Jansen if (lp.m_pData != m_pData) 123c2c66affSColin Finck Attach(lp.Detach()); 124c2c66affSColin Finck return *this; 125c2c66affSColin Finck } 126c2c66affSColin Finck AllocateBytes(_In_ size_t nBytes)127c2c66affSColin Finck bool AllocateBytes(_In_ size_t nBytes) 128c2c66affSColin Finck { 129*45d33582SMark Jansen ATLASSERT(m_pData == NULL); 130*45d33582SMark Jansen m_pData = static_cast<T*>(Allocator::Allocate(nBytes)); 131*45d33582SMark Jansen return m_pData != NULL; 132c2c66affSColin Finck } 133c2c66affSColin Finck ReallocateBytes(_In_ size_t nBytes)134c2c66affSColin Finck bool ReallocateBytes(_In_ size_t nBytes) 135c2c66affSColin Finck { 136*45d33582SMark Jansen T* newData = static_cast<T*>(Allocator::Reallocate(m_pData, nBytes)); 137c2c66affSColin Finck if (newData == NULL) 138c2c66affSColin Finck return false; 139*45d33582SMark Jansen m_pData = newData; 140c2c66affSColin Finck return true; 141c2c66affSColin Finck } 142c2c66affSColin Finck 143c2c66affSColin Finck bool Allocate(_In_ size_t nElements = 1) 144c2c66affSColin Finck { 145c2c66affSColin Finck return AllocateBytes(nElements * sizeof(T)); 146c2c66affSColin Finck } 147c2c66affSColin Finck Reallocate(_In_ size_t nElements)148c2c66affSColin Finck bool Reallocate(_In_ size_t nElements) 149c2c66affSColin Finck { 150c2c66affSColin Finck return ReallocateBytes(nElements * sizeof(T)); 151c2c66affSColin Finck } 152c2c66affSColin Finck Free()153c2c66affSColin Finck void Free() 154c2c66affSColin Finck { 155*45d33582SMark Jansen if (m_pData) 156c2c66affSColin Finck { 157*45d33582SMark Jansen Allocator::Free(m_pData); 158*45d33582SMark Jansen m_pData = NULL; 159c2c66affSColin Finck } 160c2c66affSColin Finck } 161c2c66affSColin Finck Attach(T * lp)162c2c66affSColin Finck void Attach(T *lp) 163c2c66affSColin Finck { 164*45d33582SMark Jansen Allocator::Free(m_pData); 165*45d33582SMark Jansen m_pData = lp; 166c2c66affSColin Finck } 167c2c66affSColin Finck Detach()168c2c66affSColin Finck T *Detach() 169c2c66affSColin Finck { 170*45d33582SMark Jansen T *saveP = m_pData; 171*45d33582SMark Jansen m_pData = NULL; 172c2c66affSColin Finck return saveP; 173c2c66affSColin Finck } 174c2c66affSColin Finck 175c2c66affSColin Finck T **operator &() 176c2c66affSColin Finck { 177*45d33582SMark Jansen ATLASSERT(m_pData == NULL); 178*45d33582SMark Jansen return &m_pData; 179c2c66affSColin Finck } 180c2c66affSColin Finck 181c2c66affSColin Finck operator T* () const 182c2c66affSColin Finck { 183*45d33582SMark Jansen return m_pData; 184c2c66affSColin Finck } 185c2c66affSColin Finck 186c2c66affSColin Finck T* operator->() const 187c2c66affSColin Finck { 188*45d33582SMark Jansen return m_pData; 189c2c66affSColin Finck } 190c2c66affSColin Finck 191*45d33582SMark Jansen public: 192*45d33582SMark Jansen T *m_pData; 193c2c66affSColin Finck }; 194c2c66affSColin Finck 195