in core/src/main/java/flex/messaging/io/amf/Amf3Input.java [574:664]
protected Object readArray() throws ClassNotFoundException, IOException {
int ref = readUInt29();
if ((ref & 1) == 0) // This is a reference.
return getObjectReference(ref >> 1);
int len = (ref >> 1);
Object array = null;
// First, look for any string based keys. If any non-ordinal indices were used,
// or if the Array is sparse, we represent the structure as a Map.
Map map = null;
for (; ; ) {
String name = readString();
if (name == null || name.length() == 0)
break;
if (map == null) {
map = (HashMap) ClassUtil.createDefaultInstance(HashMap.class, null, true /*validate*/);
array = map;
//Remember Object
objectTable.add(array);
if (isDebug)
trace.startECMAArray(objectTable.size() - 1);
}
if (isDebug)
trace.namedElement(name);
Object value = readObjectOneLevelDown(true);
ClassUtil.validateAssignment(map, name, value);
map.put(name, value);
}
// If we didn't find any string based keys, we have a dense Array, so we
// represent the structure as a List.
if (map == null) {
// Don't instantiate List/Array right away with the supplied size if it is more than
// INITIAL_ARRAY_CAPACITY in case the supplied size has been tampered. This at least
// requires the user to pass in the actual objects for the List/Array to grow beyond.
boolean useListTemporarily = false;
// Legacy Flex 1.5 behavior was to return a java.util.Collection for Array
if (context.legacyCollection || len > INITIAL_COLLECTION_CAPACITY) {
useListTemporarily = !context.legacyCollection;
ClassUtil.validateCreation(ArrayList.class);
int initialCapacity = len < INITIAL_COLLECTION_CAPACITY ? len : INITIAL_COLLECTION_CAPACITY;
array = new ArrayList(initialCapacity);
}
// Flex 2+ behavior is to return Object[] for AS3 Array
else {
ClassUtil.validateCreation(Object[].class);
array = new Object[len];
}
int objectId = rememberObject(array); // Remember the List/Object[].
if (isDebug)
trace.startAMFArray(objectTable.size() - 1);
for (int i = 0; i < len; i++) {
if (isDebug)
trace.arrayElement(i);
Object item = readObjectOneLevelDown(true);
ClassUtil.validateAssignment(array, i, item);
if (array instanceof ArrayList)
((ArrayList) array).add(item);
else
Array.set(array, i, item);
}
if (useListTemporarily) {
array = ((ArrayList) array).toArray();
objectTable.set(objectId, array);
}
} else {
for (int i = 0; i < len; i++) {
if (isDebug)
trace.arrayElement(i);
Object item = readObjectOneLevelDown(true);
String key = Integer.toString(i);
ClassUtil.validateAssignment(map, key, item);
map.put(key, item);
}
}
if (isDebug)
trace.endAMFArray();
return array;
}