Index: lib/atl/atlalloc.h =================================================================== --- lib/atl/atlalloc.h (revision 0) +++ lib/atl/atlalloc.h (working copy) @@ -0,0 +1,179 @@ +/* + * ReactOS ATL + * + * Copyright 2009 Andrew Hill + * Copyright 2016 Mark Jansen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +class CCRTAllocator +{ +public: + static void* Allocate(_In_ size_t size) + { + return malloc(size); + } + + static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) + { + return realloc(ptr, size); + } + + static void Free(_In_opt_ void* ptr) + { + free(ptr); + } +}; + +class CLocalAllocator +{ +public: + static void* Allocate(_In_ size_t size) + { + return ::LocalAlloc(LMEM_FIXED, size); + } + + static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) + { + if (!ptr) + return Allocate(size); + if (size == 0) + { + Free(ptr); + return NULL; + } + return ::LocalReAlloc(ptr, size, 0); + } + + static void Free(_In_opt_ void* ptr) + { + ::LocalFree(ptr); + } +}; + +class CGlobalAllocator +{ +public: + static void* Allocate(_In_ size_t size) + { + return ::GlobalAlloc(GMEM_FIXED, size); + } + + static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) + { + if (!ptr) + return Allocate(size); + if (size == 0) + { + Free(ptr); + return NULL; + } + return ::GlobalReAlloc(ptr, size, 0); + } + + static void Free(_In_opt_ void* ptr) + { + GlobalFree(ptr); + } +}; + + +template +class CHeapPtr +{ +public: + CHeapPtr() : + m_Data(NULL) + { + } + + explicit CHeapPtr(T *lp) : + m_Data(lp) + { + } + + explicit CHeapPtr(CHeapPtr &lp) + { + m_Data = lp.Detach(); + } + + ~CHeapPtr() + { + Free(); + } + + CHeapPtr& operator = (CHeapPtr &lp) + { + if (lp.m_Data != m_Data) + Attach(lp.Detach()); + return *this; + } + + bool Allocate(size_t nElements = 1) + { + ATLASSERT(m_Data == NULL); + m_Data = static_cast(Allocator::Allocate(nElements * sizeof(T))); + return m_Data != NULL; + } + + bool Reallocate(_In_ size_t nElements) + { + T* newData = static_cast(Allocator::Reallocate(m_Data, nElements * sizeof(T))); + if (newData == NULL) + return false; + m_Data = newData; + return true; + } + + void Free() + { + if (m_Data) + { + Allocator::Free(m_Data); + m_Data = NULL; + } + } + + void Attach(T *lp) + { + Allocator::Free(m_Data); + m_Data = lp; + } + + T *Detach() + { + T *saveP = m_Data; + m_Data = NULL; + return saveP; + } + + T **operator &() + { + ATLASSERT(m_Data == NULL); + return &m_Data; + } + + operator T* () const + { + return m_Data; + } + +protected: + T *m_Data; +}; + Index: lib/atl/atlbase.h =================================================================== --- lib/atl/atlbase.h (revision 70788) +++ lib/atl/atlbase.h (working copy) @@ -23,6 +23,7 @@ #include "atlcore.h" #include "statreg.h" #include "atlcomcli.h" +#include "atlalloc.h" #ifdef _MSC_VER // It is common to use this in ATL constructors. They only store this for later use, so the usage is safe. @@ -817,91 +818,38 @@ extern CAtlWinModule _AtlWinModule; - -// TODO: When someone needs it, make the allocator a template, so you can use it for both -// CoTask* allocations, and CRT-like allocations (malloc, realloc, free) -template -class CComHeapPtr +class CComAllocator { public: - CComHeapPtr() : - m_Data(NULL) + static void* Allocate(_In_ size_t size) { + return ::CoTaskMemAlloc(size); } - explicit CComHeapPtr(T *lp) : - m_Data(lp) + static void* Reallocate(_In_opt_ void* ptr, _In_ size_t size) { + return ::CoTaskMemRealloc(ptr, size); } - explicit CComHeapPtr(CComHeapPtr &lp) + static void Free(_In_opt_ void* ptr) { - m_Data = lp.Detach(); + ::CoTaskMemFree(ptr); } +}; - ~CComHeapPtr() - { - Release(); - } - T *operator = (CComHeapPtr &lp) +template +class CComHeapPtr : public CHeapPtr +{ +public: + CComHeapPtr() { - if (lp.m_Data != m_Data) - Attach(lp.Detach()); - return *this; } - bool Allocate(size_t nElements = 1) + explicit CComHeapPtr(T *lp) : + CHeapPtr(lp) { - ATLASSERT(m_Data == NULL); - m_Data = static_cast(::CoTaskMemAlloc(nElements * sizeof(T))); - return m_Data != NULL; } - - bool Reallocate(_In_ size_t nElements) - { - T* newData = static_cast(::CoTaskMemRealloc(m_Data, nElements * sizeof(T))); - if (newData == NULL) - return false; - m_Data = newData; - return true; - } - - void Release() - { - if (m_Data) - { - ::CoTaskMemFree(m_Data); - m_Data = NULL; - } - } - - void Attach(T *lp) - { - Release(); - m_Data = lp; - } - - T *Detach() - { - T *saveP = m_Data; - m_Data = NULL; - return saveP; - } - - T **operator &() - { - ATLASSERT(m_Data == NULL); - return &m_Data; - } - - operator T* () const - { - return m_Data; - } - -protected: - T *m_Data; };