1 /* 2 * Copyright (C) 2012 The Android Open Source Project 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 package com.android.inputmethod.latin.utils; 18 19 import java.util.Arrays; 20 21 // TODO: This class is not thread-safe. 22 public final class ResizableIntArray { 23 private int[] mArray; 24 private int mLength; 25 ResizableIntArray(final int capacity)26 public ResizableIntArray(final int capacity) { 27 reset(capacity); 28 } 29 get(final int index)30 public int get(final int index) { 31 if (index < mLength) { 32 return mArray[index]; 33 } 34 throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index); 35 } 36 addAt(final int index, final int val)37 public void addAt(final int index, final int val) { 38 if (index < mLength) { 39 mArray[index] = val; 40 } else { 41 mLength = index; 42 add(val); 43 } 44 } 45 add(final int val)46 public void add(final int val) { 47 final int currentLength = mLength; 48 ensureCapacity(currentLength + 1); 49 mArray[currentLength] = val; 50 mLength = currentLength + 1; 51 } 52 53 /** 54 * Calculate the new capacity of {@code mArray}. 55 * @param minimumCapacity the minimum capacity that the {@code mArray} should have. 56 * @return the new capacity that the {@code mArray} should have. Returns zero when there is no 57 * need to expand {@code mArray}. 58 */ calculateCapacity(final int minimumCapacity)59 private int calculateCapacity(final int minimumCapacity) { 60 final int currentCapcity = mArray.length; 61 if (currentCapcity < minimumCapacity) { 62 final int nextCapacity = currentCapcity * 2; 63 // The following is the same as return Math.max(minimumCapacity, nextCapacity); 64 return minimumCapacity > nextCapacity ? minimumCapacity : nextCapacity; 65 } 66 return 0; 67 } 68 ensureCapacity(final int minimumCapacity)69 private void ensureCapacity(final int minimumCapacity) { 70 final int newCapacity = calculateCapacity(minimumCapacity); 71 if (newCapacity > 0) { 72 // TODO: Implement primitive array pool. 73 mArray = Arrays.copyOf(mArray, newCapacity); 74 } 75 } 76 getLength()77 public int getLength() { 78 return mLength; 79 } 80 setLength(final int newLength)81 public void setLength(final int newLength) { 82 ensureCapacity(newLength); 83 mLength = newLength; 84 } 85 reset(final int capacity)86 public void reset(final int capacity) { 87 // TODO: Implement primitive array pool. 88 mArray = new int[capacity]; 89 mLength = 0; 90 } 91 getPrimitiveArray()92 public int[] getPrimitiveArray() { 93 return mArray; 94 } 95 set(final ResizableIntArray ip)96 public void set(final ResizableIntArray ip) { 97 // TODO: Implement primitive array pool. 98 mArray = ip.mArray; 99 mLength = ip.mLength; 100 } 101 copy(final ResizableIntArray ip)102 public void copy(final ResizableIntArray ip) { 103 final int newCapacity = calculateCapacity(ip.mLength); 104 if (newCapacity > 0) { 105 // TODO: Implement primitive array pool. 106 mArray = new int[newCapacity]; 107 } 108 System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength); 109 mLength = ip.mLength; 110 } 111 append(final ResizableIntArray src, final int startPos, final int length)112 public void append(final ResizableIntArray src, final int startPos, final int length) { 113 if (length == 0) { 114 return; 115 } 116 final int currentLength = mLength; 117 final int newLength = currentLength + length; 118 ensureCapacity(newLength); 119 System.arraycopy(src.mArray, startPos, mArray, currentLength, length); 120 mLength = newLength; 121 } 122 fill(final int value, final int startPos, final int length)123 public void fill(final int value, final int startPos, final int length) { 124 if (startPos < 0 || length < 0) { 125 throw new IllegalArgumentException("startPos=" + startPos + "; length=" + length); 126 } 127 final int endPos = startPos + length; 128 ensureCapacity(endPos); 129 Arrays.fill(mArray, startPos, endPos, value); 130 if (mLength < endPos) { 131 mLength = endPos; 132 } 133 } 134 135 /** 136 * Shift to the left by elementCount, discarding elementCount pointers at the start. 137 * @param elementCount how many elements to shift. 138 */ shift(final int elementCount)139 public void shift(final int elementCount) { 140 System.arraycopy(mArray, elementCount, mArray, 0, mLength - elementCount); 141 mLength -= elementCount; 142 } 143 144 @Override toString()145 public String toString() { 146 final StringBuilder sb = new StringBuilder(); 147 for (int i = 0; i < mLength; i++) { 148 if (i != 0) { 149 sb.append(","); 150 } 151 sb.append(mArray[i]); 152 } 153 return "[" + sb + "]"; 154 } 155 } 156