protected Object readArray()

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;
    }