Home | History | Annotate | Download | only in utils
      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 
     26     public ResizableIntArray(final int capacity) {
     27         reset(capacity);
     28     }
     29 
     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 
     37     public void add(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 
     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      */
     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 
     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 
     77     public int getLength() {
     78         return mLength;
     79     }
     80 
     81     public void setLength(final int newLength) {
     82         ensureCapacity(newLength);
     83         mLength = newLength;
     84     }
     85 
     86     public void reset(final int capacity) {
     87         // TODO: Implement primitive array pool.
     88         mArray = new int[capacity];
     89         mLength = 0;
     90     }
     91 
     92     public int[] getPrimitiveArray() {
     93         return mArray;
     94     }
     95 
     96     public void set(final ResizableIntArray ip) {
     97         // TODO: Implement primitive array pool.
     98         mArray = ip.mArray;
     99         mLength = ip.mLength;
    100     }
    101 
    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 
    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 
    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      */
    139     public void shift(final int elementCount) {
    140         System.arraycopy(mArray, elementCount, mArray, 0, mLength - elementCount);
    141         mLength -= elementCount;
    142     }
    143 
    144     @Override
    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