1 /*
2  * Copyright (C) 2006 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 android.text;
18 
19 import com.android.internal.util.ArrayUtils;
20 import com.android.internal.util.GrowingArrayUtils;
21 
22 import libcore.util.EmptyArray;
23 
24 class PackedObjectVector<E>
25 {
26     private int mColumns;
27     private int mRows;
28 
29     private int mRowGapStart;
30     private int mRowGapLength;
31 
32     private Object[] mValues;
33 
34     public
PackedObjectVector(int columns)35     PackedObjectVector(int columns)
36     {
37         mColumns = columns;
38         mValues = EmptyArray.OBJECT;
39         mRows = 0;
40 
41         mRowGapStart = 0;
42         mRowGapLength = mRows;
43     }
44 
45     public E
getValue(int row, int column)46     getValue(int row, int column)
47     {
48         if (row >= mRowGapStart)
49             row += mRowGapLength;
50 
51         Object value = mValues[row * mColumns + column];
52 
53         return (E) value;
54     }
55 
56     public void
setValue(int row, int column, E value)57     setValue(int row, int column, E value)
58     {
59         if (row >= mRowGapStart)
60             row += mRowGapLength;
61 
62         mValues[row * mColumns + column] = value;
63     }
64 
65     public void
insertAt(int row, E[] values)66     insertAt(int row, E[] values)
67     {
68         moveRowGapTo(row);
69 
70         if (mRowGapLength == 0)
71             growBuffer();
72 
73         mRowGapStart++;
74         mRowGapLength--;
75 
76         if (values == null)
77             for (int i = 0; i < mColumns; i++)
78                 setValue(row, i, null);
79         else
80             for (int i = 0; i < mColumns; i++)
81                 setValue(row, i, values[i]);
82     }
83 
84     public void
deleteAt(int row, int count)85     deleteAt(int row, int count)
86     {
87         moveRowGapTo(row + count);
88 
89         mRowGapStart -= count;
90         mRowGapLength += count;
91 
92         if (mRowGapLength > size() * 2)
93         {
94             // dump();
95             // growBuffer();
96         }
97     }
98 
99     public int
size()100     size()
101     {
102         return mRows - mRowGapLength;
103     }
104 
105     public int
width()106     width()
107     {
108         return mColumns;
109     }
110 
111     private void
growBuffer()112     growBuffer()
113     {
114         Object[] newvalues = ArrayUtils.newUnpaddedObjectArray(
115                 GrowingArrayUtils.growSize(size()) * mColumns);
116         int newsize = newvalues.length / mColumns;
117         int after = mRows - (mRowGapStart + mRowGapLength);
118 
119         System.arraycopy(mValues, 0, newvalues, 0, mColumns * mRowGapStart);
120         System.arraycopy(mValues, (mRows - after) * mColumns, newvalues, (newsize - after) * mColumns, after * mColumns);
121 
122         mRowGapLength += newsize - mRows;
123         mRows = newsize;
124         mValues = newvalues;
125     }
126 
127     private void
moveRowGapTo(int where)128     moveRowGapTo(int where)
129     {
130         if (where == mRowGapStart)
131             return;
132 
133         if (where > mRowGapStart)
134         {
135             int moving = where + mRowGapLength - (mRowGapStart + mRowGapLength);
136 
137             for (int i = mRowGapStart + mRowGapLength; i < mRowGapStart + mRowGapLength + moving; i++)
138             {
139                 int destrow = i - (mRowGapStart + mRowGapLength) + mRowGapStart;
140 
141                 for (int j = 0; j < mColumns; j++)
142                 {
143                     Object val = mValues[i * mColumns + j];
144 
145                     mValues[destrow * mColumns + j] = val;
146                 }
147             }
148         }
149         else /* where < mRowGapStart */
150         {
151             int moving = mRowGapStart - where;
152 
153             for (int i = where + moving - 1; i >= where; i--)
154             {
155                 int destrow = i - where + mRowGapStart + mRowGapLength - moving;
156 
157                 for (int j = 0; j < mColumns; j++)
158                 {
159                     Object val = mValues[i * mColumns + j];
160 
161                     mValues[destrow * mColumns + j] = val;
162                 }
163             }
164         }
165 
166         mRowGapStart = where;
167     }
168 
169     public void // XXX
dump()170     dump()
171     {
172         for (int i = 0; i < mRows; i++)
173         {
174             for (int j = 0; j < mColumns; j++)
175             {
176                 Object val = mValues[i * mColumns + j];
177 
178                 if (i < mRowGapStart || i >= mRowGapStart + mRowGapLength)
179                     System.out.print(val + " ");
180                 else
181                     System.out.print("(" + val + ") ");
182             }
183 
184             System.out.print(" << \n");
185         }
186 
187         System.out.print("-----\n\n");
188     }
189 }
190