#pragma once #include "lhport.h" #include "pshpack8.h" class CPositionIndependentBlob; template class CFunction { public: union { T * pfn; ULONGLONG ull; }; }; typedef void (__stdcall * PFN_GROW_FUNCTION)(CPositionIndependentBlob * This); class CPositionIndependentOperatorNew { public: void * operator new(size_t n, CPositionIndependentBlob * Container); }; // // aka position independent heap, with support for persistance to disk // class CPositionIndependentBlob : public CPositionIndependentOperatorNew { public: //protected: void OutOfMemory(); public: static void ThrowWin32Error(DWORD); BOOL IsPagefileMapping(); union { ULONGLONG ll; CPositionIndependentBlob * m_Container; }; CPositionIndependentBlob(); ~CPositionIndependentBlob(); BOOL Write(HANDLE FileHandle, ULONGLONG Offset); BOOL Read(HANDLE FileHandle, ULONGLONG Offset); void GetBounds(const BYTE * Bounds[2]); void IsInBlob(const BYTE * Pointer, ULONG Size, BOOL * IsInBlob); class CBlock { public: CBlock() : m_Offset(0), m_Size(0) { } ULONG m_Offset; ULONG m_Size; bool operator==(const CBlock & x) const { if (this == &x) return true; if (m_Offset != x.m_Offset) return false; if (m_Size != x.m_Size) return false; return true; } typedef std::pair CPair; class CLessThanByOffset { public: bool operator()(const CBlock & x, const CBlock & y) const { return CPair(x.m_Offset, x.m_Size) < CPair(y.m_Offset, y.m_Size); } }; class CLessThanBySize { public: bool operator()(const CBlock & x, const CBlock & y) const { return CPair(x.m_Size, x.m_Offset) < CPair(y.m_Size, y.m_Offset); } }; static bool Neighbors(const CBlock & x, const CBlock & y) { if (y.m_Offset + y.m_Size == x.m_Offset) return true; if (x.m_Offset + x.m_Size == y.m_Offset) return true; return false; } bool Neighbors(const CBlock & x) const { return Neighbors(*this, x); } }; union { struct { ULONG m_HeaderSize; ULONG m_HeaderVersion; ULONG m_BitsInPointer; BYTE m_IsBigEndian; BYTE m_Spare1[3]; union { ULONGLONG ll; HANDLE m_FileHandle; }; union { ULONGLONG ll; HANDLE m_FileMapping; }; ULONGLONG m_FileOffset; union { ULONGLONG m_Base; PBYTE m_BasePointer; }; ULONG m_AllocatedSize; ULONG m_UsedSize; ULONG m_FreeSize; ULONG m_OffsetToFreeBlocks; ULONG m_NumberOfFreeBlocks; CBlock m_MostRecentlyFreedBlock; }; BYTE Page[0x2000]; }; typedef std::set CBlockByOffsetSet; typedef std::set CBlockBySizeSet; ULONG m_PendingFreeBySize; CBlockByOffsetSet m_FreeBlocksSortedByOffset; CBlockBySizeSet m_FreeBlocksSortedBySize; CBlockByOffsetSet m_InUseBlocksSortedByOffset; PBYTE GetBasePointer(); void Alloc(ULONG NumberOfBytes, ULONG * Offset); void Alloc(CPositionIndependentBlob * Container, ULONG NumberOfBytes, ULONG * Offset); void Free(const BYTE * Pointer); void Reserve(ULONG Bytes, ULONG Blocks) { /* UNDONE */ } void Grow(ULONG); void RecalculateBlocksBySize(); // protected void (CPositionIndependentBlob::*m_pmfCompact)(); void * OperatorNew(SIZE_T NumberOfBytes) { void * Pointer = 0; ULONG Offset = 0; Alloc(static_cast(NumberOfBytes), &Offset); OffsetToPointer(Offset, &Pointer); return Pointer; } //PBYTE OffsetToPointer(ULONG Offset) { return m_BasePointer + Offset; } //template void OffsetToPointer(ULONG Offset, T * & Pointer) { Pointer = reinterpret_cast(m_Base + static_cast(Offset)); } template void OffsetToPointer(ULONG Offset, T * * Pointer) { *Pointer = reinterpret_cast(m_Base + static_cast(Offset)); } template ULONG PointerToOffset(const T * Pointer) { return static_cast(reinterpret_cast(Pointer) - m_BasePointer); } }; #include "poppack.h"