public void finaliseBands()

in src/main/java/org/apache/commons/compress/harmony/pack200/ClassBands.java [708:884]


    public void finaliseBands() {
        final int defaultMajorVersion = segmentHeader.getDefaultMajorVersion();
        for (int i = 0; i < class_flags.length; i++) {
            final int major = major_versions[i];
            if (major != defaultMajorVersion) {
                class_flags[i] |= 1 << 24;
                classFileVersionMajor.add(major);
                classFileVersionMinor.add(0);
            }
        }
        // Calculate code headers
        codeHeaders = new int[codeHandlerCount.size()];
        int removed = 0;
        for (int i = 0; i < codeHeaders.length; i++) {
            final int numHandlers = codeHandlerCount.get(i - removed);
            final int maxLocals = codeMaxLocals.get(i - removed);
            final int maxStack = codeMaxStack.get(i - removed);
            switch (numHandlers) {
            case 0: {
                final int header = maxLocals * 12 + maxStack + 1;
                if (header < 145 && maxStack < 12) {
                    codeHeaders[i] = header;
                }
                break;
            }
            case 1: {
                final int header = maxLocals * 8 + maxStack + 145;
                if (header < 209 && maxStack < 8) {
                    codeHeaders[i] = header;
                }
                break;
            }
            case 2: {
                final int header = maxLocals * 7 + maxStack + 209;
                if (header < 256 && maxStack < 7) {
                    codeHeaders[i] = header;
                }
                break;
            }
            default:
                break;
            }
            if (codeHeaders[i] != 0) { // Remove the redundant values from
                                       // codeHandlerCount, codeMaxLocals and
                                       // codeMaxStack
                codeHandlerCount.remove(i - removed);
                codeMaxLocals.remove(i - removed);
                codeMaxStack.remove(i - removed);
                removed++;
            } else if (!segment.getSegmentHeader().have_all_code_flags()) {
                codeFlags.add(Long.valueOf(0));
            }
        }

        // Compute any required IcLocals
        final IntList innerClassesN = new IntList();
        final List<IcTuple> icLocal = new ArrayList<>();
        for (int i = 0; i < class_this.length; i++) {
            final CPClass cpClass = class_this[i];
            final Set<CPClass> referencedInnerClasses = classReferencesInnerClass.get(cpClass);
            if (referencedInnerClasses != null) {
                int innerN = 0;
                final List<IcTuple> innerClasses = segment.getIcBands().getInnerClassesForOuter(cpClass.toString());
                if (innerClasses != null) {
                    for (final IcTuple element : innerClasses) {
                        referencedInnerClasses.remove(element.C);
                    }
                }
                for (final CPClass inner : referencedInnerClasses) {
                    final IcTuple icTuple = segment.getIcBands().getIcTuple(inner);
                    if (icTuple != null && !icTuple.isAnonymous()) {
                        // should transmit an icLocal entry
                        icLocal.add(icTuple);
                        innerN++;
                    }
                }
                if (innerN != 0) {
                    innerClassesN.add(innerN);
                    class_flags[i] |= 1 << 23;
                }
            }
        }
        class_InnerClasses_N = innerClassesN.toArray();
        class_InnerClasses_RC = new CPClass[icLocal.size()];
        class_InnerClasses_F = new int[icLocal.size()];
        classInnerClassesOuterRCN = new ArrayList<>();
        classInnerClassesNameRUN = new ArrayList<>();
        for (int i = 0; i < class_InnerClasses_RC.length; i++) {
            final IcTuple icTuple = icLocal.get(i);
            class_InnerClasses_RC[i] = icTuple.C;
            if (icTuple.C2 == null && icTuple.N == null) {
                class_InnerClasses_F[i] = 0;
            } else {
                if (icTuple.F == 0) {
                    class_InnerClasses_F[i] = 0x00010000;
                } else {
                    class_InnerClasses_F[i] = icTuple.F;
                }
                classInnerClassesOuterRCN.add(icTuple.C2);
                classInnerClassesNameRUN.add(icTuple.N);
            }
        }
        // Calculate any backwards calls from metadata bands
        final IntList classAttrCalls = new IntList();
        final IntList fieldAttrCalls = new IntList();
        final IntList methodAttrCalls = new IntList();
        final IntList codeAttrCalls = new IntList();

        if (class_RVA_bands.hasContent()) {
            classAttrCalls.add(class_RVA_bands.numBackwardsCalls());
        }
        if (class_RIA_bands.hasContent()) {
            classAttrCalls.add(class_RIA_bands.numBackwardsCalls());
        }
        if (field_RVA_bands.hasContent()) {
            fieldAttrCalls.add(field_RVA_bands.numBackwardsCalls());
        }
        if (field_RIA_bands.hasContent()) {
            fieldAttrCalls.add(field_RIA_bands.numBackwardsCalls());
        }
        if (method_RVA_bands.hasContent()) {
            methodAttrCalls.add(method_RVA_bands.numBackwardsCalls());
        }
        if (method_RIA_bands.hasContent()) {
            methodAttrCalls.add(method_RIA_bands.numBackwardsCalls());
        }
        if (method_RVPA_bands.hasContent()) {
            methodAttrCalls.add(method_RVPA_bands.numBackwardsCalls());
        }
        if (method_RIPA_bands.hasContent()) {
            methodAttrCalls.add(method_RIPA_bands.numBackwardsCalls());
        }
        if (method_AD_bands.hasContent()) {
            methodAttrCalls.add(method_AD_bands.numBackwardsCalls());
        }

        // Sort non-predefined attribute bands
        final Comparator<NewAttributeBands> comparator = (arg0, arg1) -> arg0.getFlagIndex() - arg1.getFlagIndex();
        classAttributeBands.sort(comparator);
        methodAttributeBands.sort(comparator);
        fieldAttributeBands.sort(comparator);
        codeAttributeBands.sort(comparator);

        for (final NewAttributeBands bands : classAttributeBands) {
            if (bands.isUsedAtLeastOnce()) {
                for (final int backwardsCallCount : bands.numBackwardsCalls()) {
                    classAttrCalls.add(backwardsCallCount);
                }
            }
        }
        for (final NewAttributeBands bands : methodAttributeBands) {
            if (bands.isUsedAtLeastOnce()) {
                for (final int backwardsCallCount : bands.numBackwardsCalls()) {
                    methodAttrCalls.add(backwardsCallCount);
                }
            }
        }
        for (final NewAttributeBands bands : fieldAttributeBands) {
            if (bands.isUsedAtLeastOnce()) {
                for (final int backwardsCallCount : bands.numBackwardsCalls()) {
                    fieldAttrCalls.add(backwardsCallCount);
                }
            }
        }
        for (final NewAttributeBands bands : codeAttributeBands) {
            if (bands.isUsedAtLeastOnce()) {
                for (final int backwardsCallCount : bands.numBackwardsCalls()) {
                    codeAttrCalls.add(backwardsCallCount);
                }
            }
        }

        class_attr_calls = classAttrCalls.toArray();
        field_attr_calls = fieldAttrCalls.toArray();
        method_attr_calls = methodAttrCalls.toArray();
        code_attr_calls = codeAttrCalls.toArray();
    }