35 * In most cases this will be an array of alternating
36 * key-value pairs. As it grows larger it is scaled
37 * up to a Hashtable.
38 * <p>
39 * This does no synchronization, if you need thread safety synchronize on
40 * another object before calling this.
41 *
42 * @author Georges Saab
43 * @author Scott Violet
44 */
45 class ArrayTable implements Cloneable {
46 // Our field for storage
47 private Object table = null;
48 private static final int ARRAY_BOUNDARY = 8;
49
50
51 /**
52 * Writes the passed in ArrayTable to the passed in ObjectOutputStream.
53 * The data is saved as an integer indicating how many key/value
54 * pairs are being archived, followed by the key/value pairs. If
55 * <code>table</code> is null, 0 will be written to <code>s</code>.
56 * <p>
57 * This is a convenience method that ActionMap/InputMap and
58 * AbstractAction use to avoid having the same code in each class.
59 */
60 static void writeArrayTable(ObjectOutputStream s, ArrayTable table) throws IOException {
61 Object keys[];
62
63 if (table == null || (keys = table.getKeys(null)) == null) {
64 s.writeInt(0);
65 }
66 else {
67 // Determine how many keys have Serializable values, when
68 // done all non-null values in keys identify the Serializable
69 // values.
70 int validCount = 0;
71
72 for (int counter = 0; counter < keys.length; counter++) {
73 Object key = keys[counter];
74
75 /* include in Serialization when both keys and values are Serializable */
234 table = (tmp.length == 0) ? null : tmp;
235 }
236 } else {
237 value = ((Hashtable)table).remove(key);
238 }
239 if (size()==ARRAY_BOUNDARY - 1 && !isArray()) {
240 shrink();
241 }
242 }
243 return value;
244 }
245
246 /**
247 * Removes all the mappings.
248 */
249 public void clear() {
250 table = null;
251 }
252
253 /*
254 * Returns a clone of the <code>ArrayTable</code>.
255 */
256 public Object clone() {
257 ArrayTable newArrayTable = new ArrayTable();
258 if (isArray()) {
259 Object[] array = (Object[])table;
260 for (int i = 0 ;i < array.length-1 ; i+=2) {
261 newArrayTable.put(array[i], array[i+1]);
262 }
263 } else {
264 Hashtable<?,?> tmp = (Hashtable)table;
265 Enumeration<?> keys = tmp.keys();
266 while (keys.hasMoreElements()) {
267 Object o = keys.nextElement();
268 newArrayTable.put(o,tmp.get(o));
269 }
270 }
271 return newArrayTable;
272 }
273
274 /**
275 * Returns the keys of the table, or <code>null</code> if there
276 * are currently no bindings.
277 * @param keys array of keys
278 * @return an array of bindings
279 */
280 public Object[] getKeys(Object[] keys) {
281 if (table == null) {
282 return null;
283 }
284 if (isArray()) {
285 Object[] array = (Object[])table;
286 if (keys == null) {
287 keys = new Object[array.length / 2];
288 }
289 for (int i = 0, index = 0 ;i < array.length-1 ; i+=2,
290 index++) {
291 keys[index] = array[i];
292 }
293 } else {
294 Hashtable<?,?> tmp = (Hashtable)table;
295 Enumeration<?> enum_ = tmp.keys();
|
35 * In most cases this will be an array of alternating
36 * key-value pairs. As it grows larger it is scaled
37 * up to a Hashtable.
38 * <p>
39 * This does no synchronization, if you need thread safety synchronize on
40 * another object before calling this.
41 *
42 * @author Georges Saab
43 * @author Scott Violet
44 */
45 class ArrayTable implements Cloneable {
46 // Our field for storage
47 private Object table = null;
48 private static final int ARRAY_BOUNDARY = 8;
49
50
51 /**
52 * Writes the passed in ArrayTable to the passed in ObjectOutputStream.
53 * The data is saved as an integer indicating how many key/value
54 * pairs are being archived, followed by the key/value pairs. If
55 * {@code table} is null, 0 will be written to {@code s}.
56 * <p>
57 * This is a convenience method that ActionMap/InputMap and
58 * AbstractAction use to avoid having the same code in each class.
59 */
60 static void writeArrayTable(ObjectOutputStream s, ArrayTable table) throws IOException {
61 Object keys[];
62
63 if (table == null || (keys = table.getKeys(null)) == null) {
64 s.writeInt(0);
65 }
66 else {
67 // Determine how many keys have Serializable values, when
68 // done all non-null values in keys identify the Serializable
69 // values.
70 int validCount = 0;
71
72 for (int counter = 0; counter < keys.length; counter++) {
73 Object key = keys[counter];
74
75 /* include in Serialization when both keys and values are Serializable */
234 table = (tmp.length == 0) ? null : tmp;
235 }
236 } else {
237 value = ((Hashtable)table).remove(key);
238 }
239 if (size()==ARRAY_BOUNDARY - 1 && !isArray()) {
240 shrink();
241 }
242 }
243 return value;
244 }
245
246 /**
247 * Removes all the mappings.
248 */
249 public void clear() {
250 table = null;
251 }
252
253 /*
254 * Returns a clone of the {@code ArrayTable}.
255 */
256 public Object clone() {
257 ArrayTable newArrayTable = new ArrayTable();
258 if (isArray()) {
259 Object[] array = (Object[])table;
260 for (int i = 0 ;i < array.length-1 ; i+=2) {
261 newArrayTable.put(array[i], array[i+1]);
262 }
263 } else {
264 Hashtable<?,?> tmp = (Hashtable)table;
265 Enumeration<?> keys = tmp.keys();
266 while (keys.hasMoreElements()) {
267 Object o = keys.nextElement();
268 newArrayTable.put(o,tmp.get(o));
269 }
270 }
271 return newArrayTable;
272 }
273
274 /**
275 * Returns the keys of the table, or {@code null} if there
276 * are currently no bindings.
277 * @param keys array of keys
278 * @return an array of bindings
279 */
280 public Object[] getKeys(Object[] keys) {
281 if (table == null) {
282 return null;
283 }
284 if (isArray()) {
285 Object[] array = (Object[])table;
286 if (keys == null) {
287 keys = new Object[array.length / 2];
288 }
289 for (int i = 0, index = 0 ;i < array.length-1 ; i+=2,
290 index++) {
291 keys[index] = array[i];
292 }
293 } else {
294 Hashtable<?,?> tmp = (Hashtable)table;
295 Enumeration<?> enum_ = tmp.keys();
|