1. /*
  2. * $Header: /home/cvs/jakarta-commons/primitives/src/java/org/apache/commons/collections/primitives/ArrayUnsignedIntList.java,v 1.3 2003/10/16 20:49:36 scolebourne Exp $
  3. * ====================================================================
  4. * The Apache Software License, Version 1.1
  5. *
  6. * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
  7. * reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. *
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. *
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in
  18. * the documentation and/or other materials provided with the
  19. * distribution.
  20. *
  21. * 3. The end-user documentation included with the redistribution, if
  22. * any, must include the following acknowledgement:
  23. * "This product includes software developed by the
  24. * Apache Software Foundation (http://www.apache.org/)."
  25. * Alternately, this acknowledgement may appear in the software itself,
  26. * if and wherever such third-party acknowledgements normally appear.
  27. *
  28. * 4. The names "The Jakarta Project", "Commons", and "Apache Software
  29. * Foundation" must not be used to endorse or promote products derived
  30. * from this software without prior written permission. For written
  31. * permission, please contact apache@apache.org.
  32. *
  33. * 5. Products derived from this software may not be called "Apache"
  34. * nor may "Apache" appear in their names without prior written
  35. * permission of the Apache Software Foundation.
  36. *
  37. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  38. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  39. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  41. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  42. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  43. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  44. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  45. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  46. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  47. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  48. * SUCH DAMAGE.
  49. * ====================================================================
  50. *
  51. * This software consists of voluntary contributions made by many
  52. * individuals on behalf of the Apache Software Foundation. For more
  53. * information on the Apache Software Foundation, please see
  54. * <http://www.apache.org/>.
  55. *
  56. */
  57. package org.apache.commons.collections.primitives;
  58. import java.io.IOException;
  59. import java.io.ObjectInputStream;
  60. import java.io.ObjectOutputStream;
  61. import java.io.Serializable;
  62. /**
  63. * An {@link IntList} backed by an array of unsigned
  64. * <code>int</code> values.
  65. * This list stores <code>int</code> values
  66. * in the range [{@link #MIN_VALUE <code>0</code>},
  67. * {@link #MAX_VALUE <code>65535</code>}] in 16-bits
  68. * per element. Attempts to use elements outside this
  69. * range may cause an
  70. * {@link IllegalArgumentException IllegalArgumentException}
  71. * to be thrown.
  72. * <p />
  73. * This implementation supports all optional methods.
  74. *
  75. * @since Commons Primitives 1.0
  76. * @version $Revision: 1.3 $ $Date: 2003/10/16 20:49:36 $
  77. *
  78. * @author Rodney Waldhoff
  79. */
  80. public class ArrayUnsignedIntList extends RandomAccessLongList implements LongList, Serializable {
  81. // constructors
  82. //-------------------------------------------------------------------------
  83. /**
  84. * Construct an empty list with the default
  85. * initial capacity.
  86. */
  87. public ArrayUnsignedIntList() {
  88. this(8);
  89. }
  90. /**
  91. * Construct an empty list with the given
  92. * initial capacity.
  93. * @throws IllegalArgumentException when <i>initialCapacity</i> is negative
  94. */
  95. public ArrayUnsignedIntList(int initialCapacity) {
  96. if(initialCapacity < 0) {
  97. throw new IllegalArgumentException("capacity " + initialCapacity);
  98. }
  99. _data = new int[initialCapacity];
  100. _size = 0;
  101. }
  102. /**
  103. * Constructs a list containing the elements of the given collection,
  104. * in the order they are returned by that collection's iterator.
  105. *
  106. * @see AbstractLongCollection#addAll(LongCollection)
  107. * @param that the non-<code>null</code> collection of <code>int</code>s
  108. * to add
  109. * @throws NullPointerException if <i>that</i> is <code>null</code>
  110. */
  111. public ArrayUnsignedIntList(LongCollection that) {
  112. this(that.size());
  113. addAll(that);
  114. }
  115. // IntList methods
  116. //-------------------------------------------------------------------------
  117. /**
  118. * Returns the element at the specified position within
  119. * me.
  120. * By construction, the returned value will be
  121. * between {@link #MIN_VALUE} and {@link #MAX_VALUE}, inclusive.
  122. *
  123. * @param index the index of the element to return
  124. * @return the value of the element at the specified position
  125. * @throws IndexOutOfBoundsException if the specified index is out of range
  126. */
  127. public long get(int index) {
  128. checkRange(index);
  129. return toLong(_data[index]);
  130. }
  131. public int size() {
  132. return _size;
  133. }
  134. /**
  135. * Removes the element at the specified position in
  136. * (optional operation). Any subsequent elements
  137. * are shifted to the left, subtracting one from their
  138. * indices. Returns the element that was removed.
  139. * By construction, the returned value will be
  140. * between {@link #MIN_VALUE} and {@link #MAX_VALUE}, inclusive.
  141. *
  142. * @param index the index of the element to remove
  143. * @return the value of the element that was removed
  144. *
  145. * @throws UnsupportedOperationException when this operation is not
  146. * supported
  147. * @throws IndexOutOfBoundsException if the specified index is out of range
  148. */
  149. public long removeElementAt(int index) {
  150. checkRange(index);
  151. incrModCount();
  152. long oldval = toLong(_data[index]);
  153. int numtomove = _size - index - 1;
  154. if(numtomove > 0) {
  155. System.arraycopy(_data,index+1,_data,index,numtomove);
  156. }
  157. _size--;
  158. return oldval;
  159. }
  160. /**
  161. * Replaces the element at the specified
  162. * position in me with the specified element
  163. * (optional operation).
  164. * Throws {@link IllegalArgumentException} if <i>element</i>
  165. * is less than {@link #MIN_VALUE} or greater than {@link #MAX_VALUE}.
  166. *
  167. * @param index the index of the element to change
  168. * @param element the value to be stored at the specified position
  169. * @return the value previously stored at the specified position
  170. *
  171. * @throws UnsupportedOperationException when this operation is not
  172. * supported
  173. * @throws IndexOutOfBoundsException if the specified index is out of range
  174. */
  175. public long set(int index, long element) {
  176. assertValidUnsignedInt(element);
  177. checkRange(index);
  178. incrModCount();
  179. long oldval = toLong(_data[index]);
  180. _data[index] = fromLong(element);
  181. return oldval;
  182. }
  183. /**
  184. * Inserts the specified element at the specified position
  185. * (optional operation). Shifts the element currently
  186. * at that position (if any) and any subsequent elements to the
  187. * right, increasing their indices.
  188. * Throws {@link IllegalArgumentException} if <i>element</i>
  189. * is less than {@link #MIN_VALUE} or greater than {@link #MAX_VALUE}.
  190. *
  191. * @param index the index at which to insert the element
  192. * @param element the value to insert
  193. *
  194. * @throws UnsupportedOperationException when this operation is not
  195. * supported
  196. * @throws IllegalArgumentException if some aspect of the specified element
  197. * prevents it from being added to me
  198. * @throws IndexOutOfBoundsException if the specified index is out of range
  199. */
  200. public void add(int index, long element) {
  201. assertValidUnsignedInt(element);
  202. checkRangeIncludingEndpoint(index);
  203. incrModCount();
  204. ensureCapacity(_size+1);
  205. int numtomove = _size-index;
  206. System.arraycopy(_data,index,_data,index+1,numtomove);
  207. _data[index] = fromLong(element);
  208. _size++;
  209. }
  210. // capacity methods
  211. //-------------------------------------------------------------------------
  212. /**
  213. * Increases my capacity, if necessary, to ensure that I can hold at
  214. * least the number of elements specified by the minimum capacity
  215. * argument without growing.
  216. */
  217. public void ensureCapacity(int mincap) {
  218. incrModCount();
  219. if(mincap > _data.length) {
  220. int newcap = (_data.length * 3)/2 + 1;
  221. int[] olddata = _data;
  222. _data = new int[newcap < mincap ? mincap : newcap];
  223. System.arraycopy(olddata,0,_data,0,_size);
  224. }
  225. }
  226. /**
  227. * Reduce my capacity, if necessary, to match my
  228. * current {@link #size size}.
  229. */
  230. public void trimToSize() {
  231. incrModCount();
  232. if(_size < _data.length) {
  233. int[] olddata = _data;
  234. _data = new int[_size];
  235. System.arraycopy(olddata,0,_data,0,_size);
  236. }
  237. }
  238. // private methods
  239. //-------------------------------------------------------------------------
  240. private final long toLong(int value) {
  241. return ((long)value)&MAX_VALUE;
  242. }
  243. private final int fromLong(long value) {
  244. return (int)(value&MAX_VALUE);
  245. }
  246. private final void assertValidUnsignedInt(long value) throws IllegalArgumentException {
  247. if(value > MAX_VALUE) {
  248. throw new IllegalArgumentException(value + " > " + MAX_VALUE);
  249. }
  250. if(value < MIN_VALUE) {
  251. throw new IllegalArgumentException(value + " < " + MIN_VALUE);
  252. }
  253. }
  254. private void writeObject(ObjectOutputStream out) throws IOException{
  255. out.defaultWriteObject();
  256. out.writeInt(_data.length);
  257. for(int i=0;i<_size;i++) {
  258. out.writeInt(_data[i]);
  259. }
  260. }
  261. private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
  262. in.defaultReadObject();
  263. _data = new int[in.readInt()];
  264. for(int i=0;i<_size;i++) {
  265. _data[i] = in.readInt();
  266. }
  267. }
  268. private final void checkRange(int index) {
  269. if(index < 0 || index >= _size) {
  270. throw new IndexOutOfBoundsException("Should be at least 0 and less than " + _size + ", found " + index);
  271. }
  272. }
  273. private final void checkRangeIncludingEndpoint(int index) {
  274. if(index < 0 || index > _size) {
  275. throw new IndexOutOfBoundsException("Should be at least 0 and at most " + _size + ", found " + index);
  276. }
  277. }
  278. // attributes
  279. //-------------------------------------------------------------------------
  280. /**
  281. * The maximum possible unsigned 32-bit value.
  282. */
  283. public static final long MAX_VALUE = 0xFFFFFFFFL;
  284. /**
  285. * The minimum possible unsigned 32-bit value.
  286. */
  287. public static final long MIN_VALUE = 0L;
  288. private transient int[] _data = null;
  289. private int _size = 0;
  290. }