/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.text;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
import libcore.util.EmptyArray;
class PackedObjectVector<E>
{
private int mColumns;
private int mRows;
private int mRowGapStart;
private int mRowGapLength;
private Object[] mValues;
public
PackedObjectVector(int columns)
{
mColumns = columns;
mValues = EmptyArray.OBJECT;
mRows = 0;
mRowGapStart = 0;
mRowGapLength = mRows;
}
public E
getValue(int row, int column)
{
if (row >= mRowGapStart)
row += mRowGapLength;
Object value = mValues[row * mColumns + column];
return (E) value;
}
public void
setValue(int row, int column, E value)
{
if (row >= mRowGapStart)
row += mRowGapLength;
mValues[row * mColumns + column] = value;
}
public void
insertAt(int row, E[] values)
{
moveRowGapTo(row);
if (mRowGapLength == 0)
growBuffer();
mRowGapStart++;
mRowGapLength--;
if (values == null)
for (int i = 0; i < mColumns; i++)
setValue(row, i, null);
else
for (int i = 0; i < mColumns; i++)
setValue(row, i, values[i]);
}
public void
deleteAt(int row, int count)
{
moveRowGapTo(row + count);
mRowGapStart -= count;
mRowGapLength += count;
if (mRowGapLength > size() * 2)
{
// dump();
// growBuffer();
}
}
public int
size()
{
return mRows - mRowGapLength;
}
public int
width()
{
return mColumns;
}
private void
growBuffer()
{
Object[] newvalues = ArrayUtils.newUnpaddedObjectArray(
GrowingArrayUtils.growSize(size()) * mColumns);
int newsize = newvalues.length / mColumns;
int after = mRows - (mRowGapStart + mRowGapLength);
System.arraycopy(mValues, 0, newvalues, 0, mColumns * mRowGapStart);
System.arraycopy(mValues, (mRows - after) * mColumns, newvalues, (newsize - after) * mColumns, after * mColumns);
mRowGapLength += newsize - mRows;
mRows = newsize;
mValues = newvalues;
}
private void
moveRowGapTo(int where)
{
if (where == mRowGapStart)
return;
if (where > mRowGapStart)
{
int moving = where + mRowGapLength - (mRowGapStart + mRowGapLength);
for (int i = mRowGapStart + mRowGapLength; i < mRowGapStart + mRowGapLength + moving; i++)
{
int destrow = i - (mRowGapStart + mRowGapLength) + mRowGapStart;
for (int j = 0; j < mColumns; j++)
{
Object val = mValues[i * mColumns + j];
mValues[destrow * mColumns + j] = val;
}
}
}
else /* where < mRowGapStart */
{
int moving = mRowGapStart - where;
for (int i = where + moving - 1; i >= where; i--)
{
int destrow = i - where + mRowGapStart + mRowGapLength - moving;
for (int j = 0; j < mColumns; j++)
{
Object val = mValues[i * mColumns + j];
mValues[destrow * mColumns + j] = val;
}
}
}
mRowGapStart = where;
}
public void // XXX
dump()
{
for (int i = 0; i < mRows; i++)
{
for (int j = 0; j < mColumns; j++)
{
Object val = mValues[i * mColumns + j];
if (i < mRowGapStart || i >= mRowGapStart + mRowGapLength)
System.out.print(val + " ");
else
System.out.print("(" + val + ") ");
}
System.out.print(" << \n");
}
System.out.print("-----\n\n");
}
}