1. /*
  2. * Copyright 2002-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id$
  18. */
  19. package com.sun.org.apache.xml.internal.utils;
  20. /**
  21. * A very simple table that stores a list of objects.
  22. *
  23. * This version is based on a "realloc" strategy -- a simle array is
  24. * used, and when more storage is needed, a larger array is obtained
  25. * and all existing data is recopied into it. As a result, read/write
  26. * access to existing nodes is O(1) fast but appending may be O(N**2)
  27. * slow.
  28. * @xsl.usage internal
  29. */
  30. public class ObjectVector implements Cloneable
  31. {
  32. /** Size of blocks to allocate */
  33. protected int m_blocksize;
  34. /** Array of objects */
  35. protected Object m_map[];
  36. /** Number of ints in array */
  37. protected int m_firstFree = 0;
  38. /** Size of array */
  39. protected int m_mapSize;
  40. /**
  41. * Default constructor. Note that the default
  42. * block size is very small, for small lists.
  43. */
  44. public ObjectVector()
  45. {
  46. m_blocksize = 32;
  47. m_mapSize = m_blocksize;
  48. m_map = new Object[m_blocksize];
  49. }
  50. /**
  51. * Construct a IntVector, using the given block size.
  52. *
  53. * @param blocksize Size of block to allocate
  54. */
  55. public ObjectVector(int blocksize)
  56. {
  57. m_blocksize = blocksize;
  58. m_mapSize = blocksize;
  59. m_map = new Object[blocksize];
  60. }
  61. /**
  62. * Construct a IntVector, using the given block size.
  63. *
  64. * @param blocksize Size of block to allocate
  65. */
  66. public ObjectVector(int blocksize, int increaseSize)
  67. {
  68. m_blocksize = increaseSize;
  69. m_mapSize = blocksize;
  70. m_map = new Object[blocksize];
  71. }
  72. /**
  73. * Copy constructor for ObjectVector
  74. *
  75. * @param v Existing ObjectVector to copy
  76. */
  77. public ObjectVector(ObjectVector v)
  78. {
  79. m_map = new Object[v.m_mapSize];
  80. m_mapSize = v.m_mapSize;
  81. m_firstFree = v.m_firstFree;
  82. m_blocksize = v.m_blocksize;
  83. System.arraycopy(v.m_map, 0, m_map, 0, m_firstFree);
  84. }
  85. /**
  86. * Get the length of the list.
  87. *
  88. * @return length of the list
  89. */
  90. public final int size()
  91. {
  92. return m_firstFree;
  93. }
  94. /**
  95. * Get the length of the list.
  96. *
  97. * @return length of the list
  98. */
  99. public final void setSize(int sz)
  100. {
  101. m_firstFree = sz;
  102. }
  103. /**
  104. * Append an object onto the vector.
  105. *
  106. * @param value Object to add to the list
  107. */
  108. public final void addElement(Object value)
  109. {
  110. if ((m_firstFree + 1) >= m_mapSize)
  111. {
  112. m_mapSize += m_blocksize;
  113. Object newMap[] = new Object[m_mapSize];
  114. System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
  115. m_map = newMap;
  116. }
  117. m_map[m_firstFree] = value;
  118. m_firstFree++;
  119. }
  120. /**
  121. * Append several Object values onto the vector.
  122. *
  123. * @param value Object to add to the list
  124. */
  125. public final void addElements(Object value, int numberOfElements)
  126. {
  127. if ((m_firstFree + numberOfElements) >= m_mapSize)
  128. {
  129. m_mapSize += (m_blocksize+numberOfElements);
  130. Object newMap[] = new Object[m_mapSize];
  131. System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
  132. m_map = newMap;
  133. }
  134. for (int i = 0; i < numberOfElements; i++)
  135. {
  136. m_map[m_firstFree] = value;
  137. m_firstFree++;
  138. }
  139. }
  140. /**
  141. * Append several slots onto the vector, but do not set the values.
  142. *
  143. * @param numberOfElements number of slots to append
  144. */
  145. public final void addElements(int numberOfElements)
  146. {
  147. if ((m_firstFree + numberOfElements) >= m_mapSize)
  148. {
  149. m_mapSize += (m_blocksize+numberOfElements);
  150. Object newMap[] = new Object[m_mapSize];
  151. System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
  152. m_map = newMap;
  153. }
  154. m_firstFree += numberOfElements;
  155. }
  156. /**
  157. * Inserts the specified object in this vector at the specified index.
  158. * Each component in this vector with an index greater or equal to
  159. * the specified index is shifted upward to have an index one greater
  160. * than the value it had previously.
  161. *
  162. * @param value Object to insert
  163. * @param at Index of where to insert
  164. */
  165. public final void insertElementAt(Object value, int at)
  166. {
  167. if ((m_firstFree + 1) >= m_mapSize)
  168. {
  169. m_mapSize += m_blocksize;
  170. Object newMap[] = new Object[m_mapSize];
  171. System.arraycopy(m_map, 0, newMap, 0, m_firstFree + 1);
  172. m_map = newMap;
  173. }
  174. if (at <= (m_firstFree - 1))
  175. {
  176. System.arraycopy(m_map, at, m_map, at + 1, m_firstFree - at);
  177. }
  178. m_map[at] = value;
  179. m_firstFree++;
  180. }
  181. /**
  182. * Remove all elements objects from the list.
  183. */
  184. public final void removeAllElements()
  185. {
  186. for (int i = 0; i < m_firstFree; i++)
  187. {
  188. m_map[i] = null;
  189. }
  190. m_firstFree = 0;
  191. }
  192. /**
  193. * Removes the first occurrence of the argument from this vector.
  194. * If the object is found in this vector, each component in the vector
  195. * with an index greater or equal to the object's index is shifted
  196. * downward to have an index one smaller than the value it had
  197. * previously.
  198. *
  199. * @param s Object to remove from array
  200. *
  201. * @return True if the object was removed, false if it was not found
  202. */
  203. public final boolean removeElement(Object s)
  204. {
  205. for (int i = 0; i < m_firstFree; i++)
  206. {
  207. if (m_map[i] == s)
  208. {
  209. if ((i + 1) < m_firstFree)
  210. System.arraycopy(m_map, i + 1, m_map, i - 1, m_firstFree - i);
  211. else
  212. m_map[i] = null;
  213. m_firstFree--;
  214. return true;
  215. }
  216. }
  217. return false;
  218. }
  219. /**
  220. * Deletes the component at the specified index. Each component in
  221. * this vector with an index greater or equal to the specified
  222. * index is shifted downward to have an index one smaller than
  223. * the value it had previously.
  224. *
  225. * @param i index of where to remove an object
  226. */
  227. public final void removeElementAt(int i)
  228. {
  229. if (i > m_firstFree)
  230. System.arraycopy(m_map, i + 1, m_map, i, m_firstFree);
  231. else
  232. m_map[i] = null;
  233. m_firstFree--;
  234. }
  235. /**
  236. * Sets the component at the specified index of this vector to be the
  237. * specified object. The previous component at that position is discarded.
  238. *
  239. * The index must be a value greater than or equal to 0 and less
  240. * than the current size of the vector.
  241. *
  242. * @param value object to set
  243. * @param index Index of where to set the object
  244. */
  245. public final void setElementAt(Object value, int index)
  246. {
  247. m_map[index] = value;
  248. }
  249. /**
  250. * Get the nth element.
  251. *
  252. * @param i index of object to get
  253. *
  254. * @return object at given index
  255. */
  256. public final Object elementAt(int i)
  257. {
  258. return m_map[i];
  259. }
  260. /**
  261. * Tell if the table contains the given Object.
  262. *
  263. * @param s object to look for
  264. *
  265. * @return true if the object is in the list
  266. */
  267. public final boolean contains(Object s)
  268. {
  269. for (int i = 0; i < m_firstFree; i++)
  270. {
  271. if (m_map[i] == s)
  272. return true;
  273. }
  274. return false;
  275. }
  276. /**
  277. * Searches for the first occurence of the given argument,
  278. * beginning the search at index, and testing for equality
  279. * using the equals method.
  280. *
  281. * @param elem object to look for
  282. * @param index Index of where to begin search
  283. * @return the index of the first occurrence of the object
  284. * argument in this vector at position index or later in the
  285. * vector; returns -1 if the object is not found.
  286. */
  287. public final int indexOf(Object elem, int index)
  288. {
  289. for (int i = index; i < m_firstFree; i++)
  290. {
  291. if (m_map[i] == elem)
  292. return i;
  293. }
  294. return java.lang.Integer.MIN_VALUE;
  295. }
  296. /**
  297. * Searches for the first occurence of the given argument,
  298. * beginning the search at index, and testing for equality
  299. * using the equals method.
  300. *
  301. * @param elem object to look for
  302. * @return the index of the first occurrence of the object
  303. * argument in this vector at position index or later in the
  304. * vector; returns -1 if the object is not found.
  305. */
  306. public final int indexOf(Object elem)
  307. {
  308. for (int i = 0; i < m_firstFree; i++)
  309. {
  310. if (m_map[i] == elem)
  311. return i;
  312. }
  313. return java.lang.Integer.MIN_VALUE;
  314. }
  315. /**
  316. * Searches for the first occurence of the given argument,
  317. * beginning the search at index, and testing for equality
  318. * using the equals method.
  319. *
  320. * @param elem Object to look for
  321. * @return the index of the first occurrence of the object
  322. * argument in this vector at position index or later in the
  323. * vector; returns -1 if the object is not found.
  324. */
  325. public final int lastIndexOf(Object elem)
  326. {
  327. for (int i = (m_firstFree - 1); i >= 0; i--)
  328. {
  329. if (m_map[i] == elem)
  330. return i;
  331. }
  332. return java.lang.Integer.MIN_VALUE;
  333. }
  334. /*
  335. * Reset the array to the supplied size.
  336. *
  337. * @param size
  338. */
  339. public final void setToSize(int size) {
  340. Object newMap[] = new Object[size];
  341. System.arraycopy(m_map, 0, newMap, 0, m_firstFree);
  342. m_mapSize = size;
  343. m_map = newMap;
  344. }
  345. /**
  346. * Returns clone of current ObjectVector
  347. *
  348. * @return clone of current ObjectVector
  349. */
  350. public Object clone()
  351. throws CloneNotSupportedException
  352. {
  353. return new ObjectVector(this);
  354. }
  355. }