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.

145 lines
3.5 KiB

  1. //
  2. // ptrary.cpp
  3. //
  4. // CPtrArray
  5. //
  6. #include "private.h"
  7. #include "ptrary.h"
  8. #include "mem.h"
  9. //+---------------------------------------------------------------------------
  10. //
  11. // Insert(int iIndex, int cElems)
  12. //
  13. // Grows the array to accomodate cElems at offset iIndex.
  14. //
  15. // The new cells are NOT initialized!
  16. //
  17. //----------------------------------------------------------------------------
  18. BOOL CVoidPtrArray::Insert(int iIndex, int cElems)
  19. {
  20. void **ppv;
  21. int iSizeNew;
  22. Assert(iIndex >= 0);
  23. Assert(iIndex <= _cElems);
  24. Assert(cElems >= 0);
  25. if (cElems == 0)
  26. return TRUE;
  27. // allocate space if necessary
  28. if (_iSize < _cElems + cElems)
  29. {
  30. // allocate 1.5x what we need to avoid future allocs
  31. iSizeNew = max(_cElems + cElems, _cElems + _cElems / 2);
  32. if ((ppv = (_rgpv == NULL) ? (void **)cicMemAlloc(iSizeNew*sizeof(void *)) :
  33. (void **)cicMemReAlloc(_rgpv, iSizeNew*sizeof(void *)))
  34. == NULL)
  35. {
  36. return FALSE;
  37. }
  38. _rgpv = ppv;
  39. _iSize = iSizeNew;
  40. }
  41. if (iIndex < _cElems)
  42. {
  43. // make room for the new addition
  44. memmove(&_rgpv[iIndex + cElems], &_rgpv[iIndex], (_cElems - iIndex)*sizeof(void *));
  45. }
  46. _cElems += cElems;
  47. Assert(_iSize >= _cElems);
  48. return TRUE;
  49. }
  50. //+---------------------------------------------------------------------------
  51. //
  52. // Remove(int Index, int cElems)
  53. //
  54. // Removes cElems at offset iIndex.
  55. //
  56. //----------------------------------------------------------------------------
  57. void CVoidPtrArray::Remove(int iIndex, int cElems)
  58. {
  59. int iSizeNew;
  60. Assert(cElems > 0);
  61. Assert(iIndex >= 0);
  62. Assert(iIndex + cElems <= _cElems);
  63. if (iIndex + cElems < _cElems)
  64. {
  65. // shift following eles left
  66. memmove(&_rgpv[iIndex], &_rgpv[iIndex + cElems], (_cElems - iIndex - cElems)*sizeof(void *));
  67. }
  68. _cElems -= cElems;
  69. // free mem when array contents uses less than half alloc'd mem
  70. iSizeNew = _iSize / 2;
  71. if (iSizeNew > _cElems)
  72. {
  73. CompactSize(iSizeNew);
  74. }
  75. }
  76. //+---------------------------------------------------------------------------
  77. //
  78. // Move
  79. //
  80. // Move an entry from one position to another, shifting other entries as
  81. // appropriate to maintain the array size.
  82. //
  83. // The entry currently at iIndexNew will follow the moved entry on return.
  84. //
  85. // Returns the new index, which will be iIndexNew or iIndexNew - 1 if
  86. // iIndexOld < iIndexNew.
  87. //----------------------------------------------------------------------------
  88. int CVoidPtrArray::Move(int iIndexNew, int iIndexOld)
  89. {
  90. int iSrc;
  91. int iDst;
  92. int iActualNew;
  93. void *pv;
  94. int c;
  95. Assert(iIndexOld >= 0);
  96. Assert(iIndexOld < _cElems);
  97. Assert(iIndexNew >= 0);
  98. if (iIndexOld == iIndexNew)
  99. return iIndexOld;
  100. pv = _rgpv[iIndexOld];
  101. if (iIndexOld < iIndexNew)
  102. {
  103. c = iIndexNew - iIndexOld - 1;
  104. iSrc = iIndexOld + 1;
  105. iDst = iIndexOld;
  106. iActualNew = iIndexNew - 1;
  107. }
  108. else
  109. {
  110. c = iIndexOld - iIndexNew;
  111. iSrc = iIndexOld - c;
  112. iDst = iIndexOld - c + 1;
  113. iActualNew = iIndexNew;
  114. }
  115. Assert(iActualNew >= 0);
  116. Assert(iActualNew < _cElems);
  117. memmove(&_rgpv[iDst], &_rgpv[iSrc], c*sizeof(void *));
  118. _rgpv[iActualNew] = pv;
  119. return iActualNew;
  120. }