Source Code Cross Referenced for ClassBands.java in  » Apache-Harmony-Java-SE » org-package » org » apache » harmony » pack200 » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » org package » org.apache.harmony.pack200 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:        package org.apache.harmony.pack200;
0018:
0019:        import java.io.IOException;
0020:        import java.io.InputStream;
0021:        import java.util.ArrayList;
0022:        import java.util.Iterator;
0023:        import java.util.List;
0024:
0025:        import org.apache.harmony.pack200.bytecode.Attribute;
0026:        import org.apache.harmony.pack200.bytecode.CPClass;
0027:        import org.apache.harmony.pack200.bytecode.CPNameAndType;
0028:        import org.apache.harmony.pack200.bytecode.CPUTF8;
0029:        import org.apache.harmony.pack200.bytecode.ClassConstantPool;
0030:        import org.apache.harmony.pack200.bytecode.ConstantValueAttribute;
0031:        import org.apache.harmony.pack200.bytecode.EnclosingMethodAttribute;
0032:        import org.apache.harmony.pack200.bytecode.ExceptionsAttribute;
0033:        import org.apache.harmony.pack200.bytecode.LineNumberTableAttribute;
0034:        import org.apache.harmony.pack200.bytecode.LocalVariableTableAttribute;
0035:        import org.apache.harmony.pack200.bytecode.LocalVariableTypeTableAttribute;
0036:        import org.apache.harmony.pack200.bytecode.SignatureAttribute;
0037:        import org.apache.harmony.pack200.bytecode.SourceFileAttribute;
0038:
0039:        /**
0040:         * Pack200 Class Bands
0041:         */
0042:        public class ClassBands extends BandSet {
0043:
0044:            private int[] classFieldCount;
0045:
0046:            private long[] classFlags;
0047:
0048:            private String[][] classInterfaces;
0049:
0050:            private int[] classMethodCount;
0051:
0052:            private String[] classSuper;
0053:
0054:            private String[] classThis;
0055:
0056:            private ArrayList[] classAttributes;
0057:
0058:            private int[] classVersionMajor;
0059:
0060:            private int[] classVersionMinor;
0061:
0062:            private IcTuple[][] icLocal;
0063:
0064:            private ArrayList[] codeAttributes;
0065:
0066:            private int[] codeHandlerCount;
0067:
0068:            private int[] codeMaxNALocals;
0069:
0070:            private int[] codeMaxStack;
0071:
0072:            private ArrayList[][] fieldAttributes;
0073:
0074:            private String[][] fieldDescr;
0075:
0076:            private long[][] fieldFlags;
0077:
0078:            private ArrayList[][] methodAttributes;
0079:
0080:            private String[][] methodDescr;
0081:
0082:            private long[][] methodFlags;
0083:
0084:            private AttributeLayoutMap attrMap;
0085:
0086:            private CpBands cpBands;
0087:
0088:            private SegmentOptions options;
0089:
0090:            private int classCount;
0091:
0092:            private int[] methodAttrCalls;
0093:
0094:            private int[][] codeHandlerStartP;
0095:
0096:            private int[][] codeHandlerEndPO;
0097:
0098:            private int[][] codeHandlerCatchPO;
0099:
0100:            private String[][] codeHandlerClassRCN;
0101:
0102:            /**
0103:             * @param segment
0104:             */
0105:            public ClassBands(Segment segment) {
0106:                super (segment);
0107:                this .attrMap = segment.getAttrDefinitionBands()
0108:                        .getAttributeDefinitionMap();
0109:                this .cpBands = segment.getCpBands();
0110:                this .classCount = header.getClassCount();
0111:                this .options = header.getOptions();
0112:
0113:            }
0114:
0115:            /*
0116:             * (non-Javadoc)
0117:             *
0118:             * @see org.apache.harmony.pack200.BandSet#unpack(java.io.InputStream)
0119:             */
0120:            public void unpack(InputStream in) throws IOException,
0121:                    Pack200Exception {
0122:                int classCount = header.getClassCount();
0123:                classThis = parseReferences("class_this", in, Codec.DELTA5,
0124:                        classCount, cpBands.getCpClass());
0125:                classSuper = parseReferences("class_super", in, Codec.DELTA5,
0126:                        classCount, cpBands.getCpClass());
0127:                int[] classInterfaceLengths = decodeBandInt(
0128:                        "class_interface_count", in, Codec.DELTA5, classCount);
0129:                classInterfaces = parseReferences("class_interface", in,
0130:                        Codec.DELTA5, classInterfaceLengths, cpBands
0131:                                .getCpClass());
0132:                classFieldCount = decodeBandInt("class_field_count", in,
0133:                        Codec.DELTA5, classCount);
0134:                classMethodCount = decodeBandInt("class_method_count", in,
0135:                        Codec.DELTA5, classCount);
0136:                parseFieldBands(in);
0137:                parseMethodBands(in);
0138:                parseClassAttrBands(in);
0139:                parseCodeBands(in);
0140:
0141:            }
0142:
0143:            private void parseFieldBands(InputStream in) throws IOException,
0144:                    Pack200Exception {
0145:                fieldDescr = parseReferences("field_descr", in, Codec.DELTA5,
0146:                        classFieldCount, cpBands.getCpDescriptor());
0147:                parseFieldAttrBands(in);
0148:            }
0149:
0150:            private void parseFieldAttrBands(InputStream in)
0151:                    throws IOException, Pack200Exception {
0152:                fieldFlags = parseFlags("field_flags", in, classFieldCount,
0153:                        Codec.UNSIGNED5, options.hasFieldFlagsHi());
0154:                int fieldAttrCount = SegmentUtils.countBit16(fieldFlags);
0155:                int[] fieldAttrCounts = decodeBandInt("field_attr_count", in,
0156:                        Codec.UNSIGNED5, fieldAttrCount);
0157:                int[][] fieldAttrIndexes = decodeBandInt("field_attr_indexes",
0158:                        in, Codec.UNSIGNED5, fieldAttrCounts);
0159:                int callCount = getCallCount(fieldAttrIndexes, fieldFlags,
0160:                        AttributeLayout.CONTEXT_FIELD);
0161:                int[] fieldAttrCalls = decodeBandInt("field_attr_calls", in,
0162:                        Codec.UNSIGNED5, callCount);
0163:
0164:                // Assign empty field attributes
0165:                fieldAttributes = new ArrayList[classCount][];
0166:                for (int i = 0; i < classCount; i++) {
0167:                    fieldAttributes[i] = new ArrayList[fieldFlags[i].length];
0168:                    for (int j = 0; j < fieldFlags[i].length; j++) {
0169:                        fieldAttributes[i][j] = new ArrayList();
0170:                    }
0171:                }
0172:
0173:                AttributeLayout constantValueLayout = attrMap
0174:                        .getAttributeLayout("ConstantValue",
0175:                                AttributeLayout.CONTEXT_FIELD);
0176:                int constantCount = SegmentUtils.countMatches(fieldFlags,
0177:                        constantValueLayout);
0178:                int[] field_constantValue_KQ = decodeBandInt(
0179:                        "field_ConstantValue_KQ", in, Codec.UNSIGNED5,
0180:                        constantCount);
0181:                int constantValueIndex = 0;
0182:
0183:                AttributeLayout signatureLayout = attrMap.getAttributeLayout(
0184:                        AttributeLayout.ATTRIBUTE_SIGNATURE,
0185:                        AttributeLayout.CONTEXT_FIELD);
0186:                int signatureCount = SegmentUtils.countMatches(fieldFlags,
0187:                        signatureLayout);
0188:                int[] fieldSignatureRS = decodeBandInt("field_Signature_RS",
0189:                        in, Codec.UNSIGNED5, signatureCount);
0190:                int signatureIndex = 0;
0191:
0192:                int backwardsCallsUsed = parseFieldMetadataBands(in,
0193:                        fieldAttrCalls);
0194:
0195:                // Parse non-predefined attribute bands
0196:                int backwardsCallIndex = backwardsCallsUsed;
0197:                int limit = options.hasFieldFlagsHi() ? 62 : 31;
0198:                AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
0199:                int[] counts = new int[limit + 1];
0200:                List[] otherAttributes = new List[limit + 1];
0201:                for (int i = 0; i < limit; i++) {
0202:                    AttributeLayout layout = attrMap.getAttributeLayout(i,
0203:                            AttributeLayout.CONTEXT_FIELD);
0204:                    if (layout != null && !(layout.isDefaultLayout())) {
0205:                        otherLayouts[i] = layout;
0206:                        counts[i] = SegmentUtils.countMatches(fieldFlags,
0207:                                layout);
0208:                    }
0209:                }
0210:                for (int i = 0; i < counts.length; i++) {
0211:                    if (counts[i] > 0) {
0212:                        NewAttributeBands bands = attrMap
0213:                                .getAttributeBands(otherLayouts[i]);
0214:                        otherAttributes[i] = bands.parseAttributes(in,
0215:                                counts[i]);
0216:                        int numBackwardsCallables = otherLayouts[i]
0217:                                .numBackwardsCallables();
0218:                        if (numBackwardsCallables > 0) {
0219:                            int[] backwardsCalls = new int[numBackwardsCallables];
0220:                            System.arraycopy(fieldAttrCalls,
0221:                                    backwardsCallIndex, backwardsCalls, 0,
0222:                                    numBackwardsCallables);
0223:                            bands.setBackwardsCalls(backwardsCalls);
0224:                            backwardsCallIndex += numBackwardsCallables;
0225:                        }
0226:                    }
0227:                }
0228:
0229:                for (int i = 0; i < classCount; i++) {
0230:                    for (int j = 0; j < fieldFlags[i].length; j++) {
0231:                        long flag = fieldFlags[i][j];
0232:                        if (constantValueLayout.matches(flag)) {
0233:                            // we've got a value to read
0234:                            long result = field_constantValue_KQ[constantValueIndex];
0235:                            String desc = fieldDescr[i][j];
0236:                            int colon = desc.indexOf(':');
0237:                            String type = desc.substring(colon + 1);
0238:                            if (type.equals("B") || type.equals("S")
0239:                                    || type.equals("C") || type.equals("Z"))
0240:                                type = "I";
0241:                            Object value = constantValueLayout.getValue(result,
0242:                                    type, cpBands.getConstantPool());
0243:                            fieldAttributes[i][j]
0244:                                    .add(new ConstantValueAttribute(value));
0245:                            constantValueIndex++;
0246:                        }
0247:                        if (signatureLayout.matches(flag)) {
0248:                            // we've got a signature attribute
0249:                            long result = fieldSignatureRS[signatureIndex];
0250:                            String desc = fieldDescr[i][j];
0251:                            int colon = desc.indexOf(':');
0252:                            String type = desc.substring(colon + 1);
0253:                            CPUTF8 value = new CPUTF8((String) signatureLayout
0254:                                    .getValue(result, type, cpBands
0255:                                            .getConstantPool()),
0256:                                    ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
0257:                            fieldAttributes[i][j].add(new SignatureAttribute(
0258:                                    value));
0259:                            signatureIndex++;
0260:                        }
0261:                        // Non-predefined attributes
0262:                        for (int k = 0; k < otherLayouts.length; k++) {
0263:                            if (otherLayouts[k] != null
0264:                                    && otherLayouts[k].matches(flag)) {
0265:                                // Add the next attribute
0266:                                fieldAttributes[i][j].add(otherAttributes[k]
0267:                                        .get(0));
0268:                                otherAttributes[k].remove(0);
0269:                            }
0270:                        }
0271:                    }
0272:                }
0273:            }
0274:
0275:            private void parseMethodBands(InputStream in) throws IOException,
0276:                    Pack200Exception {
0277:                methodDescr = parseReferences("method_descr", in,
0278:                        Codec.MDELTA5, classMethodCount, cpBands
0279:                                .getCpDescriptor());
0280:                parseMethodAttrBands(in);
0281:            }
0282:
0283:            private void parseMethodAttrBands(InputStream in)
0284:                    throws IOException, Pack200Exception {
0285:                methodFlags = parseFlags("method_flags", in, classMethodCount,
0286:                        Codec.UNSIGNED5, options.hasMethodFlagsHi());
0287:                int methodAttrCount = SegmentUtils.countBit16(methodFlags);
0288:                int[] methodAttrCounts = decodeBandInt("method_attr_count", in,
0289:                        Codec.UNSIGNED5, methodAttrCount);
0290:                int[][] methodAttrIndexes = decodeBandInt(
0291:                        "method_attr_indexes", in, Codec.UNSIGNED5,
0292:                        methodAttrCounts);
0293:                int callCount = getCallCount(methodAttrIndexes, methodFlags,
0294:                        AttributeLayout.CONTEXT_METHOD);
0295:                methodAttrCalls = decodeBandInt("code_attr_calls", in,
0296:                        Codec.UNSIGNED5, callCount);
0297:
0298:                // assign empty method attributes
0299:                methodAttributes = new ArrayList[classCount][];
0300:                for (int i = 0; i < classCount; i++) {
0301:                    methodAttributes[i] = new ArrayList[methodFlags[i].length];
0302:                    for (int j = 0; j < methodFlags[i].length; j++) {
0303:                        methodAttributes[i][j] = new ArrayList();
0304:                    }
0305:                }
0306:
0307:                // Parse method exceptions attributes
0308:                AttributeLayout methodExceptionsLayout = attrMap
0309:                        .getAttributeLayout(
0310:                                AttributeLayout.ATTRIBUTE_EXCEPTIONS,
0311:                                AttributeLayout.CONTEXT_METHOD);
0312:                int count = SegmentUtils.countMatches(methodFlags,
0313:                        methodExceptionsLayout);
0314:                int[] numExceptions = decodeBandInt("method_Exceptions_n", in,
0315:                        Codec.UNSIGNED5, count);
0316:                String[][] methodExceptionsRS = parseReferences(
0317:                        "method_Exceptions_RC", in, Codec.UNSIGNED5,
0318:                        numExceptions, cpBands.getCpClass());
0319:
0320:                // Parse method signature attributes
0321:                AttributeLayout methodSignatureLayout = attrMap
0322:                        .getAttributeLayout(
0323:                                AttributeLayout.ATTRIBUTE_SIGNATURE,
0324:                                AttributeLayout.CONTEXT_METHOD);
0325:                int count1 = SegmentUtils.countMatches(methodFlags,
0326:                        methodSignatureLayout);
0327:                long[] methodSignatureRS = decodeBandLong(
0328:                        "method_signature_RS", in, Codec.UNSIGNED5, count1);
0329:
0330:                // Parse method metadata bands
0331:                int backwardsCallsUsed = parseMethodMetadataBands(in,
0332:                        methodAttrCalls);
0333:
0334:                // Parse non-predefined attribute bands
0335:                int backwardsCallIndex = backwardsCallsUsed;
0336:                int limit = options.hasMethodFlagsHi() ? 62 : 31;
0337:                AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
0338:                int[] counts = new int[limit + 1];
0339:                List[] otherAttributes = new List[limit + 1];
0340:                for (int i = 0; i < limit; i++) {
0341:                    AttributeLayout layout = attrMap.getAttributeLayout(i,
0342:                            AttributeLayout.CONTEXT_METHOD);
0343:                    if (layout != null && !(layout.isDefaultLayout())) {
0344:                        otherLayouts[i] = layout;
0345:                        counts[i] = SegmentUtils.countMatches(methodFlags,
0346:                                layout);
0347:                    }
0348:                }
0349:                for (int i = 0; i < counts.length; i++) {
0350:                    if (counts[i] > 0) {
0351:                        NewAttributeBands bands = attrMap
0352:                                .getAttributeBands(otherLayouts[i]);
0353:                        otherAttributes[i] = bands.parseAttributes(in,
0354:                                counts[i]);
0355:                        int numBackwardsCallables = otherLayouts[i]
0356:                                .numBackwardsCallables();
0357:                        if (numBackwardsCallables > 0) {
0358:                            int[] backwardsCalls = new int[numBackwardsCallables];
0359:                            System.arraycopy(methodAttrCalls,
0360:                                    backwardsCallIndex, backwardsCalls, 0,
0361:                                    numBackwardsCallables);
0362:                            bands.setBackwardsCalls(backwardsCalls);
0363:                            backwardsCallIndex += numBackwardsCallables;
0364:                        }
0365:                    }
0366:                }
0367:
0368:                // Add attributes to the attribute arrays
0369:                int methodExceptionsIndex = 0;
0370:                int methodSignatureIndex = 0;
0371:                for (int i = 0; i < methodAttributes.length; i++) {
0372:                    for (int j = 0; j < methodAttributes[i].length; j++) {
0373:                        long flag = methodFlags[i][j];
0374:                        if (methodExceptionsLayout.matches(flag)) {
0375:                            int n = numExceptions[methodExceptionsIndex];
0376:                            String[] exceptions = methodExceptionsRS[methodExceptionsIndex];
0377:                            CPClass[] exceptionClasses = new CPClass[n];
0378:                            for (int k = 0; k < n; k++) {
0379:                                exceptionClasses[k] = new CPClass(exceptions[k]);
0380:                            }
0381:                            methodAttributes[i][j].add(new ExceptionsAttribute(
0382:                                    exceptionClasses));
0383:                            methodExceptionsIndex++;
0384:                        }
0385:                        if (methodSignatureLayout.matches(flag)) {
0386:                            // We've got a signature attribute
0387:                            long result = methodSignatureRS[methodSignatureIndex];
0388:                            String desc = methodDescr[i][j];
0389:                            int colon = desc.indexOf(':');
0390:                            String type = desc.substring(colon + 1);
0391:                            // TODO Got to get better at this ... in any case, it should
0392:                            // be e.g. KIB or KIH
0393:                            if (type.equals("B") || type.equals("H"))
0394:                                type = "I";
0395:                            Object value = methodSignatureLayout.getValue(
0396:                                    result, type, cpBands.getConstantPool());
0397:                            methodAttributes[i][j]
0398:                                    .add(new ConstantValueAttribute(value));
0399:                            methodSignatureIndex++;
0400:                        }
0401:                        // Non-predefined attributes
0402:                        for (int k = 0; k < otherLayouts.length; k++) {
0403:                            if (otherLayouts[k] != null
0404:                                    && otherLayouts[k].matches(flag)) {
0405:                                // Add the next attribute
0406:                                methodAttributes[i][j].add(otherAttributes[k]
0407:                                        .get(0));
0408:                                otherAttributes[k].remove(0);
0409:                            }
0410:                        }
0411:                    }
0412:                }
0413:            }
0414:
0415:            private int getCallCount(int[][] methodAttrIndexes, long[][] flags,
0416:                    int context) throws Pack200Exception {
0417:                int callCount = 0;
0418:                for (int i = 0; i < methodAttrIndexes.length; i++) {
0419:                    for (int j = 0; j < methodAttrIndexes[i].length; j++) {
0420:                        int index = methodAttrIndexes[i][j];
0421:                        AttributeLayout layout = attrMap.getAttributeLayout(
0422:                                index, context);
0423:                        callCount += layout.numBackwardsCallables();
0424:                    }
0425:                }
0426:                int layoutsUsed = 0;
0427:                for (int i = 0; i < flags.length; i++) {
0428:                    for (int j = 0; j < flags[i].length; j++) {
0429:                        layoutsUsed |= flags[i][j];
0430:                    }
0431:                }
0432:                for (int i = 0; i < 26; i++) {
0433:                    if ((layoutsUsed & 1 << i) != 0) {
0434:                        AttributeLayout layout = attrMap.getAttributeLayout(i,
0435:                                context);
0436:                        callCount += layout.numBackwardsCallables();
0437:                    }
0438:                }
0439:                return callCount;
0440:            }
0441:
0442:            private void parseClassAttrBands(InputStream in)
0443:                    throws IOException, Pack200Exception {
0444:                String[] cpUTF8 = cpBands.getCpUTF8();
0445:                String[] cpClass = cpBands.getCpClass();
0446:
0447:                // Prepare empty attribute lists
0448:                classAttributes = new ArrayList[classCount];
0449:                for (int i = 0; i < classCount; i++) {
0450:                    classAttributes[i] = new ArrayList();
0451:                }
0452:
0453:                classFlags = parseFlags("class_flags", in, classCount,
0454:                        Codec.UNSIGNED5, options.hasClassFlagsHi());
0455:                int classAttrCount = SegmentUtils.countBit16(classFlags);
0456:                int[] classAttrCounts = decodeBandInt("class_attr_count", in,
0457:                        Codec.UNSIGNED5, classAttrCount);
0458:                int[][] classAttrIndexes = decodeBandInt("class_attr_indexes",
0459:                        in, Codec.UNSIGNED5, classAttrCounts);
0460:                int callCount = getCallCount(classAttrIndexes,
0461:                        new long[][] { classFlags },
0462:                        AttributeLayout.CONTEXT_CLASS);
0463:                int[] classAttrCalls = decodeBandInt("class_attr_calls", in,
0464:                        Codec.UNSIGNED5, callCount);
0465:
0466:                AttributeLayout sourceFileLayout = attrMap.getAttributeLayout(
0467:                        AttributeLayout.ATTRIBUTE_SOURCE_FILE,
0468:                        AttributeLayout.CONTEXT_CLASS);
0469:                int sourceFileCount = SegmentUtils.countMatches(classFlags,
0470:                        sourceFileLayout);
0471:                int[] classSourceFile = decodeBandInt("class_SourceFile_RUN",
0472:                        in, Codec.UNSIGNED5, sourceFileCount);
0473:
0474:                AttributeLayout enclosingMethodLayout = attrMap
0475:                        .getAttributeLayout(
0476:                                AttributeLayout.ATTRIBUTE_ENCLOSING_METHOD,
0477:                                AttributeLayout.CONTEXT_CLASS);
0478:                int enclosingMethodCount = SegmentUtils.countMatches(
0479:                        classFlags, enclosingMethodLayout);
0480:                String[] enclosingMethodRC = parseReferences(
0481:                        "class_EnclosingMethod_RC", in, Codec.UNSIGNED5,
0482:                        enclosingMethodCount, cpClass);
0483:                String[] enclosingMethodRDN = parseReferences(
0484:                        "class_EnclosingMethod_RDN", in, Codec.UNSIGNED5,
0485:                        enclosingMethodCount, cpBands.getCpDescriptor());
0486:
0487:                AttributeLayout signatureLayout = attrMap.getAttributeLayout(
0488:                        AttributeLayout.ATTRIBUTE_SIGNATURE,
0489:                        AttributeLayout.CONTEXT_CLASS);
0490:                int signatureCount = SegmentUtils.countMatches(classFlags,
0491:                        signatureLayout);
0492:                int[] classSignature = decodeBandInt("class_Signature_RS", in,
0493:                        Codec.UNSIGNED5, signatureCount);
0494:
0495:                int backwardsCallsUsed = parseClassMetadataBands(in,
0496:                        classAttrCalls);
0497:
0498:                AttributeLayout innerClassLayout = attrMap.getAttributeLayout(
0499:                        AttributeLayout.ATTRIBUTE_INNER_CLASSES,
0500:                        AttributeLayout.CONTEXT_CLASS);
0501:                int innerClassCount = SegmentUtils.countMatches(classFlags,
0502:                        innerClassLayout);
0503:                int[] classInnerClassesN = decodeBandInt(
0504:                        "class_InnerClasses_N", in, Codec.UNSIGNED5,
0505:                        innerClassCount);
0506:                int[][] classInnerClassesRC = decodeBandInt(
0507:                        "class_InnerClasses_RC", in, Codec.UNSIGNED5,
0508:                        classInnerClassesN);
0509:                int[][] classInnerClassesF = decodeBandInt(
0510:                        "class_InnerClasses_F", in, Codec.UNSIGNED5,
0511:                        classInnerClassesN);
0512:                int flagsCount = 0;
0513:                for (int i = 0; i < classInnerClassesF.length; i++) {
0514:                    for (int j = 0; j < classInnerClassesF[i].length; j++) {
0515:                        if (classInnerClassesF[i][j] != 0) {
0516:                            flagsCount++;
0517:                        }
0518:                    }
0519:                }
0520:                int[] classInnerClassesOuterRCN = decodeBandInt(
0521:                        "class_InnerClasses_outer_RCN", in, Codec.UNSIGNED5,
0522:                        flagsCount);
0523:                int[] classInnerClassesNameRUN = decodeBandInt(
0524:                        "class_InnerClasses_name_RUN", in, Codec.UNSIGNED5,
0525:                        flagsCount);
0526:
0527:                AttributeLayout versionLayout = attrMap.getAttributeLayout(
0528:                        AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION,
0529:                        AttributeLayout.CONTEXT_CLASS);
0530:                int versionCount = SegmentUtils.countMatches(classFlags,
0531:                        versionLayout);
0532:                int[] classFileVersionMinorH = decodeBandInt(
0533:                        "class_file_version_minor_H", in, Codec.UNSIGNED5,
0534:                        versionCount);
0535:                int[] classFileVersionMajorH = decodeBandInt(
0536:                        "class_file_version_major_H", in, Codec.UNSIGNED5,
0537:                        versionCount);
0538:                if (versionCount > 0) {
0539:                    classVersionMajor = new int[classCount];
0540:                    classVersionMinor = new int[classCount];
0541:                }
0542:                int defaultVersionMajor = header.getDefaultClassMajorVersion();
0543:                int defaultVersionMinor = header.getDefaultClassMinorVersion();
0544:
0545:                // Parse non-predefined attribute bands
0546:                int backwardsCallIndex = backwardsCallsUsed;
0547:                int limit = options.hasClassFlagsHi() ? 62 : 31;
0548:                AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
0549:                int[] counts = new int[limit + 1];
0550:                List[] otherAttributes = new List[limit + 1];
0551:                for (int i = 0; i < limit; i++) {
0552:                    AttributeLayout layout = attrMap.getAttributeLayout(i,
0553:                            AttributeLayout.CONTEXT_CLASS);
0554:                    if (layout != null && !(layout.isDefaultLayout())) {
0555:                        otherLayouts[i] = layout;
0556:                        counts[i] = SegmentUtils.countMatches(classFlags,
0557:                                layout);
0558:                    }
0559:                }
0560:                for (int i = 0; i < counts.length; i++) {
0561:                    if (counts[i] > 0) {
0562:                        NewAttributeBands bands = attrMap
0563:                                .getAttributeBands(otherLayouts[i]);
0564:                        otherAttributes[i] = bands.parseAttributes(in,
0565:                                counts[i]);
0566:                        int numBackwardsCallables = otherLayouts[i]
0567:                                .numBackwardsCallables();
0568:                        if (numBackwardsCallables > 0) {
0569:                            int[] backwardsCalls = new int[numBackwardsCallables];
0570:                            System.arraycopy(classAttrCalls,
0571:                                    backwardsCallIndex, backwardsCalls, 0,
0572:                                    numBackwardsCallables);
0573:                            bands.setBackwardsCalls(backwardsCalls);
0574:                            backwardsCallIndex += numBackwardsCallables;
0575:                        }
0576:                    }
0577:                }
0578:
0579:                // Now process the attribute bands we have parsed
0580:                int sourceFileIndex = 0;
0581:                int enclosingMethodIndex = 0;
0582:                int signatureIndex = 0;
0583:                int innerClassIndex = 0;
0584:                int innerClassC2NIndex = 0;
0585:                int versionIndex = 0;
0586:                icLocal = new IcTuple[classCount][];
0587:                for (int i = 0; i < classCount; i++) {
0588:                    long flag = classFlags[i];
0589:
0590:                    if (sourceFileLayout.matches(flag)) {
0591:                        long result = classSourceFile[sourceFileIndex];
0592:                        String value = (String) sourceFileLayout.getValue(
0593:                                result, cpBands.getConstantPool());
0594:                        if (value == null) {
0595:                            // Remove package prefix
0596:                            String className = classThis[i]
0597:                                    .substring(classThis[i].lastIndexOf('/') + 1);
0598:                            className = className.substring(className
0599:                                    .lastIndexOf('.') + 1);
0600:
0601:                            // Remove mangled nested class names
0602:                            char[] chars = className.toCharArray();
0603:                            int index = -1;
0604:                            for (int j = 0; j < chars.length; j++) {
0605:                                if (chars[j] <= 0x2D) {
0606:                                    index = j;
0607:                                    break;
0608:                                }
0609:                            }
0610:                            if (index > -1) {
0611:                                className = className.substring(0, index);
0612:                            }
0613:                            // Add .java to the end
0614:                            value = className + ".java";
0615:                        }
0616:                        classAttributes[i].add(new SourceFileAttribute(value));
0617:                        sourceFileIndex++;
0618:                    }
0619:                    if (enclosingMethodLayout.matches(flag)) {
0620:                        CPClass theClass = new CPClass(
0621:                                enclosingMethodRC[enclosingMethodIndex]);
0622:                        CPNameAndType theMethod = new CPNameAndType(
0623:                                enclosingMethodRDN[enclosingMethodIndex]);
0624:                        classAttributes[i].add(new EnclosingMethodAttribute(
0625:                                theClass, theMethod));
0626:                        enclosingMethodIndex++;
0627:                    }
0628:                    if (signatureLayout.matches(flag)) {
0629:                        long result = classSignature[signatureIndex];
0630:                        Object value = signatureLayout.getValue(result, cpBands
0631:                                .getConstantPool());
0632:                        classAttributes[i]
0633:                                .add(new ConstantValueAttribute(value));
0634:                        signatureIndex++;
0635:                    }
0636:                    if (innerClassLayout.matches(flag)) {
0637:                        // Just create the tuples for now because the attributes are
0638:                        // decided at the end when creating class constant pools
0639:                        icLocal[i] = new IcTuple[classInnerClassesN[innerClassIndex]];
0640:                        for (int j = 0; j < icLocal[i].length; j++) {
0641:                            IcTuple icTuple = new IcTuple();
0642:                            icTuple.C = cpClass[classInnerClassesRC[innerClassIndex][j]];
0643:                            icTuple.F = classInnerClassesF[innerClassIndex][j];
0644:                            if (icTuple.F != 0) {
0645:                                icTuple.C2 = cpClass[classInnerClassesOuterRCN[innerClassC2NIndex]];
0646:                                icTuple.N = cpUTF8[classInnerClassesNameRUN[innerClassC2NIndex]];
0647:                                innerClassC2NIndex++;
0648:                            } else {
0649:                                // Get from icBands
0650:                                IcBands icBands = segment.getIcBands();
0651:                                IcTuple[] icAll = icBands.getIcTuples();
0652:                                for (int k = 0; k < icAll.length; k++) {
0653:                                    if (icAll[k].C.equals(icTuple.C)) {
0654:                                        icTuple.C2 = icAll[k].C2;
0655:                                        icTuple.N = icAll[k].N;
0656:                                        break;
0657:                                    }
0658:                                }
0659:                            }
0660:                            icLocal[i][j] = icTuple;
0661:                        }
0662:                        innerClassIndex++;
0663:                    }
0664:                    if (versionLayout.matches(flag)) {
0665:                        classVersionMajor[i] = classFileVersionMajorH[versionIndex];
0666:                        classVersionMinor[i] = classFileVersionMinorH[versionIndex];
0667:                        versionIndex++;
0668:                    } else if (classVersionMajor != null) {
0669:                        // Fill in with defaults
0670:                        classVersionMajor[i] = defaultVersionMajor;
0671:                        classVersionMinor[i] = defaultVersionMinor;
0672:                    }
0673:                    // Non-predefined attributes
0674:                    for (int j = 0; j < otherLayouts.length; j++) {
0675:                        if (otherLayouts[j] != null
0676:                                && otherLayouts[j].matches(flag)) {
0677:                            // Add the next attribute
0678:                            classAttributes[i].add(otherAttributes[j].get(0));
0679:                            otherAttributes[j].remove(0);
0680:                        }
0681:                    }
0682:                }
0683:            }
0684:
0685:            private void parseCodeBands(InputStream in)
0686:                    throws Pack200Exception, IOException {
0687:                AttributeLayout layout = attrMap.getAttributeLayout(
0688:                        AttributeLayout.ATTRIBUTE_CODE,
0689:                        AttributeLayout.CONTEXT_METHOD);
0690:
0691:                int codeCount = SegmentUtils.countMatches(methodFlags, layout);
0692:                int[] codeHeaders = decodeBandInt("code_headers", in,
0693:                        Codec.BYTE1, codeCount);
0694:                int codeSpecialHeader = 0;
0695:                for (int i = 0; i < codeCount; i++) {
0696:                    if (codeHeaders[i] == 0)
0697:                        codeSpecialHeader++;
0698:                }
0699:                int[] codeMaxStackSpecials = decodeBandInt("code_max_stack",
0700:                        in, Codec.UNSIGNED5, codeSpecialHeader);
0701:                int[] codeMaxNALocalsSpecials = decodeBandInt(
0702:                        "code_max_na_locals", in, Codec.UNSIGNED5,
0703:                        codeSpecialHeader);
0704:                int[] codeHandlerCountSpecials = decodeBandInt(
0705:                        "code_handler_count", in, Codec.UNSIGNED5,
0706:                        codeSpecialHeader);
0707:
0708:                codeMaxStack = new int[codeCount];
0709:                codeMaxNALocals = new int[codeCount];
0710:                codeHandlerCount = new int[codeCount];
0711:                int special = 0;
0712:                for (int i = 0; i < codeCount; i++) {
0713:                    int header = 0xff & codeHeaders[i];
0714:                    if (header < 0) {
0715:                        throw new IllegalStateException("Shouldn't get here");
0716:                    } else if (header == 0) {
0717:                        codeMaxStack[i] = codeMaxStackSpecials[special];
0718:                        codeMaxNALocals[i] = codeMaxNALocalsSpecials[special];
0719:                        codeHandlerCount[i] = codeHandlerCountSpecials[special];
0720:                        special++;
0721:                    } else if (header <= 144) {
0722:                        codeMaxStack[i] = (header - 1) % 12;
0723:                        codeMaxNALocals[i] = (header - 1) / 12;
0724:                        codeHandlerCount[i] = 0;
0725:                    } else if (header <= 208) {
0726:                        codeMaxStack[i] = (header - 145) % 8;
0727:                        codeMaxNALocals[i] = (header - 145) / 8;
0728:                        codeHandlerCount[i] = 1;
0729:                    } else if (header <= 255) {
0730:                        codeMaxStack[i] = (header - 209) % 7;
0731:                        codeMaxNALocals[i] = (header - 209) / 7;
0732:                        codeHandlerCount[i] = 2;
0733:                    } else {
0734:                        throw new IllegalStateException(
0735:                                "Shouldn't get here either");
0736:                    }
0737:                }
0738:                codeHandlerStartP = decodeBandInt("code_handler_start_P", in,
0739:                        Codec.BCI5, codeHandlerCount);
0740:                codeHandlerEndPO = decodeBandInt("code_handler_end_PO", in,
0741:                        Codec.BRANCH5, codeHandlerCount);
0742:                codeHandlerCatchPO = decodeBandInt("code_handler_catch_PO", in,
0743:                        Codec.BRANCH5, codeHandlerCount);
0744:                int[][] codeHandlerClassRCNints = decodeBandInt(
0745:                        "code_handler_class_RCN", in, Codec.UNSIGNED5,
0746:                        codeHandlerCount);
0747:                // The codeHandlerClassRCN band contains incremented references to
0748:                // cp_Class so we can't use parseReferences(..) here.
0749:                String[] cpClass = cpBands.getCpClass();
0750:                codeHandlerClassRCN = new String[codeHandlerClassRCNints.length][];
0751:                for (int i = 0; i < codeHandlerClassRCNints.length; i++) {
0752:                    codeHandlerClassRCN[i] = new String[codeHandlerClassRCNints[i].length];
0753:                    for (int j = 0; j < codeHandlerClassRCNints[i].length; j++) {
0754:                        int handlerClassReference = codeHandlerClassRCNints[i][j];
0755:                        if (handlerClassReference == 0) {
0756:                            codeHandlerClassRCN[i][j] = null;
0757:                        } else {
0758:                            codeHandlerClassRCN[i][j] = cpClass[handlerClassReference - 1];
0759:                        }
0760:                    }
0761:                }
0762:
0763:                int codeFlagsCount = segment.getSegmentHeader().getOptions()
0764:                        .hasAllCodeFlags() ? codeCount : codeSpecialHeader;
0765:
0766:                codeAttributes = new ArrayList[codeFlagsCount];
0767:                for (int i = 0; i < codeAttributes.length; i++) {
0768:                    codeAttributes[i] = new ArrayList();
0769:                }
0770:                parseCodeAttrBands(in, codeFlagsCount);
0771:            }
0772:
0773:            private void parseCodeAttrBands(InputStream in, int codeFlagsCount)
0774:                    throws IOException, Pack200Exception {
0775:                long[] codeFlags = parseFlags("code_flags", in, codeFlagsCount,
0776:                        Codec.UNSIGNED5, segment.getSegmentHeader()
0777:                                .getOptions().hasCodeFlagsHi());
0778:                int codeAttrCount = SegmentUtils.countBit16(codeFlags);
0779:                int[] codeAttrCounts = decodeBandInt("code_attr_count", in,
0780:                        Codec.UNSIGNED5, codeAttrCount);
0781:                int[][] codeAttrIndexes = decodeBandInt("code_attr_indexes",
0782:                        in, Codec.UNSIGNED5, codeAttrCounts);
0783:                int callCount = 0;
0784:                for (int i = 0; i < codeAttrIndexes.length; i++) {
0785:                    for (int j = 0; j < codeAttrIndexes[i].length; j++) {
0786:                        int index = codeAttrIndexes[i][j];
0787:                        AttributeLayout layout = attrMap.getAttributeLayout(
0788:                                index, AttributeLayout.CONTEXT_CODE);
0789:                        callCount += layout.numBackwardsCallables();
0790:                    }
0791:                }
0792:                int[] codeAttrCalls = decodeBandInt("code_attr_calls", in,
0793:                        Codec.UNSIGNED5, callCount);
0794:
0795:                AttributeLayout lineNumberTableLayout = attrMap
0796:                        .getAttributeLayout(
0797:                                AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE,
0798:                                AttributeLayout.CONTEXT_CODE);
0799:                int lineNumberTableCount = SegmentUtils.countMatches(codeFlags,
0800:                        lineNumberTableLayout);
0801:                int[] lineNumberTableN = decodeBandInt(
0802:                        "code_LineNumberTable_N", in, Codec.UNSIGNED5,
0803:                        lineNumberTableCount);
0804:                int[][] lineNumberTableBciP = decodeBandInt(
0805:                        "code_LineNumberTable_bci_P", in, Codec.BCI5,
0806:                        lineNumberTableN);
0807:                int[][] lineNumberTableLine = decodeBandInt(
0808:                        "code_LineNumberTable_line", in, Codec.UNSIGNED5,
0809:                        lineNumberTableN);
0810:
0811:                AttributeLayout localVariableTableLayout = attrMap
0812:                        .getAttributeLayout(
0813:                                AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE,
0814:                                AttributeLayout.CONTEXT_CODE);
0815:                AttributeLayout localVariableTypeTableLayout = attrMap
0816:                        .getAttributeLayout(
0817:                                AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE,
0818:                                AttributeLayout.CONTEXT_CODE);
0819:
0820:                int lengthLocalVariableNBand = SegmentUtils.countMatches(
0821:                        codeFlags, localVariableTableLayout);
0822:                int[] localVariableTableN = decodeBandInt(
0823:                        "code_LocalVariableTable_N", in, Codec.UNSIGNED5,
0824:                        lengthLocalVariableNBand);
0825:                int[][] localVariableTableBciP = decodeBandInt(
0826:                        "code_LocalVariableTable_bci_P", in, Codec.BCI5,
0827:                        localVariableTableN);
0828:                int[][] localVariableTableSpanO = decodeBandInt(
0829:                        "code_LocalVariableTable_span_O", in, Codec.BRANCH5,
0830:                        localVariableTableN);
0831:                CPUTF8[][] localVariableTableNameRU = stringsToCPUTF8(parseReferences(
0832:                        "code_LocalVariableTable_name_RU", in, Codec.UNSIGNED5,
0833:                        localVariableTableN, cpBands.getCpUTF8()));
0834:                CPUTF8[][] localVariableTableTypeRS = stringsToCPUTF8(parseReferences(
0835:                        "code_LocalVariableTable_type_RS", in, Codec.UNSIGNED5,
0836:                        localVariableTableN, cpBands.getCpSignature()));
0837:                int[][] localVariableTableSlot = decodeBandInt(
0838:                        "code_LocalVariableTable_slot", in, Codec.UNSIGNED5,
0839:                        localVariableTableN);
0840:
0841:                // Fix up localVariableTableTypeRS - for some reason,
0842:                // native signatures end up in DOMAINNORMALASCIIZ
0843:                // while nonnatives end up in DOMAINSIGNATUREASCIIZ.
0844:                // TODO: is this the right thing to do?
0845:                for (int x = 0; x < localVariableTableTypeRS.length; x++) {
0846:                    for (int y = 0; y < localVariableTableTypeRS[x].length; y++) {
0847:                        CPUTF8 element = localVariableTableTypeRS[x][y];
0848:                        // TODO: come up with a better test for native vs nonnative signatures?
0849:                        if (element.underlyingString().length() > 2) {
0850:                            element
0851:                                    .setDomain(ClassConstantPool.DOMAIN_SIGNATUREASCIIZ);
0852:                        } else {
0853:                            element
0854:                                    .setDomain(ClassConstantPool.DOMAIN_NORMALASCIIZ);
0855:                        }
0856:                    }
0857:                }
0858:
0859:                int lengthLocalVariableTypeTableNBand = SegmentUtils
0860:                        .countMatches(codeFlags, localVariableTypeTableLayout);
0861:                int[] localVariableTypeTableN = decodeBandInt(
0862:                        "code_LocalVariableTypeTable_N", in, Codec.UNSIGNED5,
0863:                        lengthLocalVariableTypeTableNBand);
0864:                int[][] localVariableTypeTableBciP = decodeBandInt(
0865:                        "code_LocalVariableTypeTable_bci_P", in, Codec.BCI5,
0866:                        localVariableTypeTableN);
0867:                int[][] localVariableTypeTableSpanO = decodeBandInt(
0868:                        "code_LocalVariableTypeTable_span_O", in,
0869:                        Codec.BRANCH5, localVariableTypeTableN);
0870:                CPUTF8[][] localVariableTypeTableNameRU = stringsToCPUTF8(parseReferences(
0871:                        "code_LocalVariableTypeTable_name_RU", in,
0872:                        Codec.UNSIGNED5, localVariableTypeTableN, cpBands
0873:                                .getCpUTF8()));
0874:                CPUTF8[][] localVariableTypeTableTypeRS = stringsToCPUTF8(parseReferences(
0875:                        "code_LocalVariableTypeTable_type_RS", in,
0876:                        Codec.UNSIGNED5, localVariableTypeTableN, cpBands
0877:                                .getCpSignature()));
0878:                int[][] localVariableTypeTableSlot = decodeBandInt(
0879:                        "code_LocalVariableTypeTable_slot", in,
0880:                        Codec.UNSIGNED5, localVariableTypeTableN);
0881:
0882:                // Parse non-predefined attribute bands
0883:                int backwardsCallIndex = 0;
0884:                int limit = options.hasCodeFlagsHi() ? 62 : 31;
0885:                AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
0886:                int[] counts = new int[limit + 1];
0887:                List[] otherAttributes = new List[limit + 1];
0888:                for (int i = 0; i < limit; i++) {
0889:                    AttributeLayout layout = attrMap.getAttributeLayout(i,
0890:                            AttributeLayout.CONTEXT_CODE);
0891:                    if (layout != null && !(layout.isDefaultLayout())) {
0892:                        otherLayouts[i] = layout;
0893:                        counts[i] = SegmentUtils
0894:                                .countMatches(codeFlags, layout);
0895:                    }
0896:                }
0897:                for (int i = 0; i < counts.length; i++) {
0898:                    if (counts[i] > 0) {
0899:                        NewAttributeBands bands = attrMap
0900:                                .getAttributeBands(otherLayouts[i]);
0901:                        otherAttributes[i] = bands.parseAttributes(in,
0902:                                counts[i]);
0903:                        int numBackwardsCallables = otherLayouts[i]
0904:                                .numBackwardsCallables();
0905:                        if (numBackwardsCallables > 0) {
0906:                            int[] backwardsCalls = new int[numBackwardsCallables];
0907:                            System.arraycopy(codeAttrCalls, backwardsCallIndex,
0908:                                    backwardsCalls, 0, numBackwardsCallables);
0909:                            bands.setBackwardsCalls(backwardsCalls);
0910:                            backwardsCallIndex += numBackwardsCallables;
0911:                        }
0912:                    }
0913:                }
0914:
0915:                int lineNumberIndex = 0;
0916:                int lvtIndex = 0;
0917:                int lvttIndex = 0;
0918:                for (int i = 0; i < codeFlagsCount; i++) {
0919:                    if (lineNumberTableLayout.matches(codeFlags[i])) {
0920:                        LineNumberTableAttribute lnta = new LineNumberTableAttribute(
0921:                                lineNumberTableN[lineNumberIndex],
0922:                                lineNumberTableBciP[lineNumberIndex],
0923:                                lineNumberTableLine[lineNumberIndex]);
0924:                        lineNumberIndex++;
0925:                        codeAttributes[i].add(lnta);
0926:                    }
0927:                    if (localVariableTableLayout.matches(codeFlags[i])) {
0928:                        LocalVariableTableAttribute lvta = new LocalVariableTableAttribute(
0929:                                localVariableTableN[lvtIndex],
0930:                                localVariableTableBciP[lvtIndex],
0931:                                localVariableTableSpanO[lvtIndex],
0932:                                localVariableTableNameRU[lvtIndex],
0933:                                localVariableTableTypeRS[lvtIndex],
0934:                                localVariableTableSlot[lvtIndex]);
0935:                        lvtIndex++;
0936:                        codeAttributes[i].add(lvta);
0937:                    }
0938:                    if (localVariableTypeTableLayout.matches(codeFlags[i])) {
0939:                        LocalVariableTypeTableAttribute lvtta = new LocalVariableTypeTableAttribute(
0940:                                localVariableTypeTableN[lvttIndex],
0941:                                localVariableTypeTableBciP[lvttIndex],
0942:                                localVariableTypeTableSpanO[lvttIndex],
0943:                                localVariableTypeTableNameRU[lvttIndex],
0944:                                localVariableTypeTableTypeRS[lvttIndex],
0945:                                localVariableTypeTableSlot[lvttIndex]);
0946:                        lvttIndex++;
0947:                        codeAttributes[i].add(lvtta);
0948:                    }
0949:                    // Non-predefined attributes
0950:                    for (int j = 0; j < otherLayouts.length; j++) {
0951:                        if (otherLayouts[j] != null
0952:                                && otherLayouts[j].matches(codeFlags[i])) {
0953:                            // Add the next attribute
0954:                            codeAttributes[i].add(otherAttributes[j].get(0));
0955:                            otherAttributes[j].remove(0);
0956:                        }
0957:                    }
0958:                }
0959:
0960:            }
0961:
0962:            private CPUTF8[][] stringsToCPUTF8(String[][] strings) {
0963:                CPUTF8[][] cpUTF8s = new CPUTF8[strings.length][];
0964:                for (int i = 0; i < strings.length; i++) {
0965:                    cpUTF8s[i] = new CPUTF8[strings[i].length];
0966:                    for (int j = 0; j < strings[i].length; j++) {
0967:                        cpUTF8s[i][j] = new CPUTF8(strings[i][j],
0968:                                ClassConstantPool.DOMAIN_NORMALASCIIZ);
0969:                    }
0970:                }
0971:                return cpUTF8s;
0972:            }
0973:
0974:            private CPUTF8[] stringsToCPUTF8(String[] strings) {
0975:                CPUTF8[] cpUTF8s = new CPUTF8[strings.length];
0976:                for (int i = 0; i < strings.length; i++) {
0977:                    cpUTF8s[i] = new CPUTF8(strings[i],
0978:                            ClassConstantPool.DOMAIN_UNDEFINED);
0979:                }
0980:                return cpUTF8s;
0981:            }
0982:
0983:            private int parseFieldMetadataBands(InputStream in,
0984:                    int[] fieldAttrCalls) throws Pack200Exception, IOException {
0985:                int backwardsCallsUsed = 0;
0986:                String[] RxA = new String[] { "RVA", "RIA" };
0987:
0988:                AttributeLayout rvaLayout = attrMap.getAttributeLayout(
0989:                        AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
0990:                        AttributeLayout.CONTEXT_FIELD);
0991:                AttributeLayout riaLayout = attrMap
0992:                        .getAttributeLayout(
0993:                                AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
0994:                                AttributeLayout.CONTEXT_FIELD);
0995:
0996:                int rvaCount = SegmentUtils.countMatches(fieldFlags, rvaLayout);
0997:                int riaCount = SegmentUtils.countMatches(fieldFlags, riaLayout);
0998:                int[] RxACount = new int[] { rvaCount, riaCount };
0999:                int[] backwardsCalls = new int[] { 0, 0 };
1000:                if (rvaCount > 0) {
1001:                    backwardsCalls[0] = fieldAttrCalls[0];
1002:                    backwardsCallsUsed++;
1003:                    if (riaCount > 0) {
1004:                        backwardsCalls[1] = fieldAttrCalls[1];
1005:                        backwardsCallsUsed++;
1006:                    }
1007:                } else if (riaCount > 0) {
1008:                    backwardsCalls[1] = fieldAttrCalls[0];
1009:                    backwardsCallsUsed++;
1010:                }
1011:                MetadataBandGroup[] mb = parseMetadata(in, RxA, RxACount,
1012:                        backwardsCalls, "field");
1013:                Iterator rvaAttributesIterator = mb[0].getAttributes()
1014:                        .iterator();
1015:                Iterator riaAttributesIterator = mb[1].getAttributes()
1016:                        .iterator();
1017:                for (int i = 0; i < fieldFlags.length; i++) {
1018:                    for (int j = 0; j < fieldFlags[i].length; j++) {
1019:                        if (rvaLayout.matches(fieldFlags[i][j])) {
1020:                            fieldAttributes[i][j].add(rvaAttributesIterator
1021:                                    .next());
1022:                        }
1023:                        if (riaLayout.matches(fieldFlags[i][j])) {
1024:                            fieldAttributes[i][j].add(riaAttributesIterator
1025:                                    .next());
1026:                        }
1027:                    }
1028:                }
1029:                return backwardsCallsUsed;
1030:            }
1031:
1032:            private MetadataBandGroup[] parseMetadata(InputStream in,
1033:                    String[] RxA, int[] RxACount, int[] backwardsCallCounts,
1034:                    String contextName) throws IOException, Pack200Exception {
1035:                MetadataBandGroup[] mbg = new MetadataBandGroup[RxA.length];
1036:                for (int i = 0; i < RxA.length; i++) {
1037:                    mbg[i] = new MetadataBandGroup(RxA[i]);
1038:                    String rxa = RxA[i];
1039:                    if (rxa.indexOf("P") >= 0) {
1040:                        mbg[i].param_NB = decodeBandInt(contextName + "_" + rxa
1041:                                + "_param_NB", in, Codec.BYTE1, RxACount[i]);
1042:                    }
1043:                    int pairCount = 0;
1044:                    if (!rxa.equals("AD")) {
1045:                        mbg[i].anno_N = decodeBandInt(contextName + "_" + rxa
1046:                                + "_anno_N", in, Codec.UNSIGNED5, RxACount[i]);
1047:                        mbg[i].type_RS = stringsToCPUTF8(parseReferences(
1048:                                contextName + "_" + rxa + "_type_RS", in,
1049:                                Codec.UNSIGNED5, mbg[i].anno_N, cpBands
1050:                                        .getCpSignature()));
1051:                        mbg[i].pair_N = decodeBandInt(contextName + "_" + rxa
1052:                                + "_pair_N", in, Codec.UNSIGNED5, mbg[i].anno_N);
1053:                        for (int j = 0; j < mbg[i].pair_N.length; j++) {
1054:                            for (int k = 0; k < mbg[i].pair_N[j].length; k++) {
1055:                                pairCount += mbg[i].pair_N[j][k];
1056:                            }
1057:                        }
1058:
1059:                        mbg[i].name_RU = stringsToCPUTF8(parseReferences(
1060:                                contextName + "_" + rxa + "_name_RU", in,
1061:                                Codec.UNSIGNED5, pairCount, cpBands.getCpUTF8()));
1062:                    }
1063:                    mbg[i].T = decodeBandInt(contextName + "_" + rxa + "_T",
1064:                            in, Codec.BYTE1, pairCount + backwardsCallCounts[i]);
1065:                    int ICount = 0, DCount = 0, FCount = 0, JCount = 0, cCount = 0, eCount = 0, sCount = 0, arrayCount = 0, atCount = 0;
1066:                    for (int j = 0; j < mbg[i].T.length; j++) {
1067:                        char c = (char) mbg[i].T[j];
1068:                        switch (c) {
1069:                        case 'B':
1070:                        case 'C':
1071:                        case 'I':
1072:                        case 'S':
1073:                        case 'Z':
1074:                            ICount++;
1075:                            break;
1076:                        case 'D':
1077:                            DCount++;
1078:                            break;
1079:                        case 'F':
1080:                            FCount++;
1081:                            break;
1082:                        case 'J':
1083:                            JCount++;
1084:                            break;
1085:                        case 'c':
1086:                            cCount++;
1087:                            break;
1088:                        case 'e':
1089:                            eCount++;
1090:                            break;
1091:                        case 's':
1092:                            sCount++;
1093:                            break;
1094:                        case '[':
1095:                            arrayCount++;
1096:                            break;
1097:                        case '@':
1098:                            atCount++;
1099:                            break;
1100:                        }
1101:                    }
1102:                    mbg[i].caseI_KI = parseCPIntReferences(contextName + "_"
1103:                            + rxa + "_caseI_KI", in, Codec.UNSIGNED5, ICount);
1104:                    mbg[i].caseD_KD = parseCPDoubleReferences(contextName + "_"
1105:                            + rxa + "_caseD_KD", in, Codec.UNSIGNED5, DCount);
1106:                    mbg[i].caseF_KF = parseCPFloatReferences(contextName + "_"
1107:                            + rxa + "_caseF_KF", in, Codec.UNSIGNED5, FCount);
1108:                    mbg[i].caseJ_KJ = parseCPLongReferences(contextName + "_"
1109:                            + rxa + "_caseJ_KJ", in, Codec.UNSIGNED5, JCount);
1110:                    mbg[i].casec_RS = parseCPUTF8References(contextName + "_"
1111:                            + rxa + "_casec_RS", in, Codec.UNSIGNED5, cCount);
1112:                    mbg[i].caseet_RS = parseReferences(contextName + "_" + rxa
1113:                            + "_caseet_RS", in, Codec.UNSIGNED5, eCount,
1114:                            cpBands.getCpSignature());
1115:                    mbg[i].caseec_RU = parseReferences(contextName + "_" + rxa
1116:                            + "_caseec_RU", in, Codec.UNSIGNED5, eCount,
1117:                            cpBands.getCpUTF8());
1118:                    mbg[i].cases_RU = parseCPUTF8References(contextName + "_"
1119:                            + rxa + "_cases_RU", in, Codec.UNSIGNED5, sCount);
1120:                    mbg[i].casearray_N = decodeBandInt(contextName + "_" + rxa
1121:                            + "_casearray_N", in, Codec.UNSIGNED5, arrayCount);
1122:                    mbg[i].nesttype_RS = parseCPUTF8References(contextName
1123:                            + "_" + rxa + "_nesttype_RS", in, Codec.UNSIGNED5,
1124:                            atCount);
1125:                    mbg[i].nestpair_N = decodeBandInt(contextName + "_" + rxa
1126:                            + "_nestpair_N", in, Codec.UNSIGNED5, atCount);
1127:                    int nestPairCount = 0;
1128:                    for (int j = 0; j < mbg[i].nestpair_N.length; j++) {
1129:                        nestPairCount += mbg[i].nestpair_N[j];
1130:                    }
1131:                    mbg[i].nestname_RU = parseCPUTF8References(contextName
1132:                            + "_" + rxa + "_nestname_RU", in, Codec.UNSIGNED5,
1133:                            nestPairCount);
1134:                }
1135:                return mbg;
1136:            }
1137:
1138:            private int parseMethodMetadataBands(InputStream in,
1139:                    int[] methodAttrCalls) throws Pack200Exception, IOException {
1140:                int backwardsCallsUsed = 0;
1141:                String[] RxA = new String[] { "RVA", "RIA", "RVPA", "RIPA",
1142:                        "AD" };
1143:                int[] rxaCounts = new int[] { 0, 0, 0, 0, 0 };
1144:                int[] backwardsCalls = new int[5];
1145:                int methodAttrIndex = 0;
1146:                for (int i = 0; i < backwardsCalls.length; i++) {
1147:                    if (rxaCounts[i] > 0) {
1148:                        backwardsCallsUsed++;
1149:                        backwardsCalls[i] = methodAttrCalls[methodAttrIndex];
1150:                        methodAttrIndex++;
1151:                    } else {
1152:                        backwardsCalls[i] = 0;
1153:                    }
1154:                }
1155:                AttributeLayout rvaLayout = attrMap.getAttributeLayout(
1156:                        AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
1157:                        AttributeLayout.CONTEXT_METHOD);
1158:                AttributeLayout riaLayout = attrMap
1159:                        .getAttributeLayout(
1160:                                AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
1161:                                AttributeLayout.CONTEXT_METHOD);
1162:                AttributeLayout rvpaLayout = attrMap
1163:                        .getAttributeLayout(
1164:                                AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
1165:                                AttributeLayout.CONTEXT_METHOD);
1166:                AttributeLayout ripaLayout = attrMap
1167:                        .getAttributeLayout(
1168:                                AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
1169:                                AttributeLayout.CONTEXT_METHOD);
1170:                AttributeLayout adLayout = attrMap.getAttributeLayout(
1171:                        AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT,
1172:                        AttributeLayout.CONTEXT_METHOD);
1173:                AttributeLayout[] rxaLayouts = new AttributeLayout[] {
1174:                        rvaLayout, riaLayout, rvpaLayout, ripaLayout, adLayout };
1175:
1176:                for (int i = 0; i < rxaLayouts.length; i++) {
1177:                    rxaCounts[i] = SegmentUtils.countMatches(methodFlags,
1178:                            rxaLayouts[i]);
1179:                }
1180:                MetadataBandGroup[] mbgs = parseMetadata(in, RxA, rxaCounts,
1181:                        backwardsCalls, "method");
1182:                Iterator[] attributeIterators = new Iterator[RxA.length];
1183:                for (int i = 0; i < mbgs.length; i++) {
1184:                    attributeIterators[i] = mbgs[i].getAttributes().iterator();
1185:                }
1186:                for (int i = 0; i < methodFlags.length; i++) {
1187:                    for (int j = 0; j < methodFlags[i].length; j++) {
1188:                        for (int k = 0; k < rxaLayouts.length; k++) {
1189:                            if (rxaLayouts[k].matches(methodFlags[i][j])) {
1190:                                methodAttributes[i][j]
1191:                                        .add(attributeIterators[k].next());
1192:                            }
1193:                        }
1194:                    }
1195:                }
1196:                return backwardsCallsUsed;
1197:            }
1198:
1199:            /**
1200:             * Parse the class metadata bands and return the number of backwards callables
1201:             * @param in
1202:             * @param classAttrCalls
1203:             * @return
1204:             * @throws Pack200Exception
1205:             * @throws IOException
1206:             */
1207:            private int parseClassMetadataBands(InputStream in,
1208:                    int[] classAttrCalls) throws Pack200Exception, IOException {
1209:                int numBackwardsCalls = 0;
1210:                String[] RxA = new String[] { "RVA", "RIA" };
1211:
1212:                AttributeLayout rvaLayout = attrMap.getAttributeLayout(
1213:                        AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS,
1214:                        AttributeLayout.CONTEXT_CLASS);
1215:                AttributeLayout riaLayout = attrMap
1216:                        .getAttributeLayout(
1217:                                AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS,
1218:                                AttributeLayout.CONTEXT_CLASS);
1219:                int rvaCount = SegmentUtils.countMatches(classFlags, rvaLayout);
1220:                int riaCount = SegmentUtils.countMatches(classFlags, riaLayout);
1221:                int[] RxACount = new int[] { rvaCount, riaCount };
1222:                int[] backwardsCalls = new int[] { 0, 0 };
1223:                if (rvaCount > 0) {
1224:                    numBackwardsCalls++;
1225:                    backwardsCalls[0] = classAttrCalls[0];
1226:                    if (riaCount > 0) {
1227:                        numBackwardsCalls++;
1228:                        backwardsCalls[1] = classAttrCalls[1];
1229:                    }
1230:                } else if (riaCount > 0) {
1231:                    numBackwardsCalls++;
1232:                    backwardsCalls[1] = classAttrCalls[0];
1233:                }
1234:                MetadataBandGroup[] mbgs = parseMetadata(in, RxA, RxACount,
1235:                        backwardsCalls, "class");
1236:                Iterator rvaAttributesIterator = mbgs[0].getAttributes()
1237:                        .iterator();
1238:                Iterator riaAttributesIterator = mbgs[1].getAttributes()
1239:                        .iterator();
1240:                for (int i = 0; i < classFlags.length; i++) {
1241:                    if (rvaLayout.matches(classFlags[i])) {
1242:                        classAttributes[i].add(rvaAttributesIterator.next());
1243:                    }
1244:                    if (riaLayout.matches(classFlags[i])) {
1245:                        classAttributes[i].add(riaAttributesIterator.next());
1246:                    }
1247:                }
1248:                return numBackwardsCalls;
1249:            }
1250:
1251:            public int[] getClassFieldCount() {
1252:                return classFieldCount;
1253:            }
1254:
1255:            public long[] getClassFlags() {
1256:                return classFlags;
1257:            }
1258:
1259:            public String[][] getClassInterfaces() {
1260:                return classInterfaces;
1261:            }
1262:
1263:            public int[] getClassMethodCount() {
1264:                return classMethodCount;
1265:            }
1266:
1267:            public String[] getClassSuper() {
1268:                return classSuper;
1269:            }
1270:
1271:            public String[] getClassThis() {
1272:                return classThis;
1273:            }
1274:
1275:            public int[] getCodeMaxNALocals() {
1276:                return codeMaxNALocals;
1277:            }
1278:
1279:            public int[] getCodeMaxStack() {
1280:                return codeMaxStack;
1281:            }
1282:
1283:            public ArrayList[][] getFieldAttributes() {
1284:                return fieldAttributes;
1285:            }
1286:
1287:            public String[][] getFieldDescr() {
1288:                return fieldDescr;
1289:            }
1290:
1291:            public long[][] getFieldFlags() {
1292:                return fieldFlags;
1293:            }
1294:
1295:            /**
1296:             * Answer an ArrayList of ArrayLists which hold the the code attributes
1297:             * corresponding to all classes in order.
1298:             *
1299:             * If a class doesn't have any attributes, the corresponding element in this
1300:             * list will be an empty ArrayList.
1301:             * @return ArrayList
1302:             */
1303:            public ArrayList getOrderedCodeAttributes() {
1304:                ArrayList orderedAttributeList = new ArrayList();
1305:                for (int classIndex = 0; classIndex < codeAttributes.length; classIndex++) {
1306:                    ArrayList currentAttributes = new ArrayList();
1307:                    for (int attributeIndex = 0; attributeIndex < codeAttributes[classIndex]
1308:                            .size(); attributeIndex++) {
1309:                        Attribute attribute = (Attribute) codeAttributes[classIndex]
1310:                                .get(attributeIndex);
1311:                        currentAttributes.add(attribute);
1312:                    }
1313:                    orderedAttributeList.add(currentAttributes);
1314:                }
1315:                return orderedAttributeList;
1316:            }
1317:
1318:            public ArrayList[][] getMethodAttributes() {
1319:                return methodAttributes;
1320:            }
1321:
1322:            public String[][] getMethodDescr() {
1323:                return methodDescr;
1324:            }
1325:
1326:            public long[][] getMethodFlags() {
1327:                return methodFlags;
1328:            }
1329:
1330:            /**
1331:             * Returns null if all classes should use the default major and minor
1332:             * version or an array of integers containing the major version numberss to
1333:             * use for each class in the segment
1334:             *
1335:             * @return Class file major version numbers, or null if none specified
1336:             */
1337:            public int[] getClassVersionMajor() {
1338:                return classVersionMajor;
1339:            }
1340:
1341:            /**
1342:             * Returns null if all classes should use the default major and minor
1343:             * version or an array of integers containing the minor version numberss to
1344:             * use for each class in the segment
1345:             *
1346:             * @return Class file minor version numbers, or null if none specified
1347:             */
1348:            public int[] getClassVersionMinor() {
1349:                return classVersionMinor;
1350:            }
1351:
1352:            public int[] getCodeHandlerCount() {
1353:                return codeHandlerCount;
1354:            }
1355:
1356:            public int[][] getCodeHandlerCatchPO() {
1357:                return codeHandlerCatchPO;
1358:            }
1359:
1360:            public String[][] getCodeHandlerClassRCN() {
1361:                return codeHandlerClassRCN;
1362:            }
1363:
1364:            public int[][] getCodeHandlerEndPO() {
1365:                return codeHandlerEndPO;
1366:            }
1367:
1368:            public int[][] getCodeHandlerStartP() {
1369:                return codeHandlerStartP;
1370:            }
1371:
1372:            public IcTuple[][] getIcLocal() {
1373:                return icLocal;
1374:            }
1375:
1376:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.