Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
3.6 KiB

  1. /*
  2. * S T A C K B U F . H
  3. *
  4. * Data buffer processing
  5. *
  6. * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  7. */
  8. #ifndef _EX_STACKBUF_H_
  9. #define _EX_STACKBUF_H_
  10. #include <caldbg.h>
  11. // Alignment macros ----------------------------------------------------------
  12. //
  13. #include <align.h>
  14. // Safe allocators -----------------------------------------------------------
  15. //
  16. #include <ex\exmem.h>
  17. // Class STACKBUF ------------------------------------------------------------
  18. //
  19. enum { STACKBUFFER_THRESHOLD = 64};
  20. template <class T, UINT N = STACKBUFFER_THRESHOLD>
  21. class CStackBuffer
  22. {
  23. private:
  24. BYTE m_rgb[N];
  25. ULONG m_fDynamic:1;
  26. ULONG m_fValid:1;
  27. ULONG m_cb:30;
  28. T* m_pt;
  29. // non-implemented operators
  30. //
  31. CStackBuffer(const CStackBuffer& );
  32. CStackBuffer& operator=(const CStackBuffer& );
  33. void release()
  34. {
  35. if (m_fDynamic && m_pt)
  36. {
  37. ExFree(m_pt);
  38. m_pt = NULL;
  39. }
  40. }
  41. T& idx(size_t iT) const
  42. {
  43. Assert(m_fValid && m_pt && ((UINT)iT < celems()));
  44. return m_pt[iT];
  45. }
  46. // non-implemented operators
  47. //
  48. operator T*() const;
  49. T& operator*() const;
  50. T** operator&() const;
  51. // block random assignments
  52. //
  53. CStackBuffer& operator=(T* pt);
  54. CStackBuffer& operator=(void * p);
  55. public:
  56. // Manuplation -----------------------------------------------------------
  57. //
  58. // Allocation mechanism, replaces _alloca()
  59. //
  60. T * resize (UINT cb)
  61. {
  62. // Max size for a stack item
  63. //
  64. Assert (cb <= 0x3FFFFFFF);
  65. // Lets go ahead an ask for a sizable chunk, regardless.
  66. //
  67. cb = max(cb, N);
  68. // If the size of the item is greater than the current size,
  69. // then we need to aquire space for the data,
  70. //
  71. if (m_cb < cb)
  72. {
  73. T* pt = NULL;
  74. // If the item is already dynamically allocated, or if the
  75. // size exceeds the threshold of the stackbuffer, allocate
  76. // the memory.
  77. //
  78. if (m_fDynamic || (N < cb))
  79. {
  80. // Allocate space using ExAlloc() and return that value,
  81. // fDynamic means that the existing value is dynamically
  82. // allocated. Free the old before creating the new.
  83. //
  84. DebugTrace ("DAV: stackbuf going dynamic...\n");
  85. //
  86. // The free/alloc should have better perf characteristics
  87. // in the multi-heap land.
  88. //
  89. release();
  90. pt = static_cast<T*>(ExAlloc(cb));
  91. m_fDynamic = TRUE;
  92. }
  93. else
  94. {
  95. pt = reinterpret_cast<T*>(m_rgb);
  96. }
  97. m_pt = pt;
  98. m_cb = cb;
  99. }
  100. m_fValid = TRUE;
  101. return m_pt;
  102. }
  103. // Constructor/Destructor ------------------------------------------------
  104. //
  105. ~CStackBuffer() { release(); }
  106. explicit CStackBuffer(UINT uInitial = N)
  107. : m_fDynamic(FALSE),
  108. m_fValid(FALSE),
  109. m_pt(NULL),
  110. m_cb(0)
  111. {
  112. resize(uInitial);
  113. }
  114. // Invalidation ----------------------------------------------------------
  115. //
  116. void clear() { m_fValid = FALSE; }
  117. // Size ------------------------------------------------------------------
  118. //
  119. size_t celems() const { return (m_cb / sizeof(T)); }
  120. size_t size() const { return m_cb; }
  121. // Accessors -------------------------------------------------------------
  122. //
  123. T* get() const { Assert(m_fValid && m_pt); return m_pt; }
  124. void* pvoid() const { Assert(m_fValid && m_pt); return m_pt; }
  125. T* operator->() const { Assert(m_fValid && m_pt); return m_pt; }
  126. T& operator[] (INT iT) const { return idx((size_t)iT); }
  127. T& operator[] (UINT iT) const { return idx((size_t)iT); }
  128. T& operator[] (DWORD iT) const { return idx((size_t)iT); }
  129. T& operator[] (__int64 iT) const { return idx((size_t)iT); }
  130. T& operator[] (unsigned __int64 iT) const { return idx((size_t)iT); }
  131. };
  132. #endif // _EX_STACKBUF_H_