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.

160 lines
4.6 KiB

  1. #include "priv.h"
  2. //*** FDSA -- small/fast DSA routines
  3. // DESCRIPTION
  4. // We attempt to behave as much like an array as possible (semantics
  5. // and performance and to some extent allocation). In particular,
  6. // - indexing (FDSA_GetItemXxx) is done entirely inline; and...
  7. // - ... involves only 1 extra indirection vs. a true array; and...
  8. // - ... knows the data type so sizeof is a constant; and...
  9. // - ... does no range checks (except possibly in DEBUG versions).
  10. // - part of the FDSA is statically alloc'ed, so one can put critical
  11. // items in the static part to ensure that they'll be there even under
  12. // low memory conditions.
  13. // NOTES
  14. // For now we only implement:
  15. // Initialize, Destroy, GetItemPtr, GetItemCount, InsertItem, AppendItem
  16. // FEATURE eventually these come from comctl...
  17. #define DABreak() /*NOTHING*/
  18. // ReAlloc and Free come from inc/heapaloc.h
  19. //*** SDSA_PITEM -- get item the hard way
  20. //
  21. #define SDSA_PITEM(pfdsa, i) \
  22. ((void *)(((BYTE *)(pfdsa)->aItem) + ((i) * (pfdsa)->cbItem)))
  23. //*** FDSA_Initialize -- initialize
  24. //
  25. // SECURITY: caller is responsible for aItemStatic having at least (cItemStatice * cbItem) bytes
  26. BOOL WINAPI FDSA_Initialize(int cbItem, int cItemGrow,
  27. PFDSA pfdsa, void * aItemStatic, int cItemStatic)
  28. {
  29. ASSERT(pfdsa != NULL); // WARNING how handle?
  30. if (cItemGrow == 0)
  31. cItemGrow = 1;
  32. // for implementation simplicity, cItemStatic must be a multiple of
  33. // cItemGrow. o.w. our 1st grow from static->dynamic is messy and
  34. // probably buggy.
  35. if (cItemStatic % cItemGrow != 0) {
  36. AssertMsg(0, TEXT("CItemStatic must be a multiple of cItemGrow"));
  37. return FALSE;
  38. }
  39. if (aItemStatic != NULL)
  40. {
  41. // since we're (eventually) in comctl, we can't assume caller's
  42. // buffer was 0'ed
  43. ZeroMemory(aItemStatic, cItemStatic * cbItem);
  44. }
  45. if (pfdsa) {
  46. pfdsa->cItem = 0;
  47. pfdsa->cItemAlloc = cItemStatic;
  48. pfdsa->aItem = aItemStatic;
  49. pfdsa->fAllocated = FALSE;
  50. pfdsa->cbItem = cbItem;
  51. ASSERT(pfdsa->cbItem == cbItem); // bitfield overflow
  52. pfdsa->cItemGrow = cItemGrow;
  53. ASSERT(pfdsa->cItemGrow == cItemGrow); // bitfield overflow
  54. }
  55. return TRUE;
  56. }
  57. BOOL WINAPI FDSA_Destroy(PFDSA pdsa)
  58. {
  59. if (pdsa == NULL) // allow NULL for low memory cases
  60. return TRUE;
  61. if (pdsa->fAllocated && pdsa->aItem && !LocalFree(pdsa->aItem))
  62. return FALSE;
  63. return TRUE;
  64. }
  65. void* _LocalReAlloc(void* p, UINT uBytes)
  66. {
  67. if (uBytes) {
  68. if (p) {
  69. return LocalReAlloc(p, uBytes, LMEM_MOVEABLE | LMEM_ZEROINIT);
  70. } else {
  71. return LocalAlloc(LPTR, uBytes);
  72. }
  73. } else {
  74. if (p)
  75. LocalFree(p);
  76. return NULL;
  77. }
  78. }
  79. //*** FDSA_InsertItem -- insert an item
  80. // ENTRY/EXIT
  81. // index insertion point; index > count (e.g. DA_LAST) means append
  82. // NOTES
  83. // param called 'pdsa' (vs. pfdsa) for easy diff'ing w/ DSA_InsertItem
  84. int WINAPI FDSA_InsertItem(PFDSA pdsa, int index, void FAR* pitem)
  85. {
  86. ASSERT(pitem);
  87. if (index < 0) {
  88. TraceMsg(DM_ERROR, "FDSA: InsertItem: Invalid index: %d", index);
  89. DABreak();
  90. return -1;
  91. }
  92. if (index > pdsa->cItem)
  93. index = pdsa->cItem;
  94. if (pdsa->cItem + 1 > pdsa->cItemAlloc) {
  95. void FAR* aItemNew = _LocalReAlloc(pdsa->fAllocated ? pdsa->aItem : NULL,
  96. (pdsa->cItemAlloc + pdsa->cItemGrow) * pdsa->cbItem);
  97. if (!aItemNew)
  98. return -1;
  99. if (!pdsa->fAllocated) {
  100. // when we go from static->dynamic, we need to copy
  101. pdsa->fAllocated = TRUE;
  102. hmemcpy(aItemNew, pdsa->aItem, pdsa->cItem * pdsa->cbItem);
  103. }
  104. pdsa->aItem = aItemNew;
  105. pdsa->cItemAlloc += pdsa->cItemGrow;
  106. }
  107. if (index < pdsa->cItem) {
  108. hmemcpy(SDSA_PITEM(pdsa, index + 1), SDSA_PITEM(pdsa, index),
  109. (pdsa->cItem - index) * pdsa->cbItem);
  110. }
  111. pdsa->cItem++;
  112. hmemcpy(SDSA_PITEM(pdsa, index), pitem, pdsa->cbItem);
  113. return index;
  114. }
  115. BOOL WINAPI FDSA_DeleteItem(PFDSA pdsa, int index)
  116. {
  117. ASSERT(pdsa);
  118. if (index < 0 || index >= pdsa->cItem)
  119. {
  120. TraceMsg(TF_ERROR, "FDSA: DeleteItem: Invalid index: %d", index);
  121. DABreak();
  122. return FALSE;
  123. }
  124. if (index < pdsa->cItem - 1)
  125. {
  126. hmemcpy(SDSA_PITEM(pdsa, index), SDSA_PITEM(pdsa, index + 1),
  127. (pdsa->cItem - (index + 1)) * pdsa->cbItem);
  128. }
  129. pdsa->cItem--;
  130. return TRUE;
  131. }