19370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka/* 29370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * Copyright (C) 2012 The Android Open Source Project 39370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * 49370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * use this file except in compliance with the License. You may obtain a copy of 69370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * the License at 79370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * 89370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 99370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * 109370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 119370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * License for the specific language governing permissions and limitations under 149370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka * the License. 159370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka */ 169370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 179370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaokapackage com.android.inputmethod.latin; 189370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 199370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaokaimport java.util.Arrays; 209370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 219370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka// TODO: This class is not thread-safe. 22a28a05e971cc242b338331a3b78276fa95188d19Tadashi G. Takaokapublic final class ResizableIntArray { 239370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka private int[] mArray; 249370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka private int mLength; 259370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 26c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public ResizableIntArray(final int capacity) { 279370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka reset(capacity); 289370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 299370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 30c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public int get(final int index) { 317abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (index < mLength) { 327abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka return mArray[index]; 33c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka } 347abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka throw new ArrayIndexOutOfBoundsException("length=" + mLength + "; index=" + index); 35c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka } 36c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka 37c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void add(final int index, final int val) { 387abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (index < mLength) { 397abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka mArray[index] = val; 407abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } else { 419370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mLength = index; 429370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka add(val); 439370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 449370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 459370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 46c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void add(final int val) { 477abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka final int currentLength = mLength; 487abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka ensureCapacity(currentLength + 1); 497abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka mArray[currentLength] = val; 507abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka mLength = currentLength + 1; 517abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 527abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka 537abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka /** 547abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka * Calculate the new capacity of {@code mArray}. 557abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka * @param minimumCapacity the minimum capacity that the {@code mArray} should have. 567abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka * @return the new capacity that the {@code mArray} should have. Returns zero when there is no 577abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka * need to expand {@code mArray}. 587abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka */ 597abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka private int calculateCapacity(final int minimumCapacity) { 607abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka final int currentCapcity = mArray.length; 617abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (currentCapcity < minimumCapacity) { 627abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka final int nextCapacity = currentCapcity * 2; 637abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka // The following is the same as return Math.max(minimumCapacity, nextCapacity); 647abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka return minimumCapacity > nextCapacity ? minimumCapacity : nextCapacity; 657abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 667abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka return 0; 679370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 689370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 69c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka private void ensureCapacity(final int minimumCapacity) { 707abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka final int newCapacity = calculateCapacity(minimumCapacity); 717abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (newCapacity > 0) { 729370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka // TODO: Implement primitive array pool. 737abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka mArray = Arrays.copyOf(mArray, newCapacity); 749370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 759370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 769370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 779370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka public int getLength() { 789370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka return mLength; 799370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 809370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 81c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void setLength(final int newLength) { 82c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka ensureCapacity(newLength); 83c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka mLength = newLength; 84c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka } 859370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 86c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void reset(final int capacity) { 879370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka // TODO: Implement primitive array pool. 889370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mArray = new int[capacity]; 899370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mLength = 0; 909370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 919370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 929370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka public int[] getPrimitiveArray() { 939370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka return mArray; 949370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 959370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 96c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void set(final ResizableIntArray ip) { 979370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka // TODO: Implement primitive array pool. 989370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mArray = ip.mArray; 999370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mLength = ip.mLength; 1009370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 1019370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 102c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void copy(final ResizableIntArray ip) { 1037abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka final int newCapacity = calculateCapacity(ip.mLength); 1047abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (newCapacity > 0) { 1057abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka // TODO: Implement primitive array pool. 1067abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka mArray = new int[newCapacity]; 1077abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 1089370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka System.arraycopy(ip.mArray, 0, mArray, 0, ip.mLength); 1099370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mLength = ip.mLength; 1109370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 1119370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka 112c49c85f835ecd14d09abb6d88c85a3303c566741Tadashi G. Takaoka public void append(final ResizableIntArray src, final int startPos, final int length) { 1137abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (length == 0) { 1147abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka return; 1157abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 1169370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka final int currentLength = mLength; 1179370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka final int newLength = currentLength + length; 1189370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka ensureCapacity(newLength); 1199370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka System.arraycopy(src.mArray, startPos, mArray, currentLength, length); 1209370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka mLength = newLength; 1219370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka } 1227abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka 1237abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka public void fill(final int value, final int startPos, final int length) { 1247abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (startPos < 0 || length < 0) { 1257abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka throw new IllegalArgumentException("startPos=" + startPos + "; length=" + length); 1267abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 1277abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka final int endPos = startPos + length; 1287abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka ensureCapacity(endPos); 1297abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka Arrays.fill(mArray, startPos, endPos, value); 1307abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka if (mLength < endPos) { 1317abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka mLength = endPos; 1327abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 1337abdcf1ed3113d3c121f6ff1b87a7464f079e141Tadashi G. Takaoka } 13464ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka 13564ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka @Override 13664ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka public String toString() { 13764ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka final StringBuilder sb = new StringBuilder(); 13864ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka for (int i = 0; i < mLength; i++) { 13964ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka if (i != 0) { 14064ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka sb.append(","); 14164ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka } 14264ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka sb.append(mArray[i]); 14364ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka } 14464ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka return "[" + sb + "]"; 14564ee09610024eb1436c51f9c9ef9fc3f77239d73Tadashi G. Takaoka } 1469370ab9adad3b4bc3af8bde52b6422b8d2b873e7Tadashi G. Takaoka} 147