XTPCustomHeap.h
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:41k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPCustomHeap.h: *** template definition.
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. //{{AFX_CODEJOCK_PRIVATE
  21. #if !defined(_XTPCUSTOMHEAP_H__)
  22. #define _XTPCUSTOMHEAP_H__
  23. #if _MSC_VER > 1000
  24. #pragma once
  25. #endif // _MSC_VER > 1000
  26. //}}AFX_CODEJOCK_PRIVATE
  27. #include "XTPVC80Helpers.h"
  28. //{{AFX_CODEJOCK_PRIVATE
  29. #define XTP_EXPORT_PARAMS_NO
  30. typedef enum _XTP_HEAP_INFORMATION_CLASS
  31. {
  32. xtpHeapCompatibilityInformation
  33. }
  34. XTP_HEAP_INFORMATION_CLASS;
  35. //}}AFX_CODEJOCK_PRIVATE
  36. //===========================================================================
  37. // Summary:
  38. //      This function enables features for a specified heap.
  39. // Parameters:
  40. //      hHeapHandle   - [in] Handle to the heap where information is to be set.
  41. //                    This handle is returned by either the HeapCreate or
  42. //                    GetProcessHeap function.
  43. //
  44. //      pHeapInformation - [in] Heap information buffer. The format of this data
  45. //                         depends on the HeapCompatibilityInformation class.
  46. //
  47. //      nHeapInformationLength - [in] Size of the pHeapInformation buffer, in bytes.
  48. // Remarks:
  49. //      This function is a wrapper to HeapSetInformation windows API function.
  50. //      If HeapSetInformation is not supported by windows, this function exits
  51. //      without any actions.
  52. // Returns:
  53. //      If the function succeeds, the return value is nonzero
  54. //      If the function fails, the return value is 0 (zero). To get extended
  55. //      error information, call GetLastError.
  56. //      If HeapSetInformation is not supported by windows return value is also TRUE.
  57. // See Also:
  58. //      HeapSetInformation, XTPHeapSetLowFragmentation
  59. //===========================================================================
  60. AFX_INLINE BOOL XTPHeapSetCompatibilityInformation(HANDLE hHeapHandle, PVOID pHeapInformation, ULONG_PTR nHeapInformationLength)
  61. {
  62. typedef BOOL (WINAPI *PFNHEAPSETINFORMATION)(HANDLE HeapHandle, XTP_HEAP_INFORMATION_CLASS eHICls, PVOID HeapInformation, ULONG_PTR HeapInformationLength);
  63. HMODULE hKernel = ::GetModuleHandle(_T("KERNEL32.DLL"));
  64. ASSERT(hKernel);
  65. if (hKernel)
  66. {
  67. PFNHEAPSETINFORMATION pfHeapSetInformation = (PFNHEAPSETINFORMATION)::GetProcAddress(hKernel, "HeapSetInformation");
  68. if (pfHeapSetInformation)
  69. {
  70. return pfHeapSetInformation(hHeapHandle, xtpHeapCompatibilityInformation,
  71.  pHeapInformation, nHeapInformationLength);
  72. }
  73. }
  74. return TRUE; // not supported;
  75. }
  76. //===========================================================================
  77. // Summary:
  78. //      Call this member to enable "Low-fragmentation Heap" (LFH) feature for
  79. //      a given heap.
  80. // Parameters:
  81. //      hHeapHandle   - [in] Handle to the heap where information is to be set.
  82. //                    This handle is returned by either the HeapCreate or
  83. //                    GetProcessHeap function.
  84. // Remarks:
  85. //      This function is a wrapper to HeapSetInformation windows API function.
  86. //      If HeapSetInformation is not supported by windows, this function exits
  87. //      without any actions.
  88. // Returns:
  89. //      If the function succeeds, the return value is nonzero
  90. //      If the function fails, the return value is 0 (zero). To get extended
  91. //      error information, call GetLastError.
  92. //      If HeapSetInformation is not supported by windows return value is also TRUE.
  93. // See Also:
  94. //      HeapSetInformation, XTPHeapSetCompatibilityInformation
  95. //===========================================================================
  96. AFX_INLINE BOOL XTPHeapSetLowFragmentation(HANDLE hHeapHandle)
  97. {
  98. // LFH mode does not enabled under debugger,
  99. // only under 'clear' run.
  100. ULONG uHI = 2;
  101. return XTPHeapSetCompatibilityInformation(hHeapHandle, &uHI, sizeof(uHI));
  102. }
  103. //===========================================================================
  104. // Summary:
  105. //      This template class used as a base class for allocators which can use
  106. //      a custom (separate) heap. Each allocator use own heap or standard heap.
  107. //      To use custom heap set ms_bUseCustomHeap member to TRUE.
  108. // Parameters:
  109. //      _TData - This class must contain following static members for allocator:
  110. //
  111. //          struct allocatorClassData
  112. //          {
  113. //              static HANDLE       ms_hCustomHeap;     // handle to the custom heap
  114. //              static LONG         ms_dwRefs;          // allocated blocks count;
  115. //              static BOOL         ms_bLFHEnabled;     // report is LFH enabled for custom heap;
  116. //              static BOOL         ms_bUseCustomHeap;  // Define does allocator use custom heap or default heap;
  117. //          };
  118. // See Also:
  119. //      XTP_DECLARE_HEAP_ALLOCATOR, XTP_IMPLEMENT_HEAP_ALLOCATOR,
  120. //      CXTPHeapObjectT
  121. //===========================================================================
  122. template<class _TData>
  123. class CXTPHeapAllocatorT : public _TData
  124. {
  125. public:
  126. //{{AFX_CODEJOCK_PRIVATE
  127. typedef _TData TData;
  128. //}}AFX_CODEJOCK_PRIVATE
  129. //*** Allocator Interface ***
  130. //-----------------------------------------------------------------------
  131. // Summary:
  132. //      Allocate memory block of nBytes size.
  133. // Returns:
  134. //      A pointer to allocated block or NULL.
  135. // See Also:
  136. //      Free_mem
  137. //-----------------------------------------------------------------------
  138. static void* AFX_CDECL Alloc_mem(size_t nBytes)
  139. {
  140. InterlockedIncrement(&ms_dwRefs); //ms_dwRefs++;
  141. if (ms_bUseCustomHeap)
  142. {
  143. CreateHeapIfNeed();
  144. return ::HeapAlloc(ms_hCustomHeap, 0, nBytes);
  145. }
  146. else
  147. {
  148. #ifdef _DEBUG
  149. return DEBUG_NEW char[nBytes];
  150. #else
  151. return new char[nBytes];
  152. #endif
  153. }
  154. };
  155. //-----------------------------------------------------------------------
  156. // Summary:
  157. //      Free memory block previously allocated by Alloc_mem.
  158. // Parameters:
  159. //      p - [in] Pointer to a memory block.
  160. // See Also:
  161. //      Alloc_mem
  162. //-----------------------------------------------------------------------
  163. static void AFX_CDECL Free_mem(void* p)
  164. {
  165. LONG nRefs = 0;
  166. if (ms_dwRefs)
  167. nRefs = InterlockedDecrement(&ms_dwRefs); //ms_dwRefs--;
  168. if (ms_bUseCustomHeap)
  169. {
  170. VERIFY(::HeapFree(ms_hCustomHeap, 0, p));
  171. if (nRefs == 0)
  172. ClearHeap();
  173. }
  174. else
  175. {
  176. delete p;
  177. }
  178. };
  179. //*** Implementation ***
  180. //{{AFX_CODEJOCK_PRIVATE
  181. CXTPHeapAllocatorT()
  182. {
  183. };
  184. virtual ~CXTPHeapAllocatorT()
  185. {
  186. // When other static objects use this allocator,
  187. // they may be destroyed later (and free memory later)
  188. // Each static object, which use this allocator,
  189. // should check ms_dwRefs and destroy heap if no more refs.
  190. if (ms_dwRefs == 0)
  191. ClearHeap();
  192. };
  193. static void AFX_CDECL CreateHeapIfNeed()
  194. {
  195. if (!ms_hCustomHeap)
  196. {
  197. ms_hCustomHeap = ::HeapCreate(0, 0, 0);
  198. ASSERT(ms_hCustomHeap);
  199. ms_bLFHEnabled = XTPHeapSetLowFragmentation(ms_hCustomHeap);
  200. }
  201. }
  202. static void AFX_CDECL ClearHeap()
  203. {
  204. ASSERT(ms_dwRefs == 0);
  205. if (ms_hCustomHeap)
  206. VERIFY(::HeapDestroy(ms_hCustomHeap));
  207. ms_hCustomHeap = NULL;
  208. }
  209. //}}AFX_CODEJOCK_PRIVATE
  210. };
  211. //{{AFX_CODEJOCK_PRIVATE
  212. #define XTP_DECLARE_HEAP_ALLOCATOR_(allocatorClass, EXPORT_PARAMS) 
  213. struct EXPORT_PARAMS allocatorClass##Data     
  214. {                                              
  215. static HANDLE       ms_hCustomHeap;        
  216. static LONG         ms_dwRefs;             
  217. static BOOL         ms_bLFHEnabled;        
  218. static BOOL         ms_bUseCustomHeap;     
  219. };                                             
  220. class  EXPORT_PARAMS allocatorClass : public CXTPHeapAllocatorT<allocatorClass##Data> {};
  221. //}}AFX_CODEJOCK_PRIVATE
  222. //===========================================================================
  223. // Summary:
  224. //      This macros used to declare allocator class derived from CXTPHeapAllocatorT
  225. //      which can use default or custom (separate) heap.
  226. //      Such allocator can be used as parameter for CXTPHeapObjectT template or
  227. //      for other cases.
  228. // Parameters:
  229. //      allocatorClass  - [in] Name of the allocator class.
  230. // Remarks:
  231. //      Used together with XTP_IMPLEMENT_HEAP_ALLOCATOR macro.
  232. // Example:
  233. // <code>
  234. //
  235. //  // probably in header (*.h) file:
  236. //  XTP_DECLARE_HEAP_ALLOCATOR(CXTPReportRowAllocator)
  237. //
  238. //  // in implementation (*.cpp) file:
  239. //  XTP_IMPLEMENT_HEAP_ALLOCATOR(CXTPReportRowAllocator)
  240. //
  241. // </code>
  242. // See Also:
  243. //      XTP_IMPLEMENT_HEAP_ALLOCATOR, CXTPHeapAllocatorT, CXTPHeapObjectT
  244. //===========================================================================
  245. #define XTP_DECLARE_HEAP_ALLOCATOR(allocatorClass) XTP_DECLARE_HEAP_ALLOCATOR_(allocatorClass, XTP_EXPORT_PARAMS_NO)
  246. //===========================================================================
  247. // Summary:
  248. //      This macros used to implement allocator class previously declared by
  249. //      XTP_DECLARE_HEAP_ALLOCATOR macro.
  250. //      Such allocator can be used as parameter for CXTPHeapObjectT template or
  251. //      for other cases.
  252. // Parameters:
  253. //      allocatorClass  - [in] Name of the allocator class.
  254. //      bUseCustomHeap  - [in] Set as TRUE to enable custom heap by default for this allocator and FALSE to disable.
  255. // Remarks:
  256. //      Used together with XTP_DECLARE_HEAP_ALLOCATOR macro.
  257. // Example:
  258. // <code>
  259. //
  260. //  // probably in header (*.h) file:
  261. //  XTP_DECLARE_HEAP_ALLOCATOR(CXTPReportRowAllocator)
  262. //
  263. //  // in implementation (*.cpp) file:
  264. //  XTP_IMPLEMENT_HEAP_ALLOCATOR(CXTPReportRowAllocator)
  265. //
  266. // </code>
  267. // See Also:
  268. //      XTP_DECLARE_HEAP_ALLOCATOR, CXTPHeapAllocatorT, CXTPHeapObjectT
  269. //===========================================================================
  270. #define XTP_IMPLEMENT_HEAP_ALLOCATOR(allocatorClass, bUseCustomHeap)        
  271. HANDLE    allocatorClass##Data::ms_hCustomHeap = NULL;  
  272. LONG      allocatorClass##Data::ms_dwRefs = 0;          
  273. BOOL      allocatorClass##Data::ms_bLFHEnabled = FALSE; 
  274. BOOL      allocatorClass##Data::ms_bUseCustomHeap = bUseCustomHeap;  
  275. allocatorClass g_obj##allocatorClass;
  276. //===========================================================================
  277. // Summary:
  278. //      This template class used as a helper class to override new/delete
  279. //      operators and use custom heap allocators inside them.
  280. // Parameters:
  281. //      _TObject    - A base class;
  282. //      _TAllocator - An allocator class name;
  283. //
  284. // Example:
  285. // <code>
  286. //
  287. //  // *** Allocator must be declared (and implemented)
  288. //  // probably in header (*.h) file:
  289. //  XTP_DECLARE_HEAP_ALLOCATOR(CMyCustomHeapAllocator)
  290. //
  291. //  // in implementation (*.cpp) file:
  292. //  XTP_IMPLEMENT_HEAP_ALLOCATOR(CMyCustomHeapAllocator, TRUE)
  293. //
  294. //  // To enable custom heap allocations use second parameter in
  295. //  // XTP_IMPLEMENT_HEAP_ALLOCATOR macro or set corresponding flag
  296. //  // on initialization, before any allocations:
  297. //  //
  298. //  CMyCustomHeapAllocator::ms_bUseCustomHeap = TRUE;
  299. //
  300. //  //*** One way to use:
  301. //  class CMyClass : public CXTPHeapObjectT<CMyClassBase, CMyCustomHeapAllocator>
  302. //  {
  303. //      // ...
  304. //  };
  305. //  CMyClass* pMyClassObj = new CMyClass();
  306. //
  307. //
  308. //  //*** Other way to use:
  309. //  class CMyClass : public CMyClassBase
  310. //  {
  311. //      // ...
  312. //  };
  313. //
  314. //  class CMyClass_heap : public CXTPHeapObjectT<CMyClass, CMyCustomHeapAllocator>
  315. //  {
  316. //  };
  317. //  CMyClass* pMyClassObj = new CMyClass_heap();
  318. // </code>
  319. //
  320. // See Also:
  321. //      XTP_DECLARE_HEAP_ALLOCATOR, XTP_IMPLEMENT_HEAP_ALLOCATOR,
  322. //===========================================================================
  323. template<class _TObject, class _TAllocator>
  324. class CXTPHeapObjectT : public _TObject
  325. {
  326. public:
  327. //{{AFX_CODEJOCK_PRIVATE
  328. typedef _TObject TObject;
  329. typedef _TAllocator TAllocator;
  330. //}}AFX_CODEJOCK_PRIVATE
  331. //-----------------------------------------------------------------------
  332. // Summary:
  333. //      Allocate memory block of nSize bytes.
  334. // Returns:
  335. //      A pointer to allocated block or NULL.
  336. // See Also:
  337. //      operator delete
  338. //-----------------------------------------------------------------------
  339. void* PASCAL operator new(size_t nSize)
  340. {
  341. if (TAllocator::ms_bUseCustomHeap)
  342. return  TAllocator::Alloc_mem(nSize);
  343. else
  344. {
  345. InterlockedIncrement(&TAllocator::ms_dwRefs); //TAllocator::ms_dwRefs++;
  346. return ::operator new(nSize);
  347. }
  348. }
  349. //-----------------------------------------------------------------------
  350. // Summary:
  351. //      Free memory block previously allocated by operator new.
  352. // Parameters:
  353. //      p - [in] Pointer to a memory block.
  354. // See Also:
  355. //      operator new
  356. //-----------------------------------------------------------------------
  357. void PASCAL operator delete(void* p)
  358. {
  359. if (TAllocator::ms_bUseCustomHeap)
  360. TAllocator::Free_mem(p);
  361. else
  362. {
  363. InterlockedDecrement(&TAllocator::ms_dwRefs); //TAllocator::ms_dwRefs--;
  364. ::operator delete(p);
  365. }
  366. }
  367. //{{AFX_CODEJOCK_PRIVATE
  368. //void* PASCAL operator new(size_t, void* p) {return p;} // default is fine as is
  369. #if _MSC_VER >= 1200
  370. void PASCAL operator delete(void* p, void* pPlace)
  371. {
  372. if (TAllocator::ms_bUseCustomHeap)
  373. operator delete(p);
  374. else
  375. {
  376. InterlockedDecrement(&TAllocator::ms_dwRefs); //TAllocator::ms_dwRefs--;
  377. ::operator delete(p, pPlace);
  378. }
  379. }
  380. #endif
  381. #if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
  382. // for file name/line number tracking using DEBUG_NEW
  383. void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
  384. {
  385. if (TAllocator::ms_bUseCustomHeap)
  386. return operator new(nSize);
  387. else
  388. {
  389. InterlockedIncrement(&TAllocator::ms_dwRefs); //TAllocator::ms_dwRefs++;
  390. return ::operator new(nSize, lpszFileName, nLine);
  391. }
  392. }
  393. #if _MSC_VER >= 1200
  394. void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine)
  395. {
  396. if (TAllocator::ms_bUseCustomHeap)
  397. operator delete(p);
  398. else
  399. {
  400. InterlockedDecrement(&TAllocator::ms_dwRefs); //TAllocator::ms_dwRefs--;
  401. ::operator delete(p, lpszFileName, nLine);
  402. }
  403. }
  404. #endif
  405. #endif
  406. //}}AFX_CODEJOCK_PRIVATE
  407. };
  408. //===========================================================================
  409. // Summary:
  410. //      This class used to store strings. It automatically allocate/deallocate
  411. //      memory for string data.
  412. // Remarks:
  413. //      Override _AllocStringData, _FreeStringData to change default memory allocation.
  414. // See Also:
  415. //      CXTPHeapStringT, XTP_DECLARE_HEAP_ALLOCATOR, CXTPHeapAllocatorT
  416. //===========================================================================
  417. class _XTP_EXT_CLASS CXTPHeapString
  418. {
  419. public:
  420. //-----------------------------------------------------------------------
  421. // Summary:
  422. //      Default object constructor.
  423. // See Also:
  424. //      ~CXTPHeapString
  425. //-----------------------------------------------------------------------
  426. CXTPHeapString()
  427. {
  428. m_nStrLen = 0;
  429. m_pcszString = NULL;
  430. }
  431. //-----------------------------------------------------------------------
  432. // Summary:
  433. //      Object constructor.
  434. // Parameters:
  435. //      pcszString - [in] Pointer to a source string.
  436. // See Also:
  437. //      ~CXTPHeapString
  438. //-----------------------------------------------------------------------
  439. CXTPHeapString(LPCTSTR pcszString)
  440. {
  441. m_nStrLen = 0;
  442. m_pcszString = NULL;
  443. SetString(pcszString);
  444. }
  445. //-----------------------------------------------------------------------
  446. // Summary:
  447. //      Default object destructor.
  448. // See Also:
  449. //      CXTPHeapString
  450. //-----------------------------------------------------------------------
  451. virtual ~CXTPHeapString()
  452. {
  453. _FreeStringData();
  454. }
  455. //-----------------------------------------------------------------------
  456. // Summary:
  457. //      Use this function to determine is string empty.
  458. // Returns:
  459. //      TRUE if stored string is empty, FALSE otherwise.
  460. //-----------------------------------------------------------------------
  461. virtual BOOL IsEmpty() const
  462. {
  463. return !m_pcszString || m_nStrLen == 0;
  464. }
  465. //-----------------------------------------------------------------------
  466. // Summary:
  467. //      Assign new string value.
  468. // Parameters:
  469. //      pcszString - [in] Pointer to a source string.
  470. // Returns:
  471. //      Stored string value.
  472. //-----------------------------------------------------------------------
  473. LPCTSTR operator=(LPCTSTR pcszString)
  474. {
  475. SetString(pcszString);
  476. return m_pcszString ? m_pcszString : _T("");
  477. }
  478. //-----------------------------------------------------------------------
  479. // Summary:
  480. //      Determine are strings equal.
  481. // Parameters:
  482. //      pcszString - [in] Pointer to a string to compare.
  483. // Returns:
  484. //      TRUE if strings are equal, FALSE otherwise.
  485. //-----------------------------------------------------------------------
  486. BOOL operator==(LPCTSTR pcszString) const
  487. {
  488. return 0 == _tcscmp((LPCTSTR)*this, pcszString);
  489. }
  490. //-----------------------------------------------------------------------
  491. // Summary:
  492. //      Determine are strings different.
  493. // Parameters:
  494. //      pcszString - [in] Pointer to a string to compare.
  495. // Returns:
  496. //      TRUE if strings are different, FALSE otherwise.
  497. //-----------------------------------------------------------------------
  498. BOOL operator!=(LPCTSTR pcszString) const
  499. {
  500. return 0 != _tcscmp((LPCTSTR)*this, pcszString);
  501. }
  502. //-----------------------------------------------------------------------
  503. // Summary:
  504. //      operator LPCTSTR.
  505. // Returns:
  506. //      Pointer to a stored string.
  507. //-----------------------------------------------------------------------
  508. operator LPCTSTR() const
  509. {
  510. return m_pcszString ? m_pcszString : _T("");
  511. }
  512. //-----------------------------------------------------------------------
  513. // Summary:
  514. //      operator CString.
  515. // Returns:
  516. //      A CString object which contains stored string.
  517. //-----------------------------------------------------------------------
  518. operator CString() const
  519. {
  520. return CString(m_pcszString ? m_pcszString : _T(""));
  521. }
  522. //-----------------------------------------------------------------------
  523. // Summary:
  524. //      Allocates a BSTR from stored string data..
  525. // Returns:
  526. //      The newly allocated string.
  527. //-----------------------------------------------------------------------
  528. virtual BSTR AllocSysString() const
  529. {
  530. CString str(m_pcszString ? m_pcszString : _T(""));
  531. return str.AllocSysString();
  532. }
  533. //-----------------------------------------------------------------------
  534. // Summary:
  535. //      Use this method to set new string value.
  536. // Parameters:
  537. //      pcszString - [in] Pointer to a source string.
  538. //-----------------------------------------------------------------------
  539. virtual void SetString(LPCTSTR pcszString)
  540. {
  541. if (!pcszString || *pcszString == 0)
  542. {
  543. _FreeStringData();
  544. return;
  545. }
  546. int nNewStrLen = (int)_tcslen(pcszString);
  547. if (nNewStrLen <= m_nStrLen && m_pcszString)
  548. {
  549. STRCPY_S(m_pcszString, m_nStrLen + 1, pcszString);
  550. }
  551. else
  552. {
  553. _FreeStringData();
  554. _AllocStringData(nNewStrLen);
  555. if (m_pcszString)
  556. STRCPY_S(m_pcszString, m_nStrLen + 1, pcszString);
  557. }
  558. }
  559. protected:
  560. //-----------------------------------------------------------------------
  561. // Summary:
  562. //      This method is used to allocate string data buffer.
  563. // Parameters:
  564. //      nNewStrLen - [in] New string length without null character.
  565. //-----------------------------------------------------------------------
  566. virtual void _AllocStringData(int nNewStrLen)
  567. {
  568. ASSERT(m_pcszString == NULL);
  569. m_nStrLen = nNewStrLen;
  570. m_pcszString = new TCHAR[nNewStrLen + 1];
  571. }
  572. //-----------------------------------------------------------------------
  573. // Summary:
  574. //      This method is used to free string data buffer previously allocated
  575. //      in _AllocStringData.
  576. //-----------------------------------------------------------------------
  577. virtual void _FreeStringData()
  578. {
  579. if (m_pcszString)
  580. delete m_pcszString;
  581. m_pcszString = NULL;
  582. m_nStrLen = 0;
  583. }
  584. int m_nStrLen;       // Stored string length (without null character).
  585. LPTSTR m_pcszString; // Pointer to a stored string (or NULL).
  586. };
  587. //===========================================================================
  588. // Summary:
  589. //      This template used to store strings using different allocators.
  590. // Remarks:
  591. //      String data stored in default or separate (custom) heap.
  592. //      Specially useful for VC 6.0 instead of CString, because
  593. //      CString Release implementation allocates data using some cache
  594. //      and data is not deallocated when CString destroyed.
  595. // See Also:
  596. //      CXTPHeapString, XTP_DECLARE_HEAP_ALLOCATOR, CXTPHeapAllocatorT
  597. //===========================================================================
  598. template<class _TAllocator>
  599. class CXTPHeapStringT : public CXTPHeapString
  600. {
  601. public:
  602. //{{AFX_CODEJOCK_PRIVATE
  603. typedef _TAllocator TAllocator;
  604. //}}AFX_CODEJOCK_PRIVATE
  605. //-----------------------------------------------------------------------
  606. // Summary:
  607. //      Default object constructor.
  608. // Parameters:
  609. //      pcszString - [in] Pointer to a source string.
  610. // See Also:
  611. //      ~CXTPHeapStringT
  612. //-----------------------------------------------------------------------
  613. CXTPHeapStringT(LPCTSTR pcszString = _T(""))
  614. {
  615. SetString(pcszString);
  616. }
  617. //-----------------------------------------------------------------------
  618. // Summary:
  619. //      Default object destructor.
  620. // See Also:
  621. //      CXTPHeapString
  622. //-----------------------------------------------------------------------
  623. virtual ~CXTPHeapStringT()
  624. {
  625. _FreeStringData();
  626. }
  627. //-----------------------------------------------------------------------
  628. // Summary:
  629. //      Assign new string value.
  630. // Parameters:
  631. //      pcszString - [in] Pointer to a source string.
  632. // Returns:
  633. //      Stored string value.
  634. //-----------------------------------------------------------------------
  635. LPCTSTR operator=(LPCTSTR pcszString)
  636. {
  637. SetString(pcszString);
  638. return m_pcszString ? m_pcszString : _T("");
  639. }
  640. //-----------------------------------------------------------------------
  641. // Summary:
  642. //      Determine are strings equal.
  643. // Parameters:
  644. //      pcszString - [in] Pointer to a string to compare.
  645. // Returns:
  646. //      TRUE if strings are equal, FALSE otherwise.
  647. //-----------------------------------------------------------------------
  648. BOOL operator==(LPCTSTR pcszString) const
  649. {
  650. return 0 == _tcscmp((LPCTSTR)*this, pcszString);
  651. }
  652. //-----------------------------------------------------------------------
  653. // Summary:
  654. //      Determine are strings different.
  655. // Parameters:
  656. //      pcszString - [in] Pointer to a string to compare.
  657. // Returns:
  658. //      TRUE if strings are different, FALSE otherwise.
  659. //-----------------------------------------------------------------------
  660. BOOL operator!=(LPCTSTR pcszString) const
  661. {
  662. return 0 != _tcscmp((LPCTSTR)*this, pcszString);
  663. }
  664. //-----------------------------------------------------------------------
  665. // Summary:
  666. //      operator LPCTSTR.
  667. // Returns:
  668. //      Pointer to a stored string.
  669. //-----------------------------------------------------------------------
  670. operator LPCTSTR() const
  671. {
  672. return m_pcszString ? m_pcszString : _T("");
  673. }
  674. //-----------------------------------------------------------------------
  675. // Summary:
  676. //      operator CString.
  677. // Returns:
  678. //      A CString object which contains stored string.
  679. //-----------------------------------------------------------------------
  680. operator CString() const
  681. {
  682. return CString(m_pcszString ? m_pcszString : _T(""));
  683. }
  684. protected:
  685. //-----------------------------------------------------------------------
  686. // Summary:
  687. //      This method is used to allocate string data buffer.
  688. // Parameters:
  689. //      nNewStrLen - [in] New string length without null character.
  690. //-----------------------------------------------------------------------
  691. virtual void _AllocStringData(int nNewStrLen)
  692. {
  693. ASSERT(m_pcszString == NULL);
  694. m_nStrLen = nNewStrLen;
  695. m_pcszString = (LPTSTR)TAllocator::Alloc_mem((nNewStrLen + 1) * sizeof(TCHAR));
  696. }
  697. //-----------------------------------------------------------------------
  698. // Summary:
  699. //      This method is used to free string data buffer previously allocated
  700. //      in _AllocStringData.
  701. //-----------------------------------------------------------------------
  702. virtual void _FreeStringData()
  703. {
  704. if (m_pcszString)
  705. TAllocator::Free_mem(m_pcszString);
  706. m_pcszString = NULL;
  707. m_nStrLen = 0;
  708. }
  709. };
  710. /////////////////////////////////////////////////////////////////////////////
  711. //{{AFX_CODEJOCK_PRIVATE
  712. struct XTP_BATCHALLOC_OBJ_HEADER;
  713. struct XTP_BATCHALLOC_BLOCK_HEADER
  714. {
  715. LONG m_dwRefs;
  716. #ifdef _DEBUG
  717. DWORD m_dwObjCount;
  718. DWORD m_dwObjSize; // for debug
  719. #endif
  720. XTP_BATCHALLOC_OBJ_HEADER* pFreeList;
  721. XTP_BATCHALLOC_BLOCK_HEADER* pPrev;
  722. XTP_BATCHALLOC_BLOCK_HEADER* pNext;
  723. };
  724. struct XTP_BATCHALLOC_OBJ_HEADER
  725. {
  726. XTP_BATCHALLOC_BLOCK_HEADER* pBlockHeader;
  727. XTP_BATCHALLOC_OBJ_HEADER* pNextFree;
  728. void* GetData()
  729. {
  730. BYTE* pData = (BYTE*)this;
  731. pData += sizeof(XTP_BATCHALLOC_OBJ_HEADER);
  732. return pData;
  733. }
  734. static XTP_BATCHALLOC_OBJ_HEADER* GetHeader(void* pData)
  735. {
  736. BYTE* pBlockData = (BYTE*)pData;
  737. pBlockData -= sizeof(XTP_BATCHALLOC_OBJ_HEADER);
  738. return (XTP_BATCHALLOC_OBJ_HEADER*)pBlockData;
  739. }
  740. };
  741. template<class _TAllocator, class _TBatchAllocData>
  742. class CXTPBatchAllocManagerT : public _TBatchAllocData
  743. {
  744. public:
  745. //{{ AFX_CODEJOCK_PRIVATE
  746. typedef _TBatchAllocData TBatchAllocData;
  747. typedef _TAllocator TAllocator;
  748. //}} AFX_CODEJOCK_PRIVATE
  749. virtual ~CXTPBatchAllocManagerT()
  750. {
  751. // all data must be deallocated before
  752. ASSERT(m_pBusyBlocks == NULL);
  753. FreeExtraData();
  754. ASSERT(m_pFreeBlocks == NULL);
  755. // This static object destructor may be called later than allocator destructor.
  756. if (TAllocator::ms_dwRefs == 0)
  757. TAllocator::ClearHeap();
  758. }
  759. AFX_INLINE static int AFX_CDECL _Round4(int nSize)
  760. {
  761. int nDiv = nSize / 4;
  762. int nMod = nSize % 4;
  763. int nSizeQ4 = (nDiv + (nMod ? 1 : 0)) * 4;
  764. return nSizeQ4;
  765. }
  766. static void* AFX_CDECL AllocData(size_t nSize)
  767. {
  768. if (!m_pFreeBlocks)
  769. {
  770. int nObjSize = _Round4((int)nSize + sizeof(XTP_BATCHALLOC_OBJ_HEADER));
  771. int nBlockDataSize = sizeof(XTP_BATCHALLOC_BLOCK_HEADER) +
  772. m_nBlockSize * nObjSize;
  773. BYTE* pBlockData = (BYTE*)_TAllocator::Alloc_mem(nBlockDataSize);
  774. if (!pBlockData)
  775. return NULL;
  776. XTP_BATCHALLOC_BLOCK_HEADER* pBlockHdr = (XTP_BATCHALLOC_BLOCK_HEADER*)pBlockData;
  777. ZeroMemory(pBlockHdr, sizeof(XTP_BATCHALLOC_BLOCK_HEADER));
  778. pBlockHdr->m_dwRefs = 0;
  779. #ifdef _DEBUG
  780. pBlockHdr->m_dwObjCount = m_nBlockSize;
  781. pBlockHdr->m_dwObjSize = (DWORD)nSize;
  782. #endif
  783. //---------
  784. m_pFreeBlocks = pBlockHdr;
  785. XTP_BATCHALLOC_OBJ_HEADER* pObjHdr = NULL;
  786. pBlockData = pBlockData + sizeof(XTP_BATCHALLOC_BLOCK_HEADER);
  787. pBlockHdr->pFreeList = (XTP_BATCHALLOC_OBJ_HEADER*)pBlockData;
  788. for (int i = 0; i < m_nBlockSize; i++)
  789. {
  790. pObjHdr = (XTP_BATCHALLOC_OBJ_HEADER*)pBlockData;
  791. //ZeroMemory(pObjHdr, sizeof(XTP_BATCHALLOC_OBJ_HEADER));
  792. pBlockData += nObjSize;
  793. pObjHdr->pBlockHeader = pBlockHdr;
  794. pObjHdr->pNextFree = (XTP_BATCHALLOC_OBJ_HEADER*)pBlockData;
  795. }
  796. if (pObjHdr) pObjHdr->pNextFree = NULL;
  797. }
  798. ASSERT(m_pFreeBlocks && m_pFreeBlocks->pFreeList);
  799. if (!m_pFreeBlocks || !m_pFreeBlocks->pFreeList)
  800. return NULL;
  801. ASSERT(m_pFreeBlocks->m_dwObjSize == (DWORD)nSize);
  802. void* pData = m_pFreeBlocks->pFreeList->GetData();
  803. m_pFreeBlocks->m_dwRefs++;
  804. m_dwAllocatedObjects++;
  805. XTP_BATCHALLOC_OBJ_HEADER* pNextFree = m_pFreeBlocks->pFreeList->pNextFree;
  806. m_pFreeBlocks->pFreeList->pNextFree = NULL;
  807. m_pFreeBlocks->pFreeList = pNextFree;
  808. // no more free objects, move to busy blocks
  809. if (!pNextFree)
  810. {
  811. XTP_BATCHALLOC_BLOCK_HEADER* pNewBusyBlock = m_pFreeBlocks;
  812. m_pFreeBlocks = m_pFreeBlocks->pPrev ? m_pFreeBlocks->pPrev : m_pFreeBlocks->pNext;
  813. if (m_pFreeBlocks)
  814. m_pFreeBlocks->pPrev = pNewBusyBlock->pPrev;
  815. pNewBusyBlock->pNext = m_pBusyBlocks;
  816. pNewBusyBlock->pPrev = m_pBusyBlocks ? m_pBusyBlocks->pPrev : NULL;
  817. if (m_pBusyBlocks)
  818. m_pBusyBlocks->pPrev = pNewBusyBlock;
  819. m_pBusyBlocks = pNewBusyBlock;
  820. }
  821. return pData;
  822. }
  823. static void AFX_CDECL FreeData(void* pObj)
  824. {
  825. if (!pObj)
  826. return;
  827. XTP_BATCHALLOC_OBJ_HEADER* pObjHdr = XTP_BATCHALLOC_OBJ_HEADER::GetHeader(pObj);
  828. pObjHdr->pNextFree = pObjHdr->pBlockHeader->pFreeList;
  829. pObjHdr->pBlockHeader->pFreeList = pObjHdr;
  830. pObjHdr->pBlockHeader->m_dwRefs--;
  831. m_dwAllocatedObjects--;
  832. // was busy block, move to free list
  833. if (pObjHdr->pNextFree == NULL)
  834. {
  835. XTP_BATCHALLOC_BLOCK_HEADER* pNewFreeBlock = pObjHdr->pBlockHeader;
  836. if (pNewFreeBlock->pPrev)
  837. pNewFreeBlock->pPrev->pNext = pNewFreeBlock->pNext;
  838. if (pNewFreeBlock->pNext)
  839. pNewFreeBlock->pNext->pPrev = pNewFreeBlock->pPrev;
  840. if (m_pBusyBlocks == pNewFreeBlock)
  841. m_pBusyBlocks = pNewFreeBlock->pPrev ? pNewFreeBlock->pPrev : pNewFreeBlock->pNext;
  842. pNewFreeBlock->pNext = m_pFreeBlocks;
  843. pNewFreeBlock->pPrev = m_pFreeBlocks ? m_pFreeBlocks->pPrev : NULL;
  844. if (m_pFreeBlocks)
  845. m_pFreeBlocks->pPrev = pNewFreeBlock;
  846. m_pFreeBlocks = pNewFreeBlock;
  847. }
  848. // block is totally free, destroy block
  849. if (pObjHdr->pBlockHeader->m_dwRefs == 0 && m_bDestroyEmptyBlocksOnFree)
  850. {
  851. XTP_BATCHALLOC_BLOCK_HEADER* pEmptyBlock = pObjHdr->pBlockHeader;
  852. XTP_BATCHALLOC_BLOCK_HEADER* pIsNextFree = pEmptyBlock->pPrev ? pEmptyBlock->pPrev : pEmptyBlock->pNext;
  853. BOOL bLast = (m_pFreeBlocks == pEmptyBlock) && pIsNextFree;
  854. // do not destroy last free block
  855. if (!bLast || m_bDestroyLastEmptyBlockOnFree)
  856. {
  857. if (pEmptyBlock->pPrev)
  858. pEmptyBlock->pPrev->pNext = pEmptyBlock->pNext;
  859. if (pEmptyBlock->pNext)
  860. pEmptyBlock->pNext->pPrev = pEmptyBlock->pPrev;
  861. if (m_pFreeBlocks == pEmptyBlock)
  862. m_pFreeBlocks = pEmptyBlock->pPrev ? pEmptyBlock->pPrev : pEmptyBlock->pNext;
  863. _TAllocator::Free_mem(pEmptyBlock);
  864. }
  865. }
  866. //      if (m_dwAllocatedObjects == 0)
  867. //          FreeExtraData();
  868. }
  869. public:
  870. static void AFX_CDECL FreeExtraData()
  871. {
  872. XTP_BATCHALLOC_BLOCK_HEADER* pBlock = m_pFreeBlocks;
  873. while (pBlock && pBlock->pPrev)
  874. {
  875. pBlock = pBlock->pPrev;
  876. }
  877. while (pBlock)
  878. {
  879. // block is totally free, destroy block
  880. if (pBlock->m_dwRefs == 0)
  881. {
  882. XTP_BATCHALLOC_BLOCK_HEADER* pEmptyBlock = pBlock;
  883. if (pEmptyBlock->pPrev)
  884. pEmptyBlock->pPrev->pNext = pEmptyBlock->pNext;
  885. if (pEmptyBlock->pNext)
  886. pEmptyBlock->pNext->pPrev = pEmptyBlock->pPrev;
  887. if (m_pFreeBlocks == pEmptyBlock)
  888. m_pFreeBlocks = pEmptyBlock->pPrev ? pEmptyBlock->pPrev : pEmptyBlock->pNext;
  889. pBlock = pBlock->pNext;
  890. TAllocator::Free_mem(pEmptyBlock);
  891. }
  892. else
  893. {
  894. pBlock = pBlock->pNext;
  895. }
  896. }
  897. }
  898. };
  899. //}}AFX_CODEJOCK_PRIVATE
  900. //===========================================================================
  901. // Summary:
  902. //      This template class used as a helper class to override new/delete
  903. //      operators and use batch allocation inside them.
  904. //      Batch allocation means that memory allocated not for one object only,
  905. //      but for many objects at one time (for 1024 objects by default).
  906. //      Next allocations take memory from this big block. New blocks allocated
  907. //      when necessary. This increase performance and reduce heap fragmentation.
  908. //      Batch allocation mechanism responsible for allocation/deallocation
  909. //      blocks of memory from heap and internally organize free/busy lists of
  910. //      memory pieces. When object deleted, its memory stored in free list and
  911. //      used for new objects.
  912. //      When all memory pieces from block free, it may be deallocated from
  913. //      heap automatically (this depends on options in _TBatchAllocData)
  914. //      or by FreeExtraData call,
  915. //
  916. // Parameters:
  917. //      _TObject         - A base class;
  918. //      _TAllocator      - An allocator class name; by default _TObject::TAllocator is used.
  919. //      _TBatchAllocData - This class must contain following static members for allocator:
  920. //
  921. //                          struct BatchAllocData
  922. //                          {
  923. //                              static BOOL m_bEnableBatchAllocation;   // Define is Batch Allocation enabled;
  924. //                              static LONG m_dwAllocatedObjects;       // allocated blocks count;
  925. //
  926. //                              static BOOL m_bDestroyEmptyBlocksOnFree;    // if TRUE - completely free blocks will be deallocated on free objects, otherwise they will stay in free list.
  927. //                              static BOOL m_bDestroyLastEmptyBlockOnFree; // if TRUE - last completely free block will be deallocated on free objects, otherwise it will stay in free list.
  928. //
  929. //                              static int  m_nBlockSize;               // Count of objects in block.
  930. //                          protected:
  931. //                              static XTP_BATCHALLOC_BLOCK_HEADER* m_pFreeBlocks;  // List of blocks which have free pieces.
  932. //                              static XTP_BATCHALLOC_BLOCK_HEADER* m_pBusyBlocks;  // List of blocks which have not free pieces.
  933. //                          };
  934. //
  935. // Example:
  936. // <code>
  937. //
  938. //  // *** Batch data must be declared (and implemented)
  939. //  // probably in header (*.h) file:
  940. //  XTP_DECLARE_BATCH_ALLOC_OBJ_DATA(CBatchReportRecord_Data);
  941. //  class CBatchReportRecord : public CXTPBatchAllocObjT<CXTPReportRecord, CBatchReportRecord_Data>
  942. //  {
  943. //      // ...
  944. //  };
  945. //
  946. //  // in implementation (*.cpp) file:
  947. //  XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA(CBatchReportRecord_Data, CBatchReportRecord, TRUE);
  948. //
  949. //  // To enable Batch allocations use second parameter in
  950. //  // XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA macro or set corresponding flag
  951. //  // on initialization, before any allocations:
  952. //  //
  953. //  CMyCustomHeapAllocator::ms_bUseCustomHeap = TRUE;
  954. //
  955. //  //*** How to use:
  956. //  CBatchReportRecord* pMyClassObj = new CBatchReportRecord();
  957. //
  958. //</code>
  959. //
  960. // See Also:
  961. //      XTP_DECLARE_BATCH_ALLOC_OBJ_DATA, XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA,
  962. //===========================================================================
  963. template<class _TObject, class _TBatchAllocData, class _TAllocator = _TObject::TAllocator >
  964. class CXTPBatchAllocObjT : public _TObject
  965. {
  966. public:
  967. //{{AFX_CODEJOCK_PRIVATE
  968. typedef _TObject TObject;
  969. typedef _TBatchAllocData TBatchAllocData;
  970. typedef _TAllocator TAllocator;
  971. typedef CXTPBatchAllocManagerT<_TAllocator, _TBatchAllocData > TBlockMan;
  972. //}}AFX_CODEJOCK_PRIVATE
  973. public:
  974. //-----------------------------------------------------------------------
  975. // Summary:
  976. //      This member function check all blocks and deallocate which are
  977. //      completely free.
  978. // See Also:
  979. //      _TBatchAllocData
  980. //-----------------------------------------------------------------------
  981. static void AFX_CDECL FreeExtraData() {
  982. TBlockMan::FreeExtraData();
  983. }
  984. //-----------------------------------------------------------------------
  985. // Summary:
  986. //      Allocate memory block of nSize bytes.
  987. // Returns:
  988. //      A pointer to allocated block or NULL.
  989. // See Also:
  990. //      operator delete
  991. //-----------------------------------------------------------------------
  992. void* PASCAL operator new(size_t nSize)
  993. {
  994. if (TBlockMan::m_bBatchAllocationEnabled)
  995. return TBlockMan::AllocData(nSize);
  996. else
  997. return _TObject::operator new(nSize);
  998. }
  999. //-----------------------------------------------------------------------
  1000. // Summary:
  1001. //      Free memory block previously allocated by operator new.
  1002. // Parameters:
  1003. //      p - [in] Pointer to a memory block.
  1004. // See Also:
  1005. //      operator new
  1006. //-----------------------------------------------------------------------
  1007. void PASCAL operator delete(void* p)
  1008. {
  1009. if (TBlockMan::m_bBatchAllocationEnabled)
  1010. TBlockMan::FreeData(p);
  1011. else
  1012. _TObject::operator delete(p);
  1013. }
  1014. //{{AFX_CODEJOCK_PRIVATE
  1015. //void* PASCAL operator new(size_t, void* p) {return p;} // default is fine as is
  1016. #if _MSC_VER >= 1200
  1017. void PASCAL operator delete(void* p, void* pPlace)
  1018. {
  1019. if (TBlockMan::m_bBatchAllocationEnabled)
  1020. TBlockMan::FreeData(p);
  1021. else
  1022. _TObject::operator delete(p, pPlace);
  1023. }
  1024. #endif
  1025. #if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
  1026. // for file name/line number tracking using DEBUG_NEW
  1027. void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
  1028. {
  1029. if (TBlockMan::m_bBatchAllocationEnabled)
  1030. return operator new(nSize);
  1031. else
  1032. return _TObject::operator new(nSize, lpszFileName, nLine);
  1033. }
  1034. #if _MSC_VER >= 1200
  1035. void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine)
  1036. {
  1037. if (TBlockMan::m_bBatchAllocationEnabled)
  1038. operator delete(p);
  1039. else
  1040. _TObject::operator delete(p, lpszFileName, nLine);
  1041. }
  1042. #endif
  1043. #endif
  1044. //}}AFX_CODEJOCK_PRIVATE
  1045. };
  1046. //{{AFX_CODEJOCK_PRIVATE
  1047. #define XTP_DECLARE_BATCH_ALLOC_OBJ_DATA_(dataClass, EXPORT_PARAMS) 
  1048. struct EXPORT_PARAMS dataClass                  
  1049. {                                               
  1050. static BOOL m_bBatchAllocationEnabled;      
  1051. static LONG m_dwAllocatedObjects;           
  1052. static BOOL m_bDestroyEmptyBlocksOnFree;    
  1053. static BOOL m_bDestroyLastEmptyBlockOnFree; 
  1054. static int  m_nBlockSize;                   
  1055. static BOOL AFX_CDECL IsDataEmpty() { return !m_pFreeBlocks && !m_pBusyBlocks; };   
  1056. protected:                                      
  1057. static XTP_BATCHALLOC_BLOCK_HEADER* m_pFreeBlocks;  
  1058. static XTP_BATCHALLOC_BLOCK_HEADER* m_pBusyBlocks;  
  1059. };
  1060. //}}AFX_CODEJOCK_PRIVATE
  1061. //===========================================================================
  1062. // Summary:
  1063. //      This macros used to declare Batch allocation data which used with
  1064. //      CXTPBatchAllocObjT template.
  1065. // Parameters:
  1066. //      dataClass   - [in] Name of the Batch allocation data class.
  1067. // Remarks:
  1068. //      Used together with XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA macro.
  1069. // Example:
  1070. // <code>
  1071. //
  1072. //  XTP_DECLARE_BATCH_ALLOC_OBJ_DATA(CBatchReportRecord_Data);
  1073. //  class CBatchReportRecord : public CXTPBatchAllocObjT<CXTPReportRecord, CBatchReportRecord_Data>
  1074. //  {
  1075. //      // ...
  1076. //  };
  1077. //
  1078. //  // in implementation (*.cpp) file:
  1079. //  XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA(CBatchReportRecord_Data, CBatchReportRecord, TRUE);
  1080. //
  1081. // </code>
  1082. // See Also:
  1083. //      XTP_IMPLEMENT_HEAP_ALLOCATOR, CXTPHeapAllocatorT, CXTPBatchAllocObjT
  1084. //===========================================================================
  1085. #define XTP_DECLARE_BATCH_ALLOC_OBJ_DATA(dataClass) XTP_DECLARE_BATCH_ALLOC_OBJ_DATA_(dataClass, XTP_EXPORT_PARAMS_NO)
  1086. //===========================================================================
  1087. // Summary:
  1088. //      This macros used to declare Batch allocation data which used with
  1089. //      CXTPBatchAllocObjT template.
  1090. // Parameters:
  1091. //      dataClass           - [in] Name of the Batch allocation data class.
  1092. //      objClass            - [in] Name of the object class for Batch allocation.
  1093. //      batchAllocEnabled   - [in] Set as TRUE to enable Batch allocation by default for this object and FALSE to disable.
  1094. // Remarks:
  1095. //      Used together with XTP_DECLARE_BATCH_ALLOC_OBJ_DATA macro.
  1096. // Example:
  1097. // <code>
  1098. //
  1099. //  XTP_DECLARE_BATCH_ALLOC_OBJ_DATA(CBatchReportRecord_Data);
  1100. //  class CBatchReportRecord : public CXTPBatchAllocObjT<CXTPReportRecord, CBatchReportRecord_Data>
  1101. //  {
  1102. //      // ...
  1103. //  };
  1104. //
  1105. //  // in implementation (*.cpp) file:
  1106. //  XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA(CBatchReportRecord_Data, CBatchReportRecord, TRUE);
  1107. //
  1108. // </code>
  1109. // See Also:
  1110. //      XTP_DECLARE_BATCH_ALLOC_OBJ_DATA, CXTPHeapAllocatorT, CXTPBatchAllocObjT
  1111. //===========================================================================
  1112. #define XTP_IMPLEMENT_BATCH_ALLOC_OBJ_DATA(dataClass, objClass, batchAllocEnabled)  
  1113. BOOL dataClass::m_bBatchAllocationEnabled       = batchAllocEnabled; 
  1114. LONG dataClass::m_dwAllocatedObjects            = 0;        
  1115. int  dataClass::m_nBlockSize                    = 1024;     
  1116. BOOL dataClass::m_bDestroyEmptyBlocksOnFree     = FALSE;    
  1117. BOOL dataClass::m_bDestroyLastEmptyBlockOnFree  = FALSE;    
  1118. XTP_BATCHALLOC_BLOCK_HEADER* dataClass::m_pFreeBlocks       = NULL; 
  1119. XTP_BATCHALLOC_BLOCK_HEADER* dataClass::m_pBusyBlocks       = NULL; 
  1120. objClass::TBlockMan gs_##objClass##_BlocksManager;
  1121. #endif // !defined(_XTPCUSTOMHEAP_H__)