//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1995 - 2000 // // File: pmalloc.hxx // // Contents: Memory allocation classes derived from PMemoryAllocator // // Classes: CCoTaskMemAllocator, CNonAlignAllocator // // History: 01 May-1998 AlanW Created from proprec.cxx // //---------------------------------------------------------------------------- #pragma once //+------------------------------------------------------------------------- // // Class: CCoTaskMemAllocator // // Purpose: A PMemoryAllocator implementation that uses OLE memory // //+------------------------------------------------------------------------- class CCoTaskMemAllocator : public PMemoryAllocator { public: void *Allocate(ULONG cbSize) { return CoTaskMemAlloc( cbSize ); } void Free(void *pv) { CoTaskMemFree( pv ); } }; //+------------------------------------------------------------------------- // // Class: CNonAlignAllocator // // Purpose: A PMemoryAllocator implementation that uses a memory buffer // //+------------------------------------------------------------------------- class CNonAlignAllocator : public PMemoryAllocator { public: inline CNonAlignAllocator(ULONG cbBuffer, VOID *pvBuffer) { _cbFree = cbBuffer; _pvCur = _pvBuffer = pvBuffer; } VOID *Allocate(ULONG cb) { VOID *pv; cb = (cb + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1); if (cb > _cbFree) { return NULL; } pv = _pvCur; _pvCur = (BYTE *) _pvCur + cb; _cbFree -= cb; return pv; } VOID Free(VOID *pv) { } inline ULONG GetFreeSize(VOID) { return _cbFree; } private: ULONG _cbFree; VOID *_pvCur; VOID *_pvBuffer; }; //+------------------------------------------------------------------------- // // Class: PVarAllocator // // Purpose: Base class for vaiable data allocator // //-------------------------------------------------------------------------- class PVarAllocator : public PMemoryAllocator { public: // PMemoryAllocator methods: // Allocate a piece of memory. //virtual PVOID Allocate(size_t cbNeeded) = 0; // // Free a previously allocated piece of memory. //virtual void Free(PVOID pMem) = 0; // Return whether OffsetToPointer has non-null effect virtual BOOL IsBasedMemory(void) { return FALSE; } ; // Convert a pointer offset to a pointer. virtual PVOID OffsetToPointer(ULONG_PTR oBuf) { return (PVOID) oBuf; } // Convert a pointer to a pointer offset. virtual ULONG_PTR PointerToOffset(PVOID pBuf) { return (ULONG_PTR) pBuf; } // Set base address for OffsetToPointer and PointerToOffset virtual void SetBase(BYTE* pbBase) {} // Allocate & Free memory for BSTRs virtual PVOID CopyBSTR(size_t cbNeeded, WCHAR* pwszBuf) { return ((BYTE*) CopyTo( cbNeeded + sizeof (DWORD) + sizeof (OLECHAR), ((BYTE *)pwszBuf) - sizeof (DWORD))) + sizeof (DWORD); } virtual PVOID AllocBSTR(size_t cbNeeded) { return ((BYTE*) Allocate( cbNeeded + sizeof (DWORD) + sizeof (OLECHAR))) + sizeof (DWORD); } virtual void FreeBSTR(PVOID pMem) { Free( ((BYTE *)pMem) - sizeof (DWORD) ); } // Copy data to newly allocated memory. PVOID CopyTo(size_t cbNeeded, BYTE* pbBuf) { void * pRetBuf = Allocate( cbNeeded ); Win4Assert( 0 != pRetBuf); RtlCopyMemory( pRetBuf, pbBuf, cbNeeded ); return pRetBuf; } }; //+------------------------------------------------------------------------- // // Class: CSafeArrayAllocator // // Purpose: Used for constructing safe arrays. // //-------------------------------------------------------------------------- class CSafeArrayAllocator : public PVarAllocator { public: CSafeArrayAllocator( PMemoryAllocator & ma ) : _ma( ma ) {} void * Allocate(ULONG cbSize) { return _ma.Allocate( cbSize ); } void Free(void *pv) { _ma.Free( pv ); } private: PMemoryAllocator & _ma; }; BOOL SaCreateAndCopy( PMemoryAllocator &ma, SAFEARRAY * psaSrc, SAFEARRAY **ppsaDest ); BOOL SaCreateData( PVarAllocator &ma, VARTYPE vt, SAFEARRAY & saSrc, SAFEARRAY & saDst, BOOL fAllocBstrUsingAllocator ); inline BOOL SaCreateDataUsingMA( PMemoryAllocator &ma, VARTYPE vt, SAFEARRAY & saSrc, SAFEARRAY & saDst, BOOL fAllocBstrUsingAllocator ) { CSafeArrayAllocator saa( ma ); return SaCreateData( saa, vt, saSrc, saDst, fAllocBstrUsingAllocator ); } ULONG SaComputeSize( VARTYPE vt, SAFEARRAY & saSrc ); inline unsigned SaCountElements( SAFEARRAY &saSrc ) { unsigned cDataElements = 1; // // get total data memory to allocate, and number of data elements in it. // for ( unsigned i = 0; i < saSrc.cDims; i++ ) cDataElements *= saSrc.rgsabound[i].cElements; return cDataElements; }