carray.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:6k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "carray.h"
  36. #include "hlxclib/string.h"
  37. static const int KInitDefaultGrowSize = 16;
  38. ///
  39. /// public methods
  40. ///
  41. CHXPtrArray::CHXPtrArray()
  42.     : m_size(0),
  43.       m_nelems(0),
  44.       m_userGrowSize(-1),
  45.       m_defGrowSize(KInitDefaultGrowSize),
  46.       m_pData(0)
  47. {
  48.     
  49. }
  50. CHXPtrArray::~CHXPtrArray()
  51. {
  52.     delete [] m_pData;
  53. }
  54. ///
  55. /// SetSize(int nelems, int growSize)
  56. ///
  57. /// set size and grow size
  58. ///
  59. void 
  60. CHXPtrArray::SetSize(int nelems, int growSize)
  61. {
  62.     if (growSize != -1)
  63. m_userGrowSize = growSize;
  64.     if (nelems > m_size)
  65. Resize(nelems);
  66.     else if (nelems < m_nelems)
  67. ::memset(&m_pData[nelems], 0, (m_nelems - nelems) * sizeof(void*));
  68.     m_nelems = nelems;
  69. }
  70. ///
  71. /// FreeExtra()
  72. ///
  73. /// free un-assigned slots
  74. ///
  75. void 
  76. CHXPtrArray::FreeExtra()
  77. {
  78.     if (m_size > m_nelems)
  79. Resize(m_nelems);
  80. }
  81. ///
  82. /// RemoveAll()
  83. ///
  84. /// free the entire array
  85. ///
  86. void 
  87. CHXPtrArray::RemoveAll()
  88. {
  89.     delete [] m_pData;
  90.     m_pData = 0;
  91.     m_nelems = 0;
  92.     m_size = 0;
  93. }
  94. ///
  95. /// SetAtGrow(int index, void* value)
  96. ///
  97. /// set value, grow array if needed
  98. ///
  99. void 
  100. CHXPtrArray::SetAtGrow(int index, void* value)
  101. {
  102.     HX_ASSERT(index >= 0);
  103.     int nelems = index + 1;
  104.     if (nelems > m_size)
  105. Resize(m_size + GetGrowSize(nelems));
  106.     if (nelems > m_nelems) m_nelems = nelems;
  107.     m_pData[index] = value;
  108. }
  109. /// 
  110. /// InsertAt(int index, void* value, int repeat=1)
  111. ///
  112. /// insert value(s) at index -- list operation
  113. ///
  114. void 
  115. CHXPtrArray::InsertAt(int index, void* value, int repeat)
  116. {
  117.     InsertCommon(index, repeat);
  118.     for (int i=0; i < repeat; ++i)
  119. m_pData[i + index] = value;
  120. }
  121. ///
  122. /// InsertAt(int index, CHXPtrArray* pPtrArray)
  123. ///
  124. /// insert array at index
  125. ///
  126. void 
  127. CHXPtrArray::InsertAt(int index, CHXPtrArray* pPtrArray)
  128. {
  129.     InsertCommon(index, pPtrArray->m_nelems);
  130.     ::memmove(&m_pData[index], pPtrArray->m_pData,
  131.       pPtrArray->m_nelems * sizeof(void*));
  132. }
  133. ///
  134. /// RemoveAt(int index, int repeat=1)
  135. ///
  136. /// remove value at index
  137. ///
  138. void 
  139. CHXPtrArray::RemoveAt(int index, int repeat)
  140. {
  141.     HX_ASSERT(index >= 0 && index < m_nelems);
  142.     int relems = MIN(repeat, m_nelems - index); // number of elements to remove
  143.     int numBytes = (m_nelems - index - relems) * sizeof(void*);
  144.     if (numBytes > 0)
  145.         ::memmove(&m_pData[index], &m_pData[index + relems], numBytes);
  146.     SetSize(m_nelems - relems);
  147. }
  148. ///
  149. /// private methods
  150. ///
  151. ///
  152. /// Resize()
  153. ///
  154. /// common resize method
  155. ///
  156. void
  157. CHXPtrArray::Resize(int size)
  158. {
  159.     void** pData = new void*[size];
  160.     HX_ASSERT(pData);
  161.     if (pData)
  162.     {
  163. // copy the existing data
  164. int celems = MIN(size, m_nelems); // number of elements to copy
  165. if (celems > 0)
  166.     ::memcpy(pData, m_pData, celems * sizeof(void*)); /* Flawfinder: ignore */
  167. if (size > celems)
  168.     ::memset(&pData[celems], 0, (size - celems) * sizeof(void*));
  169. delete [] m_pData;
  170. m_pData = pData;
  171. m_size = size;
  172. m_nelems = celems;
  173.     }
  174. }
  175. ///
  176. /// GetGrowSize() 
  177. ///
  178. /// return the size to grow the array, this may be set by the user in
  179. /// SetSize() but will default to a doubling algorithm if not
  180. ///
  181. int
  182. CHXPtrArray::GetGrowSize(int newSize) 
  183. {
  184.     int growSize = 0;
  185.     if (m_userGrowSize != -1)
  186.     {
  187. // use multiple of user set size
  188. while (m_size + growSize < newSize)
  189.     growSize += m_userGrowSize;
  190.     }
  191.     else
  192.     {
  193. // or use doubling if user did not set grow size
  194. while (m_size + m_defGrowSize < newSize)
  195.     m_defGrowSize <<= 1;
  196. growSize = m_defGrowSize;
  197.     }
  198.     return growSize;
  199. }
  200. ///
  201. /// InsertCommon(int index, int len)
  202. ///
  203. /// common implementation for InsertAt methods
  204. /// makes room in array to insert 'len' values at 'index'
  205. ///
  206. void
  207. CHXPtrArray::InsertCommon(int index, int len)
  208. {
  209.     HX_ASSERT(index >= 0);
  210.     int nelems; // total number of elements post insert
  211.     // are we adding off the end or adding in the middle?
  212.     if (index > m_nelems)
  213. nelems = index + len;
  214.     else 
  215. nelems = m_nelems + len;
  216.     // check to see if we need to grow the array
  217.     void** pData = m_pData;
  218.     if (nelems > m_size) 
  219.     {
  220. int newSize = m_size + GetGrowSize(nelems);
  221. pData = new void*[newSize];
  222. // zero the extra data
  223. ::memset(&pData[m_nelems], 0, (newSize - m_nelems) * sizeof(void*));
  224. m_size = newSize;
  225. // copy the prefix
  226. if (index > 0)
  227.     ::memcpy(pData, m_pData, MIN(m_nelems, index) * sizeof(void*)); /* Flawfinder: ignore */
  228.     }
  229.     // copy the suffix -- uses memmove in case of overlap
  230.     if (index < m_nelems)
  231. ::memmove(&pData[index + len], &m_pData[index], 
  232.   (m_nelems - index) * sizeof(void*));
  233.     m_nelems = nelems;
  234.     // if we had to resize, delete the old storage
  235.     if (pData != m_pData)
  236.     {
  237. delete [] m_pData;
  238. m_pData = pData;
  239.     }
  240. }