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.

300 lines
5.7 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. SMALLARR.INL
  5. Abstract:
  6. Small Array Inlines.
  7. History:
  8. --*/
  9. CSmallArray::CSmallArray()
  10. {
  11. SetBlob(NULL);
  12. }
  13. CSmallArray::~CSmallArray()
  14. {
  15. Empty();
  16. }
  17. void* CSmallArray::GetAt(int nIndex) const
  18. {
  19. if(IsSingleton())
  20. return GetOnlyMember(); // nIndex better be 0!
  21. else
  22. {
  23. const CSmallArrayBlob* pBlob;
  24. if (pBlob = GetBlob())
  25. return pBlob->GetAt(nIndex);
  26. else
  27. return NULL;
  28. }
  29. }
  30. void CSmallArray::SetAt(int nIndex, void *p, void** ppOld)
  31. {
  32. if(IsSingleton() && nIndex == 0)
  33. {
  34. // Changing our only element
  35. // =========================
  36. if(ppOld) *ppOld = GetOnlyMember();
  37. SetOnlyMember(p);
  38. }
  39. else
  40. {
  41. EnsureBlob(nIndex+1);
  42. CSmallArrayBlob* pBlob;
  43. if (pBlob = GetBlob())
  44. pBlob->SetAt(nIndex, p, ppOld);
  45. }
  46. }
  47. int CSmallArray::RemoveAt(int nIndex, void** ppOld)
  48. {
  49. if(IsSingleton())
  50. {
  51. // Removing our only element --- nIndex better be 0
  52. // ================================================
  53. Empty();
  54. }
  55. else
  56. {
  57. CSmallArrayBlob* pBlob;
  58. if (pBlob = GetBlob())
  59. {
  60. SetBlob(pBlob->RemoveAt(nIndex, ppOld));
  61. pBlob = NULL; // to ward off temptation --- pBlob is no longer valid
  62. // Check if the blob has become empty
  63. // ==================================
  64. pBlob = GetBlob();
  65. if(pBlob && pBlob->Size() == 0)
  66. Empty();
  67. }
  68. else
  69. return CFlexArray::out_of_memory;
  70. }
  71. return CFlexArray::no_error;
  72. }
  73. int CSmallArray::InsertAt(int nIndex, void* pMember)
  74. {
  75. if(IsEmpty())
  76. {
  77. // Inserting our first element --- nIndex better be 0
  78. // ==================================================
  79. SetOnlyMember(pMember);
  80. }
  81. else
  82. {
  83. EnsureBlob(nIndex+1);
  84. CSmallArrayBlob* pBlob;
  85. if (pBlob = GetBlob())
  86. SetBlob(pBlob->InsertAt(nIndex, pMember));
  87. else
  88. return CFlexArray::out_of_memory;
  89. }
  90. return CFlexArray::no_error;
  91. }
  92. int CSmallArray::Size() const
  93. {
  94. if(IsEmpty())
  95. return 0;
  96. else if(IsSingleton())
  97. return 1;
  98. else
  99. {
  100. const CSmallArrayBlob* pBlob;
  101. if (pBlob = GetBlob())
  102. return pBlob->Size();
  103. else
  104. return 0;
  105. }
  106. }
  107. void CSmallArray::Trim()
  108. {
  109. if(IsSingleton())
  110. {
  111. // If the member is NULL, get rid of it
  112. // ====================================
  113. if(GetOnlyMember() == NULL)
  114. Empty();
  115. }
  116. else if(IsEmpty())
  117. {
  118. }
  119. else
  120. {
  121. CSmallArrayBlob* pBlob;
  122. if (pBlob = GetBlob())
  123. {
  124. pBlob->Trim();
  125. // If the blob is now empty, convert to "empty"
  126. // ============================================
  127. if(pBlob->Size() == 0)
  128. Empty();
  129. }
  130. }
  131. }
  132. void CSmallArray::Empty()
  133. {
  134. if(IsBlob())
  135. delete [] GetBlob();
  136. SetBlob(NULL);
  137. }
  138. void CSmallArray::EnsureBlob(int nMinSize)
  139. {
  140. if(IsSingleton())
  141. {
  142. // Allocate a new blob
  143. // ===================
  144. CSmallArrayBlob* pBlob = CSmallArrayBlob::CreateBlob(nMinSize);
  145. // Copy the data
  146. // =============
  147. if(pBlob != NULL)
  148. pBlob->InsertAt(0, GetOnlyMember());
  149. SetBlob(pBlob);
  150. }
  151. }
  152. void** CSmallArray::GetArrayPtr()
  153. {
  154. if(IsEmpty())
  155. return NULL;
  156. else if(IsSingleton())
  157. return &GetOnlyMember();
  158. else
  159. {
  160. CSmallArrayBlob* pBlob;
  161. if (pBlob = GetBlob())
  162. return pBlob->GetArrayPtr();
  163. else
  164. return NULL;
  165. }
  166. }
  167. void** CSmallArray::UnbindPtr()
  168. {
  169. void** ppReturn = NULL;
  170. if(IsSingleton())
  171. {
  172. ppReturn = new void*[1];
  173. if (ppReturn)
  174. *ppReturn = GetOnlyMember();
  175. }
  176. else if(IsBlob())
  177. {
  178. CSmallArrayBlob* pBlob;
  179. if (pBlob = GetBlob())
  180. ppReturn = pBlob->CloneData();
  181. }
  182. Empty();
  183. return ppReturn;
  184. }
  185. void* const* CSmallArray::GetArrayPtr() const
  186. {
  187. if(IsEmpty())
  188. return NULL;
  189. else if(IsSingleton())
  190. return &GetOnlyMember();
  191. else
  192. {
  193. const CSmallArrayBlob* pBlob;
  194. if (pBlob = GetBlob())
  195. return pBlob->GetArrayPtr();
  196. else
  197. return NULL;
  198. }
  199. }
  200. void CSmallArray::Sort()
  201. {
  202. if(IsBlob())
  203. {
  204. CSmallArrayBlob* pBlob;
  205. if (pBlob = GetBlob())
  206. pBlob->Sort();
  207. }
  208. }
  209. void*& CSmallArray::GetOnlyMember()
  210. {
  211. return m_pData;
  212. }
  213. void* const & CSmallArray::GetOnlyMember() const
  214. {
  215. return m_pData;
  216. }
  217. void CSmallArray::SetOnlyMember(void* p)
  218. {
  219. m_pData = p;
  220. }
  221. BOOL CSmallArray::IsEmpty() const
  222. {
  223. return (m_pData == (void*)1);
  224. }
  225. BOOL CSmallArray::IsSingleton() const
  226. {
  227. return (((DWORD_PTR)m_pData & 1) == 0);
  228. }
  229. BOOL CSmallArray::IsBlob() const
  230. {
  231. return (m_pData != (void*)1) && ((DWORD_PTR)m_pData & 1);
  232. }
  233. CSmallArrayBlob* CSmallArray::GetBlob()
  234. {
  235. return (CSmallArrayBlob*)((DWORD_PTR)m_pData & ~(DWORD_PTR)1);
  236. }
  237. const CSmallArrayBlob* CSmallArray::GetBlob() const
  238. {
  239. return (CSmallArrayBlob*)((DWORD_PTR)m_pData & ~(DWORD_PTR)1);
  240. }
  241. void CSmallArray::SetBlob(CSmallArrayBlob* pBlob)
  242. {
  243. m_pData = (CSmallArrayBlob*)((DWORD_PTR)pBlob | 1);
  244. }