Source Code Cross Referenced for BandStructure.java in  » 6.0-JDK-Modules-com.sun.java » util » com » sun » java » util » jar » pack » 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 » 6.0 JDK Modules com.sun.java » util » com.sun.java.util.jar.pack 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.java.util.jar.pack;
0027:
0028:        import java.io.*;
0029:        import java.util.*;
0030:        import java.util.jar.*;
0031:        import com.sun.java.util.jar.pack.Package.Class;
0032:        import com.sun.java.util.jar.pack.Package.InnerClass;
0033:        import com.sun.java.util.jar.pack.ConstantPool.*;
0034:
0035:        /**
0036:         * Define the structure and ordering of "bands" in a packed file.
0037:         * @author John Rose
0038:         * @version 1.36, 05/05/07
0039:         */
0040:        abstract class BandStructure implements  Constants {
0041:            static final int MAX_EFFORT = 9;
0042:            static final int MIN_EFFORT = 1;
0043:            static final int DEFAULT_EFFORT = 5;
0044:
0045:            // Inherit options from Pack200:
0046:            PropMap p200 = Utils.currentPropMap();
0047:
0048:            int verbose = p200.getInteger(Utils.DEBUG_VERBOSE);
0049:            int effort = p200.getInteger(Pack200.Packer.EFFORT);
0050:            {
0051:                if (effort == 0)
0052:                    effort = DEFAULT_EFFORT;
0053:            }
0054:            boolean optDumpBands = p200.getBoolean(Utils.COM_PREFIX
0055:                    + "dump.bands");
0056:            boolean optDebugBands = p200.getBoolean(Utils.COM_PREFIX
0057:                    + "debug.bands");
0058:
0059:            // Various heuristic options.
0060:            boolean optVaryCodings = !p200.getBoolean(Utils.COM_PREFIX
0061:                    + "no.vary.codings");
0062:            boolean optBigStrings = !p200.getBoolean(Utils.COM_PREFIX
0063:                    + "no.big.strings");
0064:
0065:            abstract protected Index getCPIndex(byte tag);
0066:
0067:            // Local copy of package version.
0068:            private int packageMajver = -1;
0069:
0070:            /** Call this exactly once, early, to specify the archive major version. */
0071:            public void initPackageMajver(int packageMajver) throws IOException {
0072:                assert (packageMajver > 0 && packageMajver < 0x10000);
0073:                if (this .packageMajver > 0) {
0074:                    throw new IOException(
0075:                            "Package majver is already initialized to "
0076:                                    + this .packageMajver + "; new setting is "
0077:                                    + packageMajver);
0078:                }
0079:                this .packageMajver = packageMajver;
0080:                adjustToMajver();
0081:            }
0082:
0083:            public int getPackageMajver() {
0084:                if (packageMajver < 0) {
0085:                    throw new RuntimeException(
0086:                            "Package majver not yet initialized");
0087:                }
0088:                return packageMajver;
0089:            }
0090:
0091:            private final boolean isReader = this  instanceof  PackageReader;
0092:
0093:            protected BandStructure() {
0094:            }
0095:
0096:            final static Coding BYTE1 = Coding.of(1, 256);
0097:
0098:            final static Coding CHAR3 = Coding.of(3, 128);
0099:            // Note:  Tried sharper (3,16) with no post-zip benefit.
0100:
0101:            // This is best used with BCI values:
0102:            final static Coding BCI5 = Coding.of(5, 4); // mostly 1-byte offsets
0103:            final static Coding BRANCH5 = Coding.of(5, 4, 2); // mostly forward branches
0104:
0105:            final static Coding UNSIGNED5 = Coding.of(5, 64);
0106:            final static Coding UDELTA5 = UNSIGNED5.getDeltaCoding();
0107:            // "sharp" (5,64) zips 0.4% better than "medium" (5,128)
0108:            // It zips 1.1% better than "flat" (5,192)
0109:
0110:            final static Coding SIGNED5 = Coding.of(5, 64, 1); //sharp
0111:            final static Coding DELTA5 = SIGNED5.getDeltaCoding();
0112:            // Note:  Tried (5,128,2) and (5,192,2) with no benefit.
0113:
0114:            final static Coding MDELTA5 = Coding.of(5, 64, 2).getDeltaCoding();
0115:
0116:            final private static Coding[] basicCodings = {
0117:                    // Table of "Canonical BHSD Codings" from Pack200 spec.
0118:                    null, // _meta_default
0119:
0120:                    // Fixed-length codings:
0121:                    Coding.of(1, 256, 0),
0122:                    Coding.of(1, 256, 1),
0123:                    Coding.of(1, 256, 0).getDeltaCoding(),
0124:                    Coding.of(1, 256, 1).getDeltaCoding(),
0125:                    Coding.of(2, 256, 0),
0126:                    Coding.of(2, 256, 1),
0127:                    Coding.of(2, 256, 0).getDeltaCoding(),
0128:                    Coding.of(2, 256, 1).getDeltaCoding(),
0129:                    Coding.of(3, 256, 0),
0130:                    Coding.of(3, 256, 1),
0131:                    Coding.of(3, 256, 0).getDeltaCoding(),
0132:                    Coding.of(3, 256, 1).getDeltaCoding(),
0133:                    Coding.of(4, 256, 0),
0134:                    Coding.of(4, 256, 1),
0135:                    Coding.of(4, 256, 0).getDeltaCoding(),
0136:                    Coding.of(4, 256, 1).getDeltaCoding(),
0137:
0138:                    // Full-range variable-length codings:
0139:                    Coding.of(5, 4, 0),
0140:                    Coding.of(5, 4, 1),
0141:                    Coding.of(5, 4, 2),
0142:                    Coding.of(5, 16, 0),
0143:                    Coding.of(5, 16, 1),
0144:                    Coding.of(5, 16, 2),
0145:                    Coding.of(5, 32, 0),
0146:                    Coding.of(5, 32, 1),
0147:                    Coding.of(5, 32, 2),
0148:                    Coding.of(5, 64, 0),
0149:                    Coding.of(5, 64, 1),
0150:                    Coding.of(5, 64, 2),
0151:                    Coding.of(5, 128, 0),
0152:                    Coding.of(5, 128, 1),
0153:                    Coding.of(5, 128, 2),
0154:
0155:                    Coding.of(5, 4, 0).getDeltaCoding(),
0156:                    Coding.of(5, 4, 1).getDeltaCoding(),
0157:                    Coding.of(5, 4, 2).getDeltaCoding(),
0158:                    Coding.of(5, 16, 0).getDeltaCoding(),
0159:                    Coding.of(5, 16, 1).getDeltaCoding(),
0160:                    Coding.of(5, 16, 2).getDeltaCoding(),
0161:                    Coding.of(5, 32, 0).getDeltaCoding(),
0162:                    Coding.of(5, 32, 1).getDeltaCoding(),
0163:                    Coding.of(5, 32, 2).getDeltaCoding(),
0164:                    Coding.of(5, 64, 0).getDeltaCoding(),
0165:                    Coding.of(5, 64, 1).getDeltaCoding(),
0166:                    Coding.of(5, 64, 2).getDeltaCoding(),
0167:                    Coding.of(5, 128, 0).getDeltaCoding(),
0168:                    Coding.of(5, 128, 1).getDeltaCoding(),
0169:                    Coding.of(5, 128, 2).getDeltaCoding(),
0170:
0171:                    // Variable length subrange codings:
0172:                    Coding.of(2, 192, 0), Coding.of(2, 224, 0),
0173:                    Coding.of(2, 240, 0), Coding.of(2, 248, 0),
0174:                    Coding.of(2, 252, 0),
0175:
0176:                    Coding.of(2, 8, 0).getDeltaCoding(),
0177:                    Coding.of(2, 8, 1).getDeltaCoding(),
0178:                    Coding.of(2, 16, 0).getDeltaCoding(),
0179:                    Coding.of(2, 16, 1).getDeltaCoding(),
0180:                    Coding.of(2, 32, 0).getDeltaCoding(),
0181:                    Coding.of(2, 32, 1).getDeltaCoding(),
0182:                    Coding.of(2, 64, 0).getDeltaCoding(),
0183:                    Coding.of(2, 64, 1).getDeltaCoding(),
0184:                    Coding.of(2, 128, 0).getDeltaCoding(),
0185:                    Coding.of(2, 128, 1).getDeltaCoding(),
0186:                    Coding.of(2, 192, 0).getDeltaCoding(),
0187:                    Coding.of(2, 192, 1).getDeltaCoding(),
0188:                    Coding.of(2, 224, 0).getDeltaCoding(),
0189:                    Coding.of(2, 224, 1).getDeltaCoding(),
0190:                    Coding.of(2, 240, 0).getDeltaCoding(),
0191:                    Coding.of(2, 240, 1).getDeltaCoding(),
0192:                    Coding.of(2, 248, 0).getDeltaCoding(),
0193:                    Coding.of(2, 248, 1).getDeltaCoding(),
0194:
0195:                    Coding.of(3, 192, 0), Coding.of(3, 224, 0),
0196:                    Coding.of(3, 240, 0), Coding.of(3, 248, 0),
0197:                    Coding.of(3, 252, 0),
0198:
0199:                    Coding.of(3, 8, 0).getDeltaCoding(),
0200:                    Coding.of(3, 8, 1).getDeltaCoding(),
0201:                    Coding.of(3, 16, 0).getDeltaCoding(),
0202:                    Coding.of(3, 16, 1).getDeltaCoding(),
0203:                    Coding.of(3, 32, 0).getDeltaCoding(),
0204:                    Coding.of(3, 32, 1).getDeltaCoding(),
0205:                    Coding.of(3, 64, 0).getDeltaCoding(),
0206:                    Coding.of(3, 64, 1).getDeltaCoding(),
0207:                    Coding.of(3, 128, 0).getDeltaCoding(),
0208:                    Coding.of(3, 128, 1).getDeltaCoding(),
0209:                    Coding.of(3, 192, 0).getDeltaCoding(),
0210:                    Coding.of(3, 192, 1).getDeltaCoding(),
0211:                    Coding.of(3, 224, 0).getDeltaCoding(),
0212:                    Coding.of(3, 224, 1).getDeltaCoding(),
0213:                    Coding.of(3, 240, 0).getDeltaCoding(),
0214:                    Coding.of(3, 240, 1).getDeltaCoding(),
0215:                    Coding.of(3, 248, 0).getDeltaCoding(),
0216:                    Coding.of(3, 248, 1).getDeltaCoding(),
0217:
0218:                    Coding.of(4, 192, 0), Coding.of(4, 224, 0),
0219:                    Coding.of(4, 240, 0), Coding.of(4, 248, 0),
0220:                    Coding.of(4, 252, 0),
0221:
0222:                    Coding.of(4, 8, 0).getDeltaCoding(),
0223:                    Coding.of(4, 8, 1).getDeltaCoding(),
0224:                    Coding.of(4, 16, 0).getDeltaCoding(),
0225:                    Coding.of(4, 16, 1).getDeltaCoding(),
0226:                    Coding.of(4, 32, 0).getDeltaCoding(),
0227:                    Coding.of(4, 32, 1).getDeltaCoding(),
0228:                    Coding.of(4, 64, 0).getDeltaCoding(),
0229:                    Coding.of(4, 64, 1).getDeltaCoding(),
0230:                    Coding.of(4, 128, 0).getDeltaCoding(),
0231:                    Coding.of(4, 128, 1).getDeltaCoding(),
0232:                    Coding.of(4, 192, 0).getDeltaCoding(),
0233:                    Coding.of(4, 192, 1).getDeltaCoding(),
0234:                    Coding.of(4, 224, 0).getDeltaCoding(),
0235:                    Coding.of(4, 224, 1).getDeltaCoding(),
0236:                    Coding.of(4, 240, 0).getDeltaCoding(),
0237:                    Coding.of(4, 240, 1).getDeltaCoding(),
0238:                    Coding.of(4, 248, 0).getDeltaCoding(),
0239:                    Coding.of(4, 248, 1).getDeltaCoding(),
0240:
0241:                    null };
0242:            final private static HashMap basicCodingIndexes;
0243:            static {
0244:                assert (basicCodings[_meta_default] == null);
0245:                assert (basicCodings[_meta_canon_min] != null);
0246:                assert (basicCodings[_meta_canon_max] != null);
0247:                HashMap map = new HashMap();
0248:                for (int i = 0; i < basicCodings.length; i++) {
0249:                    Coding c = basicCodings[i];
0250:                    if (c == null)
0251:                        continue;
0252:                    assert (i >= _meta_canon_min);
0253:                    assert (i <= _meta_canon_max);
0254:                    map.put(c, new Integer(i));
0255:                }
0256:                basicCodingIndexes = map;
0257:            }
0258:
0259:            public static Coding codingForIndex(int i) {
0260:                return i < basicCodings.length ? basicCodings[i] : null;
0261:            }
0262:
0263:            public static int indexOf(Coding c) {
0264:                Integer i = (Integer) basicCodingIndexes.get(c);
0265:                if (i == null)
0266:                    return 0;
0267:                return i.intValue();
0268:            }
0269:
0270:            public static Coding[] getBasicCodings() {
0271:                return (Coding[]) basicCodings.clone();
0272:            }
0273:
0274:            protected byte[] bandHeaderBytes; // used for input only
0275:            protected int bandHeaderBytePos; // BHB read pointer, for input only
0276:            protected int bandHeaderBytePos0; // for debug
0277:
0278:            protected CodingMethod getBandHeader(int XB, Coding regularCoding) {
0279:                CodingMethod[] res = { null };
0280:                // push back XB onto the band header bytes
0281:                bandHeaderBytes[--bandHeaderBytePos] = (byte) XB;
0282:                bandHeaderBytePos0 = bandHeaderBytePos;
0283:                // scan forward through XB and any additional band header bytes
0284:                bandHeaderBytePos = parseMetaCoding(bandHeaderBytes,
0285:                        bandHeaderBytePos, regularCoding, res);
0286:                return res[0];
0287:            }
0288:
0289:            public static int parseMetaCoding(byte[] bytes, int pos,
0290:                    Coding dflt, CodingMethod[] res) {
0291:                if ((bytes[pos] & 0xFF) == _meta_default) {
0292:                    res[0] = dflt;
0293:                    return pos + 1;
0294:                }
0295:                int pos2;
0296:                pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res);
0297:                if (pos2 > pos)
0298:                    return pos2;
0299:                pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res);
0300:                if (pos2 > pos)
0301:                    return pos2;
0302:                pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res);
0303:                if (pos2 > pos)
0304:                    return pos2;
0305:                throw new RuntimeException("Bad meta-coding op "
0306:                        + (bytes[pos] & 0xFF));
0307:            }
0308:
0309:            static final int SHORT_BAND_HEURISTIC = 100;
0310:
0311:            public static final int NO_PHASE = 0;
0312:
0313:            // package writing phases:
0314:            public static final int COLLECT_PHASE = 1; // collect data before write
0315:            public static final int FROZEN_PHASE = 3; // no longer collecting
0316:            public static final int WRITE_PHASE = 5; // ready to write bytes
0317:
0318:            // package reading phases:
0319:            public static final int EXPECT_PHASE = 2; // gather expected counts
0320:            public static final int READ_PHASE = 4; // ready to read bytes
0321:            public static final int DISBURSE_PHASE = 6; // pass out data after read
0322:
0323:            public static final int DONE_PHASE = 8; // done writing or reading
0324:
0325:            static boolean phaseIsRead(int p) {
0326:                return (p % 2) == 0;
0327:            }
0328:
0329:            static int phaseCmp(int p0, int p1) {
0330:                assert ((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0);
0331:                return p0 - p1;
0332:            }
0333:
0334:            /** The packed file is divided up into a number of segments.
0335:             *  Most segments are typed as ValueBand, strongly-typed sequences
0336:             *  of integer values, all interpreted in a single way.
0337:             *  A few segments are ByteBands, which hetergeneous sequences
0338:             *  of bytes.
0339:             *
0340:             *  The two phases for writing a packed file are COLLECT and WRITE.
0341:             *  1. When writing a packed file, each band collects
0342:             *  data in an ad-hoc order.
0343:             *  2. At the end, each band is assigned a coding scheme,
0344:             *  and then all the bands are written in their global order.
0345:             *
0346:             *  The three phases for reading a packed file are EXPECT, READ,
0347:             *  and DISBURSE.
0348:             *	1. For each band, the expected number of integers  is determined.
0349:             *  2. The data is actually read from the file into the band.
0350:             *  3. The band pays out its values as requested, in an ad hoc order.
0351:             *
0352:             *  When the last phase of a band is done, it is marked so (DONE).
0353:             *  Clearly, these phases must be properly ordered WRT each other.
0354:             */
0355:            abstract class Band {
0356:                private int phase = NO_PHASE;
0357:                private final String name;
0358:
0359:                private int valuesExpected;
0360:
0361:                protected long outputSize = -1; // cache
0362:
0363:                final public Coding regularCoding;
0364:
0365:                final public int seqForDebug;
0366:                public int elementCountForDebug;
0367:
0368:                protected Band(String name, Coding regularCoding) {
0369:                    this .name = name;
0370:                    this .regularCoding = regularCoding;
0371:                    this .seqForDebug = ++nextSeqForDebug;
0372:                    if (verbose > 2)
0373:                        Utils.log.fine("Band " + seqForDebug + " is " + name);
0374:                    // caller must call init
0375:                }
0376:
0377:                public Band init() {
0378:                    // Cannot due this from the constructor, because constructor
0379:                    // may wish to initialize some subclass variables.
0380:                    // Set initial phase for reading or writing:
0381:                    if (isReader)
0382:                        readyToExpect();
0383:                    else
0384:                        readyToCollect();
0385:                    return this ;
0386:                }
0387:
0388:                // common operations
0389:                boolean isReader() {
0390:                    return isReader;
0391:                }
0392:
0393:                int phase() {
0394:                    return phase;
0395:                }
0396:
0397:                String name() {
0398:                    return name;
0399:                }
0400:
0401:                /** Return -1 if data buffer not allocated, else max length. */
0402:                public abstract int capacity();
0403:
0404:                /** Allocate data buffer to specified length. */
0405:                protected abstract void setCapacity(int cap);
0406:
0407:                /** Return current number of values in buffer, which must exist. */
0408:                public abstract int length();
0409:
0410:                protected abstract int valuesRemainingForDebug();
0411:
0412:                public final int valuesExpected() {
0413:                    return valuesExpected;
0414:                }
0415:
0416:                /** Write out bytes, encoding the values. */
0417:                public final void writeTo(OutputStream out) throws IOException {
0418:                    assert (assertReadyToWriteTo(this , out));
0419:                    setPhase(WRITE_PHASE);
0420:                    // subclasses continue by writing their contents to output
0421:                    writeDataTo(out);
0422:                    doneWriting();
0423:                }
0424:
0425:                abstract void chooseBandCodings() throws IOException;
0426:
0427:                public final long outputSize() {
0428:                    if (outputSize >= 0) {
0429:                        long size = outputSize;
0430:                        assert (size == computeOutputSize());
0431:                        return size;
0432:                    }
0433:                    return computeOutputSize();
0434:                }
0435:
0436:                protected abstract long computeOutputSize();
0437:
0438:                abstract protected void writeDataTo(OutputStream out)
0439:                        throws IOException;
0440:
0441:                /** Expect a certain number of values. */
0442:                void expectLength(int l) {
0443:                    assert (assertPhase(this , EXPECT_PHASE));
0444:                    assert (valuesExpected == 0); // all at once
0445:                    assert (l >= 0);
0446:                    valuesExpected = l;
0447:                }
0448:
0449:                /** Expect more values.  (Multiple calls accumulate.) */
0450:                void expectMoreLength(int l) {
0451:                    assert (assertPhase(this , EXPECT_PHASE));
0452:                    valuesExpected += l;
0453:                }
0454:
0455:                /// Phase change markers.
0456:
0457:                private void readyToCollect() { // called implicitly by constructor
0458:                    setCapacity(1);
0459:                    setPhase(COLLECT_PHASE);
0460:                }
0461:
0462:                protected void doneWriting() {
0463:                    assert (assertPhase(this , WRITE_PHASE));
0464:                    setPhase(DONE_PHASE);
0465:                }
0466:
0467:                private void readyToExpect() { // called implicitly by constructor
0468:                    setPhase(EXPECT_PHASE);
0469:                }
0470:
0471:                /** Read in bytes, decoding the values. */
0472:                public final void readFrom(InputStream in) throws IOException {
0473:                    assert (assertReadyToReadFrom(this , in));
0474:                    setCapacity(valuesExpected());
0475:                    setPhase(READ_PHASE);
0476:                    // subclasses continue by reading their contents from input:
0477:                    readDataFrom(in);
0478:                    readyToDisburse();
0479:                }
0480:
0481:                abstract protected void readDataFrom(InputStream in)
0482:                        throws IOException;
0483:
0484:                protected void readyToDisburse() {
0485:                    if (verbose > 1)
0486:                        Utils.log.fine("readyToDisburse " + this );
0487:                    setPhase(DISBURSE_PHASE);
0488:                }
0489:
0490:                public void doneDisbursing() {
0491:                    assert (assertPhase(this , DISBURSE_PHASE));
0492:                    setPhase(DONE_PHASE);
0493:                }
0494:
0495:                public final void doneWithUnusedBand() {
0496:                    if (isReader) {
0497:                        assert (assertPhase(this , EXPECT_PHASE));
0498:                        assert (valuesExpected() == 0);
0499:                        // Fast forward:
0500:                        setPhase(READ_PHASE);
0501:                        setPhase(DISBURSE_PHASE);
0502:                        setPhase(DONE_PHASE);
0503:                    } else {
0504:                        setPhase(FROZEN_PHASE);
0505:                    }
0506:                }
0507:
0508:                protected void setPhase(int newPhase) {
0509:                    assert (assertPhaseChangeOK(this , phase, newPhase));
0510:                    this .phase = newPhase;
0511:                }
0512:
0513:                protected int lengthForDebug = -1; // DEBUG ONLY
0514:
0515:                public String toString() { // DEBUG ONLY
0516:                    int length = (lengthForDebug != -1 ? lengthForDebug
0517:                            : length());
0518:                    String str = name;
0519:                    if (length != 0)
0520:                        str += "[" + length + "]";
0521:                    if (elementCountForDebug != 0)
0522:                        str += "(" + elementCountForDebug + ")";
0523:                    return str;
0524:                }
0525:            }
0526:
0527:            class ValueBand extends Band {
0528:                private int[] values; // must be null in EXPECT phase
0529:                private int length;
0530:                private int valuesDisbursed;
0531:
0532:                private CodingMethod bandCoding;
0533:                private byte[] metaCoding;
0534:
0535:                protected ValueBand(String name, Coding regularCoding) {
0536:                    super (name, regularCoding);
0537:                }
0538:
0539:                public int capacity() {
0540:                    return values == null ? -1 : values.length;
0541:                }
0542:
0543:                /** Declare predicted or needed capacity. */
0544:                protected void setCapacity(int cap) {
0545:                    assert (length <= cap);
0546:                    if (cap == -1) {
0547:                        values = null;
0548:                        return;
0549:                    }
0550:                    values = realloc(values, cap);
0551:                }
0552:
0553:                public int length() {
0554:                    return length;
0555:                }
0556:
0557:                protected int valuesRemainingForDebug() {
0558:                    return length - valuesDisbursed;
0559:                }
0560:
0561:                protected int valueAtForDebug(int i) {
0562:                    return values[i];
0563:                }
0564:
0565:                void patchValue(int i, int value) {
0566:                    // Only one use for this.
0567:                    assert (this  == archive_header_S);
0568:                    assert (i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
0569:                    assert (i < length); // must have already output a dummy
0570:                    values[i] = value;
0571:                    outputSize = -1; // decache
0572:                }
0573:
0574:                protected void initializeValues(int[] values) {
0575:                    assert (assertCanChangeLength(this ));
0576:                    assert (length == 0);
0577:                    this .values = values;
0578:                    this .length = values.length;
0579:                }
0580:
0581:                /** Collect one value, or store one decoded value. */
0582:                protected void addValue(int x) {
0583:                    assert (assertCanChangeLength(this ));
0584:                    if (length == values.length)
0585:                        setCapacity(length < 1000 ? length * 10 : length * 2);
0586:                    values[length++] = x;
0587:                }
0588:
0589:                private boolean canVaryCoding() {
0590:                    if (!optVaryCodings)
0591:                        return false;
0592:                    if (length == 0)
0593:                        return false;
0594:                    // Can't read band_headers w/o the archive header:
0595:                    if (this  == archive_header_0)
0596:                        return false;
0597:                    if (this  == archive_header_S)
0598:                        return false;
0599:                    if (this  == archive_header_1)
0600:                        return false;
0601:                    // BYTE1 bands can't vary codings, but the others can.
0602:                    // All that's needed for the initial escape is at least
0603:                    // 256 negative values or more than 256 non-negative values
0604:                    return (regularCoding.min() <= -256 || regularCoding.max() >= 256);
0605:                }
0606:
0607:                private boolean shouldVaryCoding() {
0608:                    assert (canVaryCoding());
0609:                    if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC)
0610:                        return false;
0611:                    return true;
0612:                }
0613:
0614:                protected void chooseBandCodings() throws IOException {
0615:                    boolean canVary = canVaryCoding();
0616:                    if (!canVary || !shouldVaryCoding()) {
0617:                        if (regularCoding.canRepresent(values, 0, length)) {
0618:                            bandCoding = regularCoding;
0619:                        } else {
0620:                            assert (canVary);
0621:                            if (verbose > 1)
0622:                                Utils.log.fine("regular coding fails in band "
0623:                                        + name());
0624:                            bandCoding = UNSIGNED5;
0625:                        }
0626:                        outputSize = -1;
0627:                    } else {
0628:                        int[] sizes = { 0, 0 };
0629:                        bandCoding = chooseCoding(values, 0, length,
0630:                                regularCoding, name(), sizes);
0631:                        outputSize = sizes[CodingChooser.BYTE_SIZE];
0632:                        if (outputSize == 0) // CodingChooser failed to size it.
0633:                            outputSize = -1;
0634:                    }
0635:
0636:                    // Compute and save the meta-coding bytes also.
0637:                    if (bandCoding != regularCoding) {
0638:                        metaCoding = bandCoding.getMetaCoding(regularCoding);
0639:                        if (verbose > 1) {
0640:                            Utils.log.fine("alternate coding " + this  + " "
0641:                                    + bandCoding);
0642:                        }
0643:                    } else if (canVary
0644:                            && decodeEscapeValue(values[0], regularCoding) >= 0) {
0645:                        // Need an explicit default.
0646:                        metaCoding = defaultMetaCoding;
0647:                    } else {
0648:                        // Common case:  Zero bytes of meta coding.
0649:                        metaCoding = noMetaCoding;
0650:                    }
0651:                    if (metaCoding.length > 0
0652:                            && (verbose > 2 || verbose > 1
0653:                                    && metaCoding.length > 1)) {
0654:                        StringBuffer sb = new StringBuffer();
0655:                        for (int i = 0; i < metaCoding.length; i++) {
0656:                            if (i == 1)
0657:                                sb.append(" /");
0658:                            sb.append(" ").append(metaCoding[i] & 0xFF);
0659:                        }
0660:                        Utils.log.fine("   meta-coding " + sb);
0661:                    }
0662:
0663:                    assert ((outputSize < 0) || !(bandCoding instanceof  Coding) || (outputSize == ((Coding) bandCoding)
0664:                            .getLength(values, 0, length))) : (bandCoding
0665:                            + " : "
0666:                            + outputSize
0667:                            + " != "
0668:                            + ((Coding) bandCoding)
0669:                                    .getLength(values, 0, length) + " ?= " + getCodingChooser()
0670:                            .computeByteSize(bandCoding, values, 0, length));
0671:
0672:                    // Compute outputSize of the escape value X, if any.
0673:                    if (metaCoding.length > 0) {
0674:                        // First byte XB of meta-coding is treated specially,
0675:                        // but any other bytes go into the band headers band.
0676:                        // This must be done before any other output happens.
0677:                        if (outputSize >= 0)
0678:                            outputSize += computeEscapeSize(); // good cache
0679:                        // Other bytes go into band_headers.
0680:                        for (int i = 1; i < metaCoding.length; i++) {
0681:                            band_headers.putByte(metaCoding[i] & 0xFF);
0682:                        }
0683:                    }
0684:                }
0685:
0686:                protected long computeOutputSize() {
0687:                    outputSize = getCodingChooser().computeByteSize(bandCoding,
0688:                            values, 0, length);
0689:                    assert (outputSize < Integer.MAX_VALUE);
0690:                    outputSize += computeEscapeSize();
0691:                    return outputSize;
0692:                }
0693:
0694:                protected int computeEscapeSize() {
0695:                    if (metaCoding.length == 0)
0696:                        return 0;
0697:                    int XB = metaCoding[0] & 0xFF;
0698:                    int X = encodeEscapeValue(XB, regularCoding);
0699:                    return regularCoding.setD(0).getLength(X);
0700:                }
0701:
0702:                protected void writeDataTo(OutputStream out) throws IOException {
0703:                    if (length == 0)
0704:                        return; // nothing to write
0705:                    long len0 = 0;
0706:                    if (out == outputCounter) {
0707:                        len0 = outputCounter.getCount();
0708:                    }
0709:                    if (metaCoding.length > 0) {
0710:                        int XB = metaCoding[0] & 0xFF;
0711:                        // We need an explicit band header, either because
0712:                        // there is a non-default coding method, or because
0713:                        // the first value would be parsed as an escape value.
0714:                        int X = encodeEscapeValue(XB, regularCoding);
0715:                        //System.out.println("X="+X+" XB="+XB+" in "+this);
0716:                        regularCoding.setD(0).writeTo(out, X);
0717:                    }
0718:                    bandCoding.writeArrayTo(out, values, 0, length);
0719:                    if (out == outputCounter) {
0720:                        long len1 = outputCounter.getCount();
0721:                        assert (outputSize == outputCounter.getCount() - len0) : (outputSize
0722:                                + " != " + outputCounter.getCount() + "-" + len0);
0723:                    }
0724:                    if (optDumpBands)
0725:                        dumpBand();
0726:                }
0727:
0728:                protected void readDataFrom(InputStream in) throws IOException {
0729:                    length = valuesExpected();
0730:                    if (length == 0)
0731:                        return; // nothing to read
0732:                    if (verbose > 1)
0733:                        Utils.log.fine("Reading band " + this );
0734:                    if (!canVaryCoding()) {
0735:                        bandCoding = regularCoding;
0736:                        metaCoding = noMetaCoding;
0737:                    } else {
0738:                        assert (in.markSupported()); // input must be buffered
0739:                        in.mark(Coding.B_MAX);
0740:                        int X = regularCoding.setD(0).readFrom(in);
0741:                        int XB = decodeEscapeValue(X, regularCoding);
0742:                        if (XB < 0) {
0743:                            // Do not consume this value.  No alternate coding.
0744:                            in.reset();
0745:                            XB = _meta_default;
0746:                            bandCoding = regularCoding;
0747:                            metaCoding = noMetaCoding;
0748:                        } else if (XB == _meta_default) {
0749:                            bandCoding = regularCoding;
0750:                            metaCoding = defaultMetaCoding;
0751:                        } else {
0752:                            if (verbose > 2)
0753:                                Utils.log.fine("found X=" + X + " => XB=" + XB);
0754:                            bandCoding = getBandHeader(XB, regularCoding);
0755:                            // This is really used only by dumpBands.
0756:                            int p0 = bandHeaderBytePos0;
0757:                            int p1 = bandHeaderBytePos;
0758:                            metaCoding = new byte[p1 - p0];
0759:                            System.arraycopy(bandHeaderBytes, p0, metaCoding,
0760:                                    0, metaCoding.length);
0761:                        }
0762:                    }
0763:                    if (bandCoding != regularCoding) {
0764:                        if (verbose > 1)
0765:                            Utils.log.fine(name() + ": irregular coding "
0766:                                    + bandCoding);
0767:                    }
0768:                    bandCoding.readArrayFrom(in, values, 0, length);
0769:                    if (optDumpBands)
0770:                        dumpBand();
0771:                }
0772:
0773:                public void doneDisbursing() {
0774:                    super .doneDisbursing();
0775:                    values = null; // for GC
0776:                }
0777:
0778:                private void dumpBand() throws IOException {
0779:                    assert (optDumpBands);
0780:                    PrintStream ps = new PrintStream(
0781:                            getDumpStream(this , ".txt"));
0782:                    String irr = (bandCoding == regularCoding) ? ""
0783:                            : " irregular";
0784:                    ps.print("# length=" + length + " size=" + outputSize()
0785:                            + irr + " coding=" + bandCoding);
0786:                    if (metaCoding != noMetaCoding) {
0787:                        StringBuffer sb = new StringBuffer();
0788:                        for (int i = 0; i < metaCoding.length; i++) {
0789:                            if (i == 1)
0790:                                sb.append(" /");
0791:                            sb.append(" ").append(metaCoding[i] & 0xFF);
0792:                        }
0793:                        ps.print(" //header: " + sb);
0794:                    }
0795:                    printArrayTo(ps, values, 0, length);
0796:                    ps.close();
0797:                    OutputStream ds = getDumpStream(this , ".bnd");
0798:                    bandCoding.writeArrayTo(ds, values, 0, length);
0799:                    ds.close();
0800:                }
0801:
0802:                /** Disburse one value. */
0803:                protected int getValue() {
0804:                    assert (phase() == DISBURSE_PHASE);
0805:                    assert (valuesDisbursed < length);
0806:                    return values[valuesDisbursed++];
0807:                }
0808:
0809:                /** Reset for another pass over the same value set. */
0810:                public void resetForSecondPass() {
0811:                    assert (phase() == DISBURSE_PHASE);
0812:                    assert (valuesDisbursed == length()); // 1st pass is complete
0813:                    valuesDisbursed = 0;
0814:                }
0815:            }
0816:
0817:            class ByteBand extends Band {
0818:                private ByteArrayOutputStream bytes; // input buffer
0819:                private ByteArrayOutputStream bytesForDump;
0820:                private InputStream in;
0821:
0822:                public ByteBand(String name) {
0823:                    super (name, BYTE1);
0824:                }
0825:
0826:                public int capacity() {
0827:                    return bytes == null ? -1 : Integer.MAX_VALUE;
0828:                }
0829:
0830:                protected void setCapacity(int cap) {
0831:                    assert (bytes == null); // do this just once
0832:                    bytes = new ByteArrayOutputStream(cap);
0833:                }
0834:
0835:                public void destroy() {
0836:                    lengthForDebug = length();
0837:                    bytes = null;
0838:                }
0839:
0840:                public int length() {
0841:                    return bytes == null ? -1 : bytes.size();
0842:                }
0843:
0844:                public void reset() {
0845:                    bytes.reset();
0846:                }
0847:
0848:                protected int valuesRemainingForDebug() {
0849:                    return (bytes == null) ? -1 : ((ByteArrayInputStream) in)
0850:                            .available();
0851:                }
0852:
0853:                protected void chooseBandCodings() throws IOException {
0854:                    // No-op.
0855:                    assert (decodeEscapeValue(regularCoding.min(),
0856:                            regularCoding) < 0);
0857:                    assert (decodeEscapeValue(regularCoding.max(),
0858:                            regularCoding) < 0);
0859:                }
0860:
0861:                protected long computeOutputSize() {
0862:                    // do not cache
0863:                    return bytes.size();
0864:                }
0865:
0866:                public void writeDataTo(OutputStream out) throws IOException {
0867:                    if (length() == 0)
0868:                        return;
0869:                    bytes.writeTo(out);
0870:                    if (optDumpBands)
0871:                        dumpBand();
0872:                    destroy(); // done with the bits!
0873:                }
0874:
0875:                private void dumpBand() throws IOException {
0876:                    assert (optDumpBands);
0877:                    OutputStream ds = getDumpStream(this , ".bnd");
0878:                    if (bytesForDump != null)
0879:                        bytesForDump.writeTo(ds);
0880:                    else
0881:                        bytes.writeTo(ds);
0882:                    ds.close();
0883:                }
0884:
0885:                public void readDataFrom(InputStream in) throws IOException {
0886:                    int vex = valuesExpected();
0887:                    if (vex == 0)
0888:                        return;
0889:                    if (verbose > 1) {
0890:                        lengthForDebug = vex;
0891:                        Utils.log.fine("Reading band " + this );
0892:                        lengthForDebug = -1;
0893:                    }
0894:                    byte[] buf = new byte[Math.min(vex, 1 << 14)];
0895:                    while (vex > 0) {
0896:                        int nr = in.read(buf, 0, Math.min(vex, buf.length));
0897:                        if (nr < 0)
0898:                            throw new EOFException();
0899:                        bytes.write(buf, 0, nr);
0900:                        vex -= nr;
0901:                    }
0902:                    if (optDumpBands)
0903:                        dumpBand();
0904:                }
0905:
0906:                public void readyToDisburse() {
0907:                    in = new ByteArrayInputStream(bytes.toByteArray());
0908:                    super .readyToDisburse();
0909:                }
0910:
0911:                public void doneDisbursing() {
0912:                    super .doneDisbursing();
0913:                    if (optDumpBands && bytesForDump != null
0914:                            && bytesForDump.size() > 0) {
0915:                        try {
0916:                            dumpBand();
0917:                        } catch (IOException ee) {
0918:                            throw new RuntimeException(ee);
0919:                        }
0920:                    }
0921:                    in = null; // GC
0922:                    bytes = null; // GC
0923:                    bytesForDump = null; // GC
0924:                }
0925:
0926:                // alternative to readFrom:
0927:                public void setInputStreamFrom(InputStream in)
0928:                        throws IOException {
0929:                    assert (bytes == null);
0930:                    assert (assertReadyToReadFrom(this , in));
0931:                    setPhase(READ_PHASE);
0932:                    this .in = in;
0933:                    if (optDumpBands) {
0934:                        // Tap the stream.
0935:                        bytesForDump = new ByteArrayOutputStream();
0936:                        this .in = new FilterInputStream(in) {
0937:                            public int read() throws IOException {
0938:                                int ch = in.read();
0939:                                if (ch >= 0)
0940:                                    bytesForDump.write(ch);
0941:                                return ch;
0942:                            }
0943:
0944:                            public int read(byte b[], int off, int len)
0945:                                    throws IOException {
0946:                                int nr = in.read(b, off, len);
0947:                                if (nr >= 0)
0948:                                    bytesForDump.write(b, off, nr);
0949:                                return nr;
0950:                            }
0951:                        };
0952:                    }
0953:                    super .readyToDisburse();
0954:                }
0955:
0956:                public OutputStream collectorStream() {
0957:                    assert (phase() == COLLECT_PHASE);
0958:                    assert (bytes != null);
0959:                    return bytes;
0960:                }
0961:
0962:                public InputStream getInputStream() {
0963:                    assert (phase() == DISBURSE_PHASE);
0964:                    assert (in != null);
0965:                    return in;
0966:                }
0967:
0968:                public int getByte() throws IOException {
0969:                    int b = getInputStream().read();
0970:                    if (b < 0)
0971:                        throw new EOFException();
0972:                    return b;
0973:                }
0974:
0975:                public void putByte(int b) throws IOException {
0976:                    assert (b == (b & 0xFF));
0977:                    collectorStream().write(b);
0978:                }
0979:
0980:                public String toString() {
0981:                    return "byte " + super .toString();
0982:                }
0983:            }
0984:
0985:            class IntBand extends ValueBand {
0986:                // The usual coding for bands is 7bit/5byte/delta.
0987:                public IntBand(String name, Coding regularCoding) {
0988:                    super (name, regularCoding);
0989:                }
0990:
0991:                public void putInt(int x) {
0992:                    assert (phase() == COLLECT_PHASE);
0993:                    addValue(x);
0994:                }
0995:
0996:                public int getInt() {
0997:                    return getValue();
0998:                }
0999:
1000:                /** Return the sum of all values in this band. */
1001:                public int getIntTotal() {
1002:                    assert (phase() == DISBURSE_PHASE);
1003:                    // assert that this is the whole pass; no other reads allowed
1004:                    assert (valuesRemainingForDebug() == length());
1005:                    int total = 0;
1006:                    for (int k = length(); k > 0; k--) {
1007:                        total += getInt();
1008:                    }
1009:                    resetForSecondPass();
1010:                    return total;
1011:                }
1012:
1013:                /** Return the occurrence count of a specific value in this band. */
1014:                public int getIntCount(int value) {
1015:                    assert (phase() == DISBURSE_PHASE);
1016:                    // assert that this is the whole pass; no other reads allowed
1017:                    assert (valuesRemainingForDebug() == length());
1018:                    int total = 0;
1019:                    for (int k = length(); k > 0; k--) {
1020:                        if (getInt() == value) {
1021:                            total += 1;
1022:                        }
1023:                    }
1024:                    resetForSecondPass();
1025:                    return total;
1026:                }
1027:            }
1028:
1029:            static int getIntTotal(int[] values) {
1030:                int total = 0;
1031:                for (int i = 0; i < values.length; i++) {
1032:                    total += values[i];
1033:                }
1034:                return total;
1035:            }
1036:
1037:            class CPRefBand extends ValueBand {
1038:                Index index;
1039:                boolean nullOK;
1040:
1041:                public CPRefBand(String name, Coding regularCoding, byte cpTag,
1042:                        boolean nullOK) {
1043:                    super (name, regularCoding);
1044:                    this .nullOK = nullOK;
1045:                    if (cpTag != CONSTANT_None)
1046:                        setBandIndex(this , cpTag);
1047:                }
1048:
1049:                public CPRefBand(String name, Coding regularCoding, byte cpTag) {
1050:                    this (name, regularCoding, cpTag, false);
1051:                }
1052:
1053:                public CPRefBand(String name, Coding regularCoding, Object undef) {
1054:                    this (name, regularCoding, CONSTANT_None, false);
1055:                }
1056:
1057:                public void setIndex(Index index) {
1058:                    this .index = index;
1059:                }
1060:
1061:                protected void readDataFrom(InputStream in) throws IOException {
1062:                    super .readDataFrom(in);
1063:                    assert (assertValidCPRefs(this ));
1064:                }
1065:
1066:                /** Write a constant pool reference. */
1067:                public void putRef(Entry e) {
1068:                    assert (index != null);
1069:                    addValue(encodeRefOrNull(e, index));
1070:                }
1071:
1072:                public void putRef(Entry e, Index index) {
1073:                    assert (this .index == null);
1074:                    addValue(encodeRefOrNull(e, index));
1075:                }
1076:
1077:                public void putRef(Entry e, byte cptag) {
1078:                    putRef(e, getCPIndex(cptag));
1079:                }
1080:
1081:                public Entry getRef() {
1082:                    if (index == null)
1083:                        Utils.log.warning("No index for " + this );
1084:                    assert (index != null);
1085:                    return decodeRefOrNull(getValue(), index);
1086:                }
1087:
1088:                public Entry getRef(Index index) {
1089:                    assert (this .index == null);
1090:                    return decodeRefOrNull(getValue(), index);
1091:                }
1092:
1093:                public Entry getRef(byte cptag) {
1094:                    return getRef(getCPIndex(cptag));
1095:                }
1096:
1097:                private int encodeRefOrNull(Entry e, Index index) {
1098:                    int nonNullCode; // NNC is the coding which assumes nulls are rare
1099:                    if (e == null) {
1100:                        nonNullCode = -1; // negative values are rare
1101:                    } else {
1102:                        nonNullCode = encodeRef(e, index);
1103:                    }
1104:                    // If nulls are expected, increment, to make -1 code turn to 0.
1105:                    return (nullOK ? 1 : 0) + nonNullCode;
1106:                }
1107:
1108:                private Entry decodeRefOrNull(int code, Index index) {
1109:                    // Inverse to encodeRefOrNull...
1110:                    int nonNullCode = code - (nullOK ? 1 : 0);
1111:                    if (nonNullCode == -1) {
1112:                        return null;
1113:                    } else {
1114:                        return decodeRef(nonNullCode, index);
1115:                    }
1116:                }
1117:            }
1118:
1119:            // Bootstrap support for CPRefBands.  These are needed to record
1120:            // intended CP indexes, before the CP has been created.
1121:            private ArrayList allKQBands = new ArrayList();
1122:            private ArrayList needPredefIndex = new ArrayList();
1123:
1124:            int encodeRef(Entry e, Index ix) {
1125:                int coding = ix.indexOf(e);
1126:                if (verbose > 2)
1127:                    Utils.log.fine("putRef " + coding + " => " + e);
1128:                return coding;
1129:            }
1130:
1131:            Entry decodeRef(int n, Index ix) {
1132:                if (n < 0 || n >= ix.size())
1133:                    Utils.log.warning("decoding bad ref " + n + " in " + ix);
1134:                Entry e = ix.getEntry(n);
1135:                if (verbose > 2)
1136:                    Utils.log.fine("getRef " + n + " => " + e);
1137:                return e;
1138:            }
1139:
1140:            private CodingChooser codingChooser;
1141:
1142:            protected CodingChooser getCodingChooser() {
1143:                if (codingChooser == null) {
1144:                    codingChooser = new CodingChooser(effort, basicCodings);
1145:                    if (codingChooser.stress != null
1146:                            && this  instanceof  PackageWriter) {
1147:                        // Twist the random state based on my first file.
1148:                        // This sends each segment off in a different direction.
1149:                        List classes = ((PackageWriter) this ).pkg.classes;
1150:                        if (!classes.isEmpty()) {
1151:                            Package.Class cls = (Package.Class) classes.get(0);
1152:                            codingChooser.addStressSeed(cls.getName()
1153:                                    .hashCode());
1154:                        }
1155:                    }
1156:                }
1157:                return codingChooser;
1158:            }
1159:
1160:            public CodingMethod chooseCoding(int[] values, int start, int end,
1161:                    Coding regular, String bandName, int[] sizes) {
1162:                assert (optVaryCodings);
1163:                if (effort <= MIN_EFFORT) {
1164:                    return regular;
1165:                }
1166:                CodingChooser cc = getCodingChooser();
1167:                if (verbose > 1 || cc.verbose > 1) {
1168:                    Utils.log.fine("--- chooseCoding " + bandName);
1169:                }
1170:                return cc.choose(values, start, end, regular, sizes);
1171:            }
1172:
1173:            static final byte[] defaultMetaCoding = { _meta_default };
1174:            static final byte[] noMetaCoding = {};
1175:
1176:            // The first value in a band is always coded with the default coding D.
1177:            // If this first value X is an escape value, it actually represents the
1178:            // first (and perhaps only) byte of a meta-coding.
1179:            //
1180:            // If D.S != 0 and D includes the range [-256..-1],
1181:            // the escape values are in that range,
1182:            // and the first byte XB is -1-X.
1183:            //
1184:            // If D.S == 0 and D includes the range [(D.L)..(D.L)+255],
1185:            // the escape values are in that range,
1186:            // and XB is X-(D.L).
1187:            //
1188:            // This representation is designed so that a band header is unlikely
1189:            // to be confused with the initial value of a headerless band,
1190:            // and yet so that a band header is likely to occupy only a byte or two.
1191:            //
1192:            // Result is in [0..255] if XB was successfully extracted, else -1.
1193:            // See section "Coding Specifier Meta-Encoding" in the JSR 200 spec.
1194:            protected static int decodeEscapeValue(int X, Coding regularCoding) {
1195:                // The first value in a band is always coded with the default coding D.
1196:                // If this first value X is an escape value, it actually represents the
1197:                // first (and perhaps only) byte of a meta-coding.
1198:                // Result is in [0..255] if XB was successfully extracted, else -1.
1199:                if (regularCoding.B() == 1 || regularCoding.L() == 0)
1200:                    return -1; // degenerate regular coding (BYTE1)
1201:                if (regularCoding.S() != 0) {
1202:                    if (-256 <= X && X <= -1 && regularCoding.min() <= -256) {
1203:                        int XB = -1 - X;
1204:                        assert (XB >= 0 && XB < 256);
1205:                        return XB;
1206:                    }
1207:                } else {
1208:                    int L = regularCoding.L();
1209:                    if (L <= X && X <= L + 255
1210:                            && regularCoding.max() >= L + 255) {
1211:                        int XB = X - L;
1212:                        assert (XB >= 0 && XB < 256);
1213:                        return XB;
1214:                    }
1215:                }
1216:                return -1; // negative value for failure
1217:            }
1218:
1219:            // Inverse to decodeEscapeValue().
1220:            protected static int encodeEscapeValue(int XB, Coding regularCoding) {
1221:                assert (XB >= 0 && XB < 256);
1222:                assert (regularCoding.B() > 1 && regularCoding.L() > 0);
1223:                int X;
1224:                if (regularCoding.S() != 0) {
1225:                    assert (regularCoding.min() <= -256);
1226:                    X = -1 - XB;
1227:                } else {
1228:                    int L = regularCoding.L();
1229:                    assert (regularCoding.max() >= L + 255);
1230:                    X = XB + L;
1231:                }
1232:                assert (decodeEscapeValue(X, regularCoding) == XB) : (regularCoding
1233:                        + " XB=" + XB + " X=" + X);
1234:                return X;
1235:            }
1236:
1237:            static {
1238:                boolean checkXB = false;
1239:                assert (checkXB = true);
1240:                if (checkXB) {
1241:                    for (int i = 0; i < basicCodings.length; i++) {
1242:                        Coding D = basicCodings[i];
1243:                        if (D == null)
1244:                            continue;
1245:                        if (D.B() == 1)
1246:                            continue;
1247:                        if (D.L() == 0)
1248:                            continue;
1249:                        for (int XB = 0; XB <= 255; XB++) {
1250:                            // The following exercises decodeEscapeValue also:
1251:                            encodeEscapeValue(XB, D);
1252:                        }
1253:                    }
1254:                }
1255:            }
1256:
1257:            class MultiBand extends Band {
1258:                MultiBand(String name, Coding regularCoding) {
1259:                    super (name, regularCoding);
1260:                }
1261:
1262:                public Band init() {
1263:                    super .init();
1264:                    // This is all just to keep the asserts happy:
1265:                    setCapacity(0);
1266:                    if (phase() == EXPECT_PHASE) {
1267:                        // Fast forward:
1268:                        setPhase(READ_PHASE);
1269:                        setPhase(DISBURSE_PHASE);
1270:                    }
1271:                    return this ;
1272:                }
1273:
1274:                Band[] bands = new Band[10];
1275:                int bandCount = 0;
1276:
1277:                int size() {
1278:                    return bandCount;
1279:                }
1280:
1281:                Band get(int i) {
1282:                    assert (i < bandCount);
1283:                    return bands[i];
1284:                }
1285:
1286:                Band[] toArray() {
1287:                    return (Band[]) realloc(bands, bandCount);
1288:                }
1289:
1290:                void add(Band b) {
1291:                    assert (bandCount == 0 || notePrevForAssert(b,
1292:                            bands[bandCount - 1]));
1293:                    if (bandCount == bands.length) {
1294:                        bands = (Band[]) realloc(bands);
1295:                    }
1296:                    bands[bandCount++] = b;
1297:                }
1298:
1299:                ByteBand newByteBand(String name) {
1300:                    ByteBand b = new ByteBand(name);
1301:                    b.init();
1302:                    add(b);
1303:                    return b;
1304:                }
1305:
1306:                IntBand newIntBand(String name) {
1307:                    IntBand b = new IntBand(name, regularCoding);
1308:                    b.init();
1309:                    add(b);
1310:                    return b;
1311:                }
1312:
1313:                IntBand newIntBand(String name, Coding regularCoding) {
1314:                    IntBand b = new IntBand(name, regularCoding);
1315:                    b.init();
1316:                    add(b);
1317:                    return b;
1318:                }
1319:
1320:                MultiBand newMultiBand(String name, Coding regularCoding) {
1321:                    MultiBand b = new MultiBand(name, regularCoding);
1322:                    b.init();
1323:                    add(b);
1324:                    return b;
1325:                }
1326:
1327:                CPRefBand newCPRefBand(String name, byte cpTag) {
1328:                    CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1329:                    b.init();
1330:                    add(b);
1331:                    return b;
1332:                }
1333:
1334:                CPRefBand newCPRefBand(String name, Coding regularCoding,
1335:                        byte cpTag) {
1336:                    CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
1337:                    b.init();
1338:                    add(b);
1339:                    return b;
1340:                }
1341:
1342:                CPRefBand newCPRefBand(String name, Coding regularCoding,
1343:                        byte cpTag, boolean nullOK) {
1344:                    CPRefBand b = new CPRefBand(name, regularCoding, cpTag,
1345:                            nullOK);
1346:                    b.init();
1347:                    add(b);
1348:                    return b;
1349:                }
1350:
1351:                int bandCount() {
1352:                    return bandCount;
1353:                }
1354:
1355:                private int cap = -1;
1356:
1357:                public int capacity() {
1358:                    return cap;
1359:                }
1360:
1361:                public void setCapacity(int cap) {
1362:                    this .cap = cap;
1363:                }
1364:
1365:                public int length() {
1366:                    return 0;
1367:                }
1368:
1369:                public int valuesRemainingForDebug() {
1370:                    return 0;
1371:                }
1372:
1373:                protected void chooseBandCodings() throws IOException {
1374:                    // coding decision pass
1375:                    for (int i = 0; i < bandCount; i++) {
1376:                        Band b = bands[i];
1377:                        b.chooseBandCodings();
1378:                    }
1379:                }
1380:
1381:                protected long computeOutputSize() {
1382:                    // coding decision pass
1383:                    long sum = 0;
1384:                    for (int i = 0; i < bandCount; i++) {
1385:                        Band b = bands[i];
1386:                        long bsize = b.outputSize();
1387:                        assert (bsize >= 0) : b;
1388:                        sum += bsize;
1389:                    }
1390:                    // do not cache
1391:                    return sum;
1392:                }
1393:
1394:                protected void writeDataTo(OutputStream out) throws IOException {
1395:                    long preCount = 0;
1396:                    if (outputCounter != null)
1397:                        preCount = outputCounter.getCount();
1398:                    for (int i = 0; i < bandCount; i++) {
1399:                        Band b = bands[i];
1400:                        b.writeTo(out);
1401:                        if (outputCounter != null) {
1402:                            long postCount = outputCounter.getCount();
1403:                            long len = postCount - preCount;
1404:                            preCount = postCount;
1405:                            if ((verbose > 0 && len > 0) || verbose > 1) {
1406:                                Utils.log.info("  ...wrote " + len
1407:                                        + " bytes from " + b);
1408:                            }
1409:                        }
1410:                    }
1411:                }
1412:
1413:                protected void readDataFrom(InputStream in) throws IOException {
1414:                    assert (false); // not called?
1415:                    for (int i = 0; i < bandCount; i++) {
1416:                        Band b = bands[i];
1417:                        b.readFrom(in);
1418:                        if ((verbose > 0 && b.length() > 0) || verbose > 1) {
1419:                            Utils.log.info("  ...read " + b);
1420:                        }
1421:                    }
1422:                }
1423:
1424:                public String toString() {
1425:                    return "{" + bandCount() + " bands: " + super .toString()
1426:                            + "}";
1427:                }
1428:            }
1429:
1430:            /**
1431:             * An output stream which counts the number of bytes written.
1432:             */
1433:            private static class ByteCounter extends FilterOutputStream {
1434:                // (should go public under the name CountingOutputStream?)
1435:
1436:                private long count;
1437:
1438:                public ByteCounter(OutputStream out) {
1439:                    super (out);
1440:                }
1441:
1442:                public long getCount() {
1443:                    return count;
1444:                }
1445:
1446:                public void setCount(long c) {
1447:                    count = c;
1448:                }
1449:
1450:                public void write(int b) throws IOException {
1451:                    count++;
1452:                    if (out != null)
1453:                        out.write(b);
1454:                }
1455:
1456:                public void write(byte b[], int off, int len)
1457:                        throws IOException {
1458:                    count += len;
1459:                    if (out != null)
1460:                        out.write(b, off, len);
1461:                }
1462:
1463:                public String toString() {
1464:                    return String.valueOf(getCount());
1465:                }
1466:            }
1467:
1468:            ByteCounter outputCounter;
1469:
1470:            void writeAllBandsTo(OutputStream out) throws IOException {
1471:                // Wrap a byte-counter around the output stream.
1472:                outputCounter = new ByteCounter(out);
1473:                out = outputCounter;
1474:                all_bands.writeTo(out);
1475:                if (verbose > 0) {
1476:                    long nbytes = outputCounter.getCount();
1477:                    Utils.log.info("Wrote total of " + nbytes + " bytes.");
1478:                    assert (nbytes == archiveSize0 + archiveSize1);
1479:                }
1480:                outputCounter = null;
1481:            }
1482:
1483:            // random AO_XXX bits, decoded from the archive header
1484:            protected int archiveOptions;
1485:
1486:            // archiveSize1 sizes most of the archive [archive_options..file_bits).
1487:            protected long archiveSize0; // size through archive_size_lo
1488:            protected long archiveSize1; // size reported in archive_header
1489:            protected int archiveNextCount; // reported in archive_header
1490:
1491:            static final int AH_LENGTH_0 = 3; //minver, majver, options
1492:            static final int AH_ARCHIVE_SIZE_HI = 0;
1493:            static final int AH_ARCHIVE_SIZE_LO = 1;
1494:            static final int AH_LENGTH_S = 2; //optional size hi/lo
1495:            static final int AH_LENGTH = 26; // mentioned in spec
1496:            // Length contributions from optional header fields:
1497:            static final int AH_FILE_HEADER_LEN = 5; // sizehi/lo/next/modtime/files
1498:            static final int AH_SPECIAL_FORMAT_LEN = 2; // layouts/band-headers
1499:            static final int AH_CP_NUMBER_LEN = 4; // int/float/long/double
1500:            static final int AH_LENGTH_MIN = AH_LENGTH
1501:                    - (AH_SPECIAL_FORMAT_LEN + AH_FILE_HEADER_LEN + AH_CP_NUMBER_LEN);
1502:
1503:            // Common structure of attribute band groups:
1504:            static final int AB_FLAGS_HI = 0;
1505:            static final int AB_FLAGS_LO = 1;
1506:            static final int AB_ATTR_COUNT = 2;
1507:            static final int AB_ATTR_INDEXES = 3;
1508:            static final int AB_ATTR_CALLS = 4;
1509:
1510:            static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) {
1511:                IntBand b = (IntBand) xxx_attr_bands.get(which);
1512:                switch (which) {
1513:                case AB_FLAGS_HI:
1514:                    assert (b.name().endsWith("_flags_hi"));
1515:                    break;
1516:                case AB_FLAGS_LO:
1517:                    assert (b.name().endsWith("_flags_lo"));
1518:                    break;
1519:                case AB_ATTR_COUNT:
1520:                    assert (b.name().endsWith("_attr_count"));
1521:                    break;
1522:                case AB_ATTR_INDEXES:
1523:                    assert (b.name().endsWith("_attr_indexes"));
1524:                    break;
1525:                case AB_ATTR_CALLS:
1526:                    assert (b.name().endsWith("_attr_calls"));
1527:                    break;
1528:                default:
1529:                    assert (false);
1530:                    break;
1531:                }
1532:                return b;
1533:            }
1534:
1535:            static private final boolean NULL_IS_OK = true;
1536:
1537:            MultiBand all_bands = (MultiBand) new MultiBand("(package)",
1538:                    UNSIGNED5).init();
1539:
1540:            // file header (various random bytes)
1541:            ByteBand archive_magic = all_bands.newByteBand("archive_magic");
1542:            IntBand archive_header_0 = all_bands.newIntBand("archive_header_0",
1543:                    UNSIGNED5);
1544:            IntBand archive_header_S = all_bands.newIntBand("archive_header_S",
1545:                    UNSIGNED5);
1546:            IntBand archive_header_1 = all_bands.newIntBand("archive_header_1",
1547:                    UNSIGNED5);
1548:            ByteBand band_headers = all_bands.newByteBand("band_headers");
1549:
1550:            // constant pool contents
1551:            MultiBand cp_bands = all_bands.newMultiBand("(constant_pool)",
1552:                    DELTA5);
1553:            IntBand cp_Utf8_prefix = cp_bands.newIntBand("cp_Utf8_prefix");
1554:            IntBand cp_Utf8_suffix = cp_bands.newIntBand("cp_Utf8_suffix",
1555:                    UNSIGNED5);
1556:            IntBand cp_Utf8_chars = cp_bands.newIntBand("cp_Utf8_chars", CHAR3);
1557:            IntBand cp_Utf8_big_suffix = cp_bands
1558:                    .newIntBand("cp_Utf8_big_suffix");
1559:            MultiBand cp_Utf8_big_chars = cp_bands.newMultiBand(
1560:                    "(cp_Utf8_big_chars)", DELTA5);
1561:            IntBand cp_Int = cp_bands.newIntBand("cp_Int", UDELTA5);
1562:            IntBand cp_Float = cp_bands.newIntBand("cp_Float", UDELTA5);
1563:            IntBand cp_Long_hi = cp_bands.newIntBand("cp_Long_hi", UDELTA5);
1564:            IntBand cp_Long_lo = cp_bands.newIntBand("cp_Long_lo");
1565:            IntBand cp_Double_hi = cp_bands.newIntBand("cp_Double_hi", UDELTA5);
1566:            IntBand cp_Double_lo = cp_bands.newIntBand("cp_Double_lo");
1567:            CPRefBand cp_String = cp_bands.newCPRefBand("cp_String", UDELTA5,
1568:                    CONSTANT_Utf8);
1569:            CPRefBand cp_Class = cp_bands.newCPRefBand("cp_Class", UDELTA5,
1570:                    CONSTANT_Utf8);
1571:            CPRefBand cp_Signature_form = cp_bands.newCPRefBand(
1572:                    "cp_Signature_form", CONSTANT_Utf8);
1573:            CPRefBand cp_Signature_classes = cp_bands.newCPRefBand(
1574:                    "cp_Signature_classes", UDELTA5, CONSTANT_Class);
1575:            CPRefBand cp_Descr_name = cp_bands.newCPRefBand("cp_Descr_name",
1576:                    CONSTANT_Utf8);
1577:            CPRefBand cp_Descr_type = cp_bands.newCPRefBand("cp_Descr_type",
1578:                    UDELTA5, CONSTANT_Signature);
1579:            CPRefBand cp_Field_class = cp_bands.newCPRefBand("cp_Field_class",
1580:                    CONSTANT_Class);
1581:            CPRefBand cp_Field_desc = cp_bands.newCPRefBand("cp_Field_desc",
1582:                    UDELTA5, CONSTANT_NameandType);
1583:            CPRefBand cp_Method_class = cp_bands.newCPRefBand(
1584:                    "cp_Method_class", CONSTANT_Class);
1585:            CPRefBand cp_Method_desc = cp_bands.newCPRefBand("cp_Method_desc",
1586:                    UDELTA5, CONSTANT_NameandType);
1587:            CPRefBand cp_Imethod_class = cp_bands.newCPRefBand(
1588:                    "cp_Imethod_class", CONSTANT_Class);
1589:            CPRefBand cp_Imethod_desc = cp_bands.newCPRefBand(
1590:                    "cp_Imethod_desc", UDELTA5, CONSTANT_NameandType);
1591:
1592:            // bands for carrying attribute definitions:
1593:            MultiBand attr_definition_bands = all_bands.newMultiBand(
1594:                    "(attr_definition_bands)", UNSIGNED5);
1595:            ByteBand attr_definition_headers = attr_definition_bands
1596:                    .newByteBand("attr_definition_headers");
1597:            CPRefBand attr_definition_name = attr_definition_bands
1598:                    .newCPRefBand("attr_definition_name", CONSTANT_Utf8);
1599:            CPRefBand attr_definition_layout = attr_definition_bands
1600:                    .newCPRefBand("attr_definition_layout", CONSTANT_Utf8);
1601:
1602:            // bands for hardwired InnerClasses attribute (shared across the package)
1603:            MultiBand ic_bands = all_bands.newMultiBand("(ic_bands)", DELTA5);
1604:            CPRefBand ic_this _class = ic_bands.newCPRefBand("ic_this_class",
1605:                    UDELTA5, CONSTANT_Class);
1606:            IntBand ic_flags = ic_bands.newIntBand("ic_flags", UNSIGNED5);
1607:            // These bands contain data only where flags sets ACC_IC_LONG_FORM:
1608:            CPRefBand ic_outer_class = ic_bands.newCPRefBand("ic_outer_class",
1609:                    DELTA5, CONSTANT_Class, NULL_IS_OK);
1610:            CPRefBand ic_name = ic_bands.newCPRefBand("ic_name", DELTA5,
1611:                    CONSTANT_Utf8, NULL_IS_OK);
1612:
1613:            // bands for carrying class schema information:
1614:            MultiBand class_bands = all_bands.newMultiBand("(class_bands)",
1615:                    DELTA5);
1616:            CPRefBand class_this  = class_bands.newCPRefBand("class_this",
1617:                    CONSTANT_Class);
1618:            CPRefBand class_super  = class_bands.newCPRefBand("class_super",
1619:                    CONSTANT_Class);
1620:            IntBand class_interface_count = class_bands
1621:                    .newIntBand("class_interface_count");
1622:            CPRefBand class_interface = class_bands.newCPRefBand(
1623:                    "class_interface", CONSTANT_Class);
1624:
1625:            // bands for class members
1626:            IntBand class_field_count = class_bands
1627:                    .newIntBand("class_field_count");
1628:            IntBand class_method_count = class_bands
1629:                    .newIntBand("class_method_count");
1630:
1631:            CPRefBand field_descr = class_bands.newCPRefBand("field_descr",
1632:                    CONSTANT_NameandType);
1633:            MultiBand field_attr_bands = class_bands.newMultiBand(
1634:                    "(field_attr_bands)", UNSIGNED5);
1635:            IntBand field_flags_hi = field_attr_bands
1636:                    .newIntBand("field_flags_hi");
1637:            IntBand field_flags_lo = field_attr_bands
1638:                    .newIntBand("field_flags_lo");
1639:            IntBand field_attr_count = field_attr_bands
1640:                    .newIntBand("field_attr_count");
1641:            IntBand field_attr_indexes = field_attr_bands
1642:                    .newIntBand("field_attr_indexes");
1643:            IntBand field_attr_calls = field_attr_bands
1644:                    .newIntBand("field_attr_calls");
1645:
1646:            // bands for predefined field attributes
1647:            CPRefBand field_ConstantValue_KQ = field_attr_bands.newCPRefBand(
1648:                    "field_ConstantValue_KQ", CONSTANT_Literal);
1649:            CPRefBand field_Signature_RS = field_attr_bands.newCPRefBand(
1650:                    "field_Signature_RS", CONSTANT_Signature);
1651:            MultiBand field_metadata_bands = field_attr_bands.newMultiBand(
1652:                    "(field_metadata_bands)", UNSIGNED5);
1653:
1654:            CPRefBand method_descr = class_bands.newCPRefBand("method_descr",
1655:                    MDELTA5, CONSTANT_NameandType);
1656:            MultiBand method_attr_bands = class_bands.newMultiBand(
1657:                    "(method_attr_bands)", UNSIGNED5);
1658:            IntBand method_flags_hi = method_attr_bands
1659:                    .newIntBand("method_flags_hi");
1660:            IntBand method_flags_lo = method_attr_bands
1661:                    .newIntBand("method_flags_lo");
1662:            IntBand method_attr_count = method_attr_bands
1663:                    .newIntBand("method_attr_count");
1664:            IntBand method_attr_indexes = method_attr_bands
1665:                    .newIntBand("method_attr_indexes");
1666:            IntBand method_attr_calls = method_attr_bands
1667:                    .newIntBand("method_attr_calls");
1668:            // band for predefined method attributes
1669:            IntBand method_Exceptions_N = method_attr_bands
1670:                    .newIntBand("method_Exceptions_N");
1671:            CPRefBand method_Exceptions_RC = method_attr_bands.newCPRefBand(
1672:                    "method_Exceptions_RC", CONSTANT_Class);
1673:            CPRefBand method_Signature_RS = method_attr_bands.newCPRefBand(
1674:                    "method_Signature_RS", CONSTANT_Signature);
1675:            MultiBand method_metadata_bands = method_attr_bands.newMultiBand(
1676:                    "(method_metadata_bands)", UNSIGNED5);
1677:
1678:            MultiBand class_attr_bands = class_bands.newMultiBand(
1679:                    "(class_attr_bands)", UNSIGNED5);
1680:            IntBand class_flags_hi = class_attr_bands
1681:                    .newIntBand("class_flags_hi");
1682:            IntBand class_flags_lo = class_attr_bands
1683:                    .newIntBand("class_flags_lo");
1684:            IntBand class_attr_count = class_attr_bands
1685:                    .newIntBand("class_attr_count");
1686:            IntBand class_attr_indexes = class_attr_bands
1687:                    .newIntBand("class_attr_indexes");
1688:            IntBand class_attr_calls = class_attr_bands
1689:                    .newIntBand("class_attr_calls");
1690:            // band for predefined SourceFile and other class attributes
1691:            CPRefBand class_SourceFile_RUN = class_attr_bands.newCPRefBand(
1692:                    "class_SourceFile_RUN", UNSIGNED5, CONSTANT_Utf8,
1693:                    NULL_IS_OK);
1694:            CPRefBand class_EnclosingMethod_RC = class_attr_bands.newCPRefBand(
1695:                    "class_EnclosingMethod_RC", CONSTANT_Class);
1696:            CPRefBand class_EnclosingMethod_RDN = class_attr_bands
1697:                    .newCPRefBand("class_EnclosingMethod_RDN", UNSIGNED5,
1698:                            CONSTANT_NameandType, NULL_IS_OK);
1699:            CPRefBand class_Signature_RS = class_attr_bands.newCPRefBand(
1700:                    "class_Signature_RS", CONSTANT_Signature);
1701:            MultiBand class_metadata_bands = class_attr_bands.newMultiBand(
1702:                    "(class_metadata_bands)", UNSIGNED5);
1703:            IntBand class_InnerClasses_N = class_attr_bands
1704:                    .newIntBand("class_InnerClasses_N");
1705:            CPRefBand class_InnerClasses_RC = class_attr_bands.newCPRefBand(
1706:                    "class_InnerClasses_RC", CONSTANT_Class);
1707:            IntBand class_InnerClasses_F = class_attr_bands
1708:                    .newIntBand("class_InnerClasses_F");
1709:            CPRefBand class_InnerClasses_outer_RCN = class_attr_bands
1710:                    .newCPRefBand("class_InnerClasses_outer_RCN", UNSIGNED5,
1711:                            CONSTANT_Class, NULL_IS_OK);
1712:            CPRefBand class_InnerClasses_name_RUN = class_attr_bands
1713:                    .newCPRefBand("class_InnerClasses_name_RUN", UNSIGNED5,
1714:                            CONSTANT_Utf8, NULL_IS_OK);
1715:            IntBand class_ClassFile_version_minor_H = class_attr_bands
1716:                    .newIntBand("class_ClassFile_version_minor_H");
1717:            IntBand class_ClassFile_version_major_H = class_attr_bands
1718:                    .newIntBand("class_ClassFile_version_major_H");
1719:
1720:            MultiBand code_bands = class_bands.newMultiBand("(code_bands)",
1721:                    UNSIGNED5);
1722:            ByteBand code_headers = code_bands.newByteBand("code_headers"); //BYTE1
1723:            IntBand code_max_stack = code_bands.newIntBand("code_max_stack",
1724:                    UNSIGNED5);
1725:            IntBand code_max_na_locals = code_bands.newIntBand(
1726:                    "code_max_na_locals", UNSIGNED5);
1727:            IntBand code_handler_count = code_bands.newIntBand(
1728:                    "code_handler_count", UNSIGNED5);
1729:            IntBand code_handler_start_P = code_bands.newIntBand(
1730:                    "code_handler_start_P", BCI5);
1731:            IntBand code_handler_end_PO = code_bands.newIntBand(
1732:                    "code_handler_end_PO", BRANCH5);
1733:            IntBand code_handler_catch_PO = code_bands.newIntBand(
1734:                    "code_handler_catch_PO", BRANCH5);
1735:            CPRefBand code_handler_class_RCN = code_bands.newCPRefBand(
1736:                    "code_handler_class_RCN", UNSIGNED5, CONSTANT_Class,
1737:                    NULL_IS_OK);
1738:
1739:            MultiBand code_attr_bands = class_bands.newMultiBand(
1740:                    "(code_attr_bands)", UNSIGNED5);
1741:            IntBand code_flags_hi = code_attr_bands.newIntBand("code_flags_hi");
1742:            IntBand code_flags_lo = code_attr_bands.newIntBand("code_flags_lo");
1743:            IntBand code_attr_count = code_attr_bands
1744:                    .newIntBand("code_attr_count");
1745:            IntBand code_attr_indexes = code_attr_bands
1746:                    .newIntBand("code_attr_indexes");
1747:            IntBand code_attr_calls = code_attr_bands
1748:                    .newIntBand("code_attr_calls");
1749:
1750:            MultiBand stackmap_bands = code_attr_bands.newMultiBand(
1751:                    "StackMapTable_bands", UNSIGNED5);
1752:            IntBand code_StackMapTable_N = stackmap_bands
1753:                    .newIntBand("code_StackMapTable_N");
1754:            IntBand code_StackMapTable_frame_T = stackmap_bands.newIntBand(
1755:                    "code_StackMapTable_frame_T", BYTE1);
1756:            IntBand code_StackMapTable_local_N = stackmap_bands
1757:                    .newIntBand("code_StackMapTable_local_N");
1758:            IntBand code_StackMapTable_stack_N = stackmap_bands
1759:                    .newIntBand("code_StackMapTable_stack_N");
1760:            IntBand code_StackMapTable_offset = stackmap_bands.newIntBand(
1761:                    "code_StackMapTable_offset", UNSIGNED5);
1762:            IntBand code_StackMapTable_T = stackmap_bands.newIntBand(
1763:                    "code_StackMapTable_T", BYTE1);
1764:            CPRefBand code_StackMapTable_RC = stackmap_bands.newCPRefBand(
1765:                    "code_StackMapTable_RC", CONSTANT_Class);
1766:            IntBand code_StackMapTable_P = stackmap_bands.newIntBand(
1767:                    "code_StackMapTable_P", BCI5);
1768:
1769:            // bands for predefined LineNumberTable attribute
1770:            IntBand code_LineNumberTable_N = code_attr_bands
1771:                    .newIntBand("code_LineNumberTable_N");
1772:            IntBand code_LineNumberTable_bci_P = code_attr_bands.newIntBand(
1773:                    "code_LineNumberTable_bci_P", BCI5);
1774:            IntBand code_LineNumberTable_line = code_attr_bands
1775:                    .newIntBand("code_LineNumberTable_line");
1776:
1777:            // bands for predefined LocalVariable{Type}Table attributes
1778:            IntBand code_LocalVariableTable_N = code_attr_bands
1779:                    .newIntBand("code_LocalVariableTable_N");
1780:            IntBand code_LocalVariableTable_bci_P = code_attr_bands.newIntBand(
1781:                    "code_LocalVariableTable_bci_P", BCI5);
1782:            IntBand code_LocalVariableTable_span_O = code_attr_bands
1783:                    .newIntBand("code_LocalVariableTable_span_O", BRANCH5);
1784:            CPRefBand code_LocalVariableTable_name_RU = code_attr_bands
1785:                    .newCPRefBand("code_LocalVariableTable_name_RU",
1786:                            CONSTANT_Utf8);
1787:            CPRefBand code_LocalVariableTable_type_RS = code_attr_bands
1788:                    .newCPRefBand("code_LocalVariableTable_type_RS",
1789:                            CONSTANT_Signature);
1790:            IntBand code_LocalVariableTable_slot = code_attr_bands
1791:                    .newIntBand("code_LocalVariableTable_slot");
1792:            IntBand code_LocalVariableTypeTable_N = code_attr_bands
1793:                    .newIntBand("code_LocalVariableTypeTable_N");
1794:            IntBand code_LocalVariableTypeTable_bci_P = code_attr_bands
1795:                    .newIntBand("code_LocalVariableTypeTable_bci_P", BCI5);
1796:            IntBand code_LocalVariableTypeTable_span_O = code_attr_bands
1797:                    .newIntBand("code_LocalVariableTypeTable_span_O", BRANCH5);
1798:            CPRefBand code_LocalVariableTypeTable_name_RU = code_attr_bands
1799:                    .newCPRefBand("code_LocalVariableTypeTable_name_RU",
1800:                            CONSTANT_Utf8);
1801:            CPRefBand code_LocalVariableTypeTable_type_RS = code_attr_bands
1802:                    .newCPRefBand("code_LocalVariableTypeTable_type_RS",
1803:                            CONSTANT_Signature);
1804:            IntBand code_LocalVariableTypeTable_slot = code_attr_bands
1805:                    .newIntBand("code_LocalVariableTypeTable_slot");
1806:
1807:            // bands for bytecodes
1808:            MultiBand bc_bands = all_bands.newMultiBand("(byte_codes)",
1809:                    UNSIGNED5);
1810:            ByteBand bc_codes = bc_bands.newByteBand("bc_codes"); //BYTE1
1811:            // remaining bands provide typed opcode fields required by the bc_codes
1812:
1813:            IntBand bc_case_count = bc_bands.newIntBand("bc_case_count"); // *switch
1814:            IntBand bc_case_value = bc_bands
1815:                    .newIntBand("bc_case_value", DELTA5); // *switch
1816:            ByteBand bc_byte = bc_bands.newByteBand("bc_byte"); //BYTE1   // bipush, iinc, *newarray
1817:            IntBand bc_short = bc_bands.newIntBand("bc_short", DELTA5); // sipush, wide iinc
1818:            IntBand bc_local = bc_bands.newIntBand("bc_local"); // *load, *store, iinc, ret
1819:            IntBand bc_label = bc_bands.newIntBand("bc_label", BRANCH5); // if*, goto*, jsr*, *switch
1820:
1821:            // Most CP refs exhibit some correlation, and benefit from delta coding.
1822:            // The notable exceptions are class and method references.
1823:
1824:            // ldc* operands:
1825:            CPRefBand bc_intref = bc_bands.newCPRefBand("bc_intref", DELTA5,
1826:                    CONSTANT_Integer);
1827:            CPRefBand bc_floatref = bc_bands.newCPRefBand("bc_floatref",
1828:                    DELTA5, CONSTANT_Float);
1829:            CPRefBand bc_longref = bc_bands.newCPRefBand("bc_longref", DELTA5,
1830:                    CONSTANT_Long);
1831:            CPRefBand bc_doubleref = bc_bands.newCPRefBand("bc_doubleref",
1832:                    DELTA5, CONSTANT_Double);
1833:            CPRefBand bc_stringref = bc_bands.newCPRefBand("bc_stringref",
1834:                    DELTA5, CONSTANT_String);
1835:
1836:            // nulls produced by bc_classref are taken to mean the current class
1837:            CPRefBand bc_classref = bc_bands.newCPRefBand("bc_classref",
1838:                    UNSIGNED5, CONSTANT_Class, NULL_IS_OK); // new, *anew*, c*cast, i*of, ldc
1839:            CPRefBand bc_fieldref = bc_bands.newCPRefBand("bc_fieldref",
1840:                    DELTA5, CONSTANT_Fieldref); // get*, put*
1841:            CPRefBand bc_methodref = bc_bands.newCPRefBand("bc_methodref",
1842:                    CONSTANT_Methodref); // invoke[vs]*
1843:            CPRefBand bc_imethodref = bc_bands.newCPRefBand("bc_imethodref",
1844:                    DELTA5, CONSTANT_InterfaceMethodref); // invokeinterface
1845:
1846:            // _self_linker_op family
1847:            CPRefBand bc_this field = bc_bands.newCPRefBand("bc_thisfield",
1848:                    CONSTANT_None); // any field within cur. class
1849:            CPRefBand bc_super field = bc_bands.newCPRefBand("bc_superfield",
1850:                    CONSTANT_None); // any field within superclass
1851:            CPRefBand bc_this method = bc_bands.newCPRefBand("bc_thismethod",
1852:                    CONSTANT_None); // any method within cur. class
1853:            CPRefBand bc_super method = bc_bands.newCPRefBand("bc_supermethod",
1854:                    CONSTANT_None); // any method within superclass
1855:            // bc_invokeinit family:
1856:            IntBand bc_initref = bc_bands.newIntBand("bc_initref");
1857:            // escapes
1858:            CPRefBand bc_escref = bc_bands.newCPRefBand("bc_escref",
1859:                    CONSTANT_All);
1860:            IntBand bc_escrefsize = bc_bands.newIntBand("bc_escrefsize");
1861:            IntBand bc_escsize = bc_bands.newIntBand("bc_escsize");
1862:            ByteBand bc_escbyte = bc_bands.newByteBand("bc_escbyte");
1863:
1864:            // bands for carrying resource files and file attributes:
1865:            MultiBand file_bands = all_bands.newMultiBand("(file_bands)",
1866:                    UNSIGNED5);
1867:            CPRefBand file_name = file_bands.newCPRefBand("file_name",
1868:                    CONSTANT_Utf8);
1869:            IntBand file_size_hi = file_bands.newIntBand("file_size_hi");
1870:            IntBand file_size_lo = file_bands.newIntBand("file_size_lo");
1871:            IntBand file_modtime = file_bands
1872:                    .newIntBand("file_modtime", DELTA5);
1873:            IntBand file_options = file_bands.newIntBand("file_options");
1874:            ByteBand file_bits = file_bands.newByteBand("file_bits");
1875:
1876:            // End of band definitions!
1877:
1878:            /** Given CP indexes, distribute tag-specific indexes to bands. */
1879:            protected void setBandIndexes() {
1880:                // Handle prior calls to setBandIndex:
1881:                for (Iterator i = needPredefIndex.iterator(); i.hasNext();) {
1882:                    Object[] need = (Object[]) i.next();
1883:                    CPRefBand b = (CPRefBand) need[0];
1884:                    Byte which = (Byte) need[1];
1885:                    b.setIndex(getCPIndex(which.byteValue()));
1886:                }
1887:                needPredefIndex = null; // no more predefs
1888:
1889:                if (verbose > 3) {
1890:                    printCDecl(all_bands);
1891:                }
1892:            }
1893:
1894:            protected void setBandIndex(CPRefBand b, byte which) {
1895:                Object[] need = { b, new Byte(which) };
1896:                if (which == CONSTANT_Literal) {
1897:                    // I.e., attribute layouts KQ (no null) or KQN (null ok).
1898:                    allKQBands.add(b);
1899:                } else if (needPredefIndex != null) {
1900:                    needPredefIndex.add(need);
1901:                } else {
1902:                    // Not in predefinition mode; getCPIndex now works.
1903:                    b.setIndex(getCPIndex(which));
1904:                }
1905:            }
1906:
1907:            protected void setConstantValueIndex(Class.Field f) {
1908:                Index ix = null;
1909:                if (f != null) {
1910:                    byte tag = f.getLiteralTag();
1911:                    ix = getCPIndex(tag);
1912:                    if (verbose > 2)
1913:                        Utils.log.fine("setConstantValueIndex " + f + " "
1914:                                + ConstantPool.tagName(tag) + " => " + ix);
1915:                    assert (ix != null);
1916:                }
1917:                // Typically, allKQBands is the singleton of field_ConstantValue_KQ.
1918:                for (Iterator i = allKQBands.iterator(); i.hasNext();) {
1919:                    CPRefBand xxx_KQ = (CPRefBand) i.next();
1920:                    xxx_KQ.setIndex(ix);
1921:                }
1922:            }
1923:
1924:            // Table of bands which contain metadata.
1925:            protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
1926:            {
1927:                metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands;
1928:                metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
1929:                metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
1930:            }
1931:
1932:            // Attribute layouts.
1933:            public static final int ADH_CONTEXT_MASK = 0x3; // (ad_hdr & ADH_CONTEXT_MASK)
1934:            public static final int ADH_BIT_SHIFT = 0x2; // (ad_hdr >> ADH_BIT_SHIFT)
1935:            public static final int ADH_BIT_IS_LSB = 1;
1936:            public static final int ATTR_INDEX_OVERFLOW = -1;
1937:
1938:            public int[] attrIndexLimit = new int[ATTR_CONTEXT_LIMIT];
1939:            // Each index limit is either 32 or 63, depending on AO_HAVE_XXX_FLAGS_HI.
1940:
1941:            // Which flag bits are taken over by attributes?
1942:            protected long[] attrFlagMask = new long[ATTR_CONTEXT_LIMIT];
1943:            // Which flag bits have been taken over explicitly?
1944:            protected long[] attrDefSeen = new long[ATTR_CONTEXT_LIMIT];
1945:
1946:            // What pseudo-attribute bits are there to watch for?
1947:            protected int[] attrOverflowMask = new int[ATTR_CONTEXT_LIMIT];
1948:            protected int attrClassFileVersionMask;
1949:
1950:            // Mapping from Attribute.Layout to Band[] (layout element bands).
1951:            protected HashMap attrBandTable = new HashMap();
1952:
1953:            // Well-known attributes:
1954:            protected final Attribute.Layout attrCodeEmpty;
1955:            protected final Attribute.Layout attrInnerClassesEmpty;
1956:            protected final Attribute.Layout attrClassFileVersion;
1957:            protected final Attribute.Layout attrConstantValue;
1958:
1959:            // Mapping from Attribute.Layout to Integer (inverse of attrDefs)
1960:            HashMap attrIndexTable = new HashMap();
1961:
1962:            // Mapping from attribute index (<32 are flag bits) to attributes.
1963:            protected ArrayList[] attrDefs = new ArrayList[ATTR_CONTEXT_LIMIT];
1964:            {
1965:                for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
1966:                    assert (attrIndexLimit[i] == 0);
1967:                    attrIndexLimit[i] = 32; // just for the sake of predefs.
1968:                    attrDefs[i] = new ArrayList(Collections.nCopies(
1969:                            attrIndexLimit[i], null));
1970:                }
1971:
1972:                // Add predefined attribute definitions:
1973:                attrInnerClassesEmpty = predefineAttribute(
1974:                        CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null,
1975:                        "InnerClasses", "");
1976:                assert (attrInnerClassesEmpty == Package.attrInnerClassesEmpty);
1977:                predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS,
1978:                        new Band[] { class_SourceFile_RUN }, "SourceFile",
1979:                        "RUNH");
1980:                predefineAttribute(CLASS_ATTR_EnclosingMethod,
1981:                        ATTR_CONTEXT_CLASS, new Band[] {
1982:                                class_EnclosingMethod_RC,
1983:                                class_EnclosingMethod_RDN }, "EnclosingMethod",
1984:                        "RCHRDNH");
1985:                attrClassFileVersion = predefineAttribute(
1986:                        CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS,
1987:                        new Band[] { class_ClassFile_version_minor_H,
1988:                                class_ClassFile_version_major_H },
1989:                        ".ClassFile.version", "HH");
1990:                predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS,
1991:                        new Band[] { class_Signature_RS }, "Signature", "RSH");
1992:                predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null,
1993:                        "Deprecated", "");
1994:                //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null,
1995:                //		   "Synthetic", "");
1996:                predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null,
1997:                        ".Overflow", "");
1998:                attrConstantValue = predefineAttribute(
1999:                        FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD,
2000:                        new Band[] { field_ConstantValue_KQ }, "ConstantValue",
2001:                        "KQH");
2002:                predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD,
2003:                        new Band[] { field_Signature_RS }, "Signature", "RSH");
2004:                predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null,
2005:                        "Deprecated", "");
2006:                //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null,
2007:                //		   "Synthetic", "");
2008:                predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null,
2009:                        ".Overflow", "");
2010:                attrCodeEmpty = predefineAttribute(METHOD_ATTR_Code,
2011:                        ATTR_CONTEXT_METHOD, null, "Code", "");
2012:                predefineAttribute(
2013:                        METHOD_ATTR_Exceptions,
2014:                        ATTR_CONTEXT_METHOD,
2015:                        new Band[] { method_Exceptions_N, method_Exceptions_RC },
2016:                        "Exceptions", "NH[RCH]");
2017:                assert (attrCodeEmpty == Package.attrCodeEmpty);
2018:                predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
2019:                        new Band[] { method_Signature_RS }, "Signature", "RSH");
2020:                predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD,
2021:                        null, "Deprecated", "");
2022:                //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null,
2023:                //		   "Synthetic", "");
2024:                predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null,
2025:                        ".Overflow", "");
2026:
2027:                for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
2028:                    MultiBand xxx_metadata_bands = metadataBands[ctype];
2029:                    if (xxx_metadata_bands == null)
2030:                        continue; // no code attrs
2031:
2032:                    // These arguments cause the bands to be built
2033:                    // automatically for this complicated layout:
2034:                    predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
2035:                            ATTR_CONTEXT_NAME[ctype] + "_RVA_",
2036:                            xxx_metadata_bands, Attribute.lookup(null, ctype,
2037:                                    "RuntimeVisibleAnnotations"));
2038:                    predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
2039:                            ATTR_CONTEXT_NAME[ctype] + "_RIA_",
2040:                            xxx_metadata_bands, Attribute.lookup(null, ctype,
2041:                                    "RuntimeInvisibleAnnotations"));
2042:                    if (ctype != ATTR_CONTEXT_METHOD)
2043:                        continue;
2044:
2045:                    predefineAttribute(
2046:                            METHOD_ATTR_RuntimeVisibleParameterAnnotations,
2047:                            "method_RVPA_", xxx_metadata_bands,
2048:                            Attribute.lookup(null, ctype,
2049:                                    "RuntimeVisibleParameterAnnotations"));
2050:                    predefineAttribute(
2051:                            METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
2052:                            "method_RIPA_", xxx_metadata_bands,
2053:                            Attribute.lookup(null, ctype,
2054:                                    "RuntimeInvisibleParameterAnnotations"));
2055:                    predefineAttribute(METHOD_ATTR_AnnotationDefault,
2056:                            "method_AD_", xxx_metadata_bands, Attribute.lookup(
2057:                                    null, ctype, "AnnotationDefault"));
2058:                }
2059:
2060:                Attribute.Layout stackMapDef = Attribute.lookup(null,
2061:                        ATTR_CONTEXT_CODE, "StackMapTable").layout();
2062:                predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE,
2063:                        stackmap_bands.toArray(), stackMapDef.name(),
2064:                        stackMapDef.layout());
2065:
2066:                predefineAttribute(CODE_ATTR_LineNumberTable,
2067:                        ATTR_CONTEXT_CODE, new Band[] { code_LineNumberTable_N,
2068:                                code_LineNumberTable_bci_P,
2069:                                code_LineNumberTable_line }, "LineNumberTable",
2070:                        "NH[PHH]");
2071:                predefineAttribute(CODE_ATTR_LocalVariableTable,
2072:                        ATTR_CONTEXT_CODE, new Band[] {
2073:                                code_LocalVariableTable_N,
2074:                                code_LocalVariableTable_bci_P,
2075:                                code_LocalVariableTable_span_O,
2076:                                code_LocalVariableTable_name_RU,
2077:                                code_LocalVariableTable_type_RS,
2078:                                code_LocalVariableTable_slot },
2079:                        "LocalVariableTable", "NH[PHOHRUHRSHH]");
2080:                predefineAttribute(CODE_ATTR_LocalVariableTypeTable,
2081:                        ATTR_CONTEXT_CODE, new Band[] {
2082:                                code_LocalVariableTypeTable_N,
2083:                                code_LocalVariableTypeTable_bci_P,
2084:                                code_LocalVariableTypeTable_span_O,
2085:                                code_LocalVariableTypeTable_name_RU,
2086:                                code_LocalVariableTypeTable_type_RS,
2087:                                code_LocalVariableTypeTable_slot },
2088:                        "LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
2089:                predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null,
2090:                        ".Overflow", "");
2091:
2092:                // Clear the record of having seen these definitions,
2093:                // so they may be redefined without error.
2094:                for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
2095:                    attrDefSeen[i] = 0;
2096:                }
2097:
2098:                // Set up the special masks:
2099:                for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
2100:                    attrOverflowMask[i] = (1 << X_ATTR_OVERFLOW);
2101:                    attrIndexLimit[i] = 0; // will make a final decision later
2102:                }
2103:                attrClassFileVersionMask = (1 << CLASS_ATTR_ClassFile_version);
2104:            }
2105:
2106:            private void adjustToMajver() {
2107:                if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) {
2108:                    if (verbose > 0)
2109:                        Utils.log.fine("Legacy package version");
2110:                    // Revoke definition of pre-1.6 attribute type.
2111:                    undefineAttribute(CODE_ATTR_StackMapTable,
2112:                            ATTR_CONTEXT_CODE);
2113:                }
2114:            }
2115:
2116:            protected void initAttrIndexLimit() {
2117:                for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
2118:                    assert (attrIndexLimit[i] == 0); // decide on it now!
2119:                    attrIndexLimit[i] = (haveFlagsHi(i) ? 63 : 32);
2120:                    assert (attrDefs[i].size() == 32); // all predef indexes are <32
2121:                    int addMore = attrIndexLimit[i] - attrDefs[i].size();
2122:                    attrDefs[i].addAll(Collections.nCopies(addMore, null));
2123:                }
2124:            }
2125:
2126:            protected boolean haveFlagsHi(int ctype) {
2127:                int mask = 1 << (LG_AO_HAVE_XXX_FLAGS_HI + ctype);
2128:                switch (ctype) {
2129:                case ATTR_CONTEXT_CLASS:
2130:                    assert (mask == AO_HAVE_CLASS_FLAGS_HI);
2131:                    break;
2132:                case ATTR_CONTEXT_FIELD:
2133:                    assert (mask == AO_HAVE_FIELD_FLAGS_HI);
2134:                    break;
2135:                case ATTR_CONTEXT_METHOD:
2136:                    assert (mask == AO_HAVE_METHOD_FLAGS_HI);
2137:                    break;
2138:                case ATTR_CONTEXT_CODE:
2139:                    assert (mask == AO_HAVE_CODE_FLAGS_HI);
2140:                    break;
2141:                default:
2142:                    assert (false);
2143:                }
2144:                return testBit(archiveOptions, mask);
2145:            }
2146:
2147:            protected ArrayList getPredefinedAttrs(int ctype) {
2148:                assert (attrIndexLimit[ctype] != 0);
2149:                ArrayList res = new ArrayList(attrIndexLimit[ctype]);
2150:                // Remove nulls and non-predefs.
2151:                for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) {
2152:                    if (testBit(attrDefSeen[ctype], 1L << ai))
2153:                        continue;
2154:                    Attribute.Layout def = (Attribute.Layout) attrDefs[ctype]
2155:                            .get(ai);
2156:                    if (def == null)
2157:                        continue; // unused flag bit
2158:                    assert (isPredefinedAttr(ctype, ai));
2159:                    res.add(def);
2160:                }
2161:                return res;
2162:            }
2163:
2164:            protected boolean isPredefinedAttr(int ctype, int ai) {
2165:                assert (attrIndexLimit[ctype] != 0);
2166:                // Overflow attrs are never predefined.
2167:                if (ai >= attrIndexLimit[ctype])
2168:                    return false;
2169:                // If the bit is set, it was explicitly def'd.
2170:                if (testBit(attrDefSeen[ctype], 1L << ai))
2171:                    return false;
2172:                return (attrDefs[ctype].get(ai) != null);
2173:            }
2174:
2175:            protected void adjustSpecialAttrMasks() {
2176:                // Clear special masks if new definitions have been seen for them.
2177:                attrClassFileVersionMask &= ~attrDefSeen[ATTR_CONTEXT_CLASS];
2178:                // It is possible to clear the overflow mask (bit 16).
2179:                for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
2180:                    attrOverflowMask[i] &= ~attrDefSeen[i];
2181:                }
2182:            }
2183:
2184:            protected Attribute makeClassFileVersionAttr(int minver, int majver) {
2185:                byte[] bytes = { (byte) (minver >> 8), (byte) minver,
2186:                        (byte) (majver >> 8), (byte) majver };
2187:                return attrClassFileVersion.addContent(bytes);
2188:            }
2189:
2190:            protected short[] parseClassFileVersionAttr(Attribute attr) {
2191:                assert (attr.layout() == attrClassFileVersion);
2192:                assert (attr.size() == 4);
2193:                byte[] bytes = attr.bytes();
2194:                int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
2195:                int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
2196:                return new short[] { (short) minver, (short) majver };
2197:            }
2198:
2199:            private boolean assertBandOKForElems(Band[] ab,
2200:                    Attribute.Layout.Element[] elems) {
2201:                for (int i = 0; i < elems.length; i++) {
2202:                    assert (assertBandOKForElem(ab, elems[i]));
2203:                }
2204:                return true;
2205:            }
2206:
2207:            private boolean assertBandOKForElem(Band[] ab,
2208:                    Attribute.Layout.Element e) {
2209:                Band b = null;
2210:                if (e.bandIndex != Attribute.NO_BAND_INDEX)
2211:                    b = ab[e.bandIndex];
2212:                Coding rc = UNSIGNED5;
2213:                boolean wantIntBand = true;
2214:                switch (e.kind) {
2215:                case Attribute.EK_INT:
2216:                    if (e.flagTest(Attribute.EF_SIGN)) {
2217:                        rc = SIGNED5;
2218:                    } else if (e.len == 1) {
2219:                        rc = BYTE1;
2220:                    }
2221:                    break;
2222:                case Attribute.EK_BCI:
2223:                    if (!e.flagTest(Attribute.EF_DELTA)) {
2224:                        rc = BCI5;
2225:                    } else {
2226:                        rc = BRANCH5;
2227:                    }
2228:                    break;
2229:                case Attribute.EK_BCO:
2230:                    rc = BRANCH5;
2231:                    break;
2232:                case Attribute.EK_FLAG:
2233:                    if (e.len == 1)
2234:                        rc = BYTE1;
2235:                    break;
2236:                case Attribute.EK_REPL:
2237:                    if (e.len == 1)
2238:                        rc = BYTE1;
2239:                    assertBandOKForElems(ab, e.body);
2240:                    break;
2241:                case Attribute.EK_UN:
2242:                    if (e.flagTest(Attribute.EF_SIGN)) {
2243:                        rc = SIGNED5;
2244:                    } else if (e.len == 1) {
2245:                        rc = BYTE1;
2246:                    }
2247:                    assertBandOKForElems(ab, e.body);
2248:                    break;
2249:                case Attribute.EK_CASE:
2250:                    assert (b == null);
2251:                    assertBandOKForElems(ab, e.body);
2252:                    return true; // no direct band
2253:                case Attribute.EK_CALL:
2254:                    assert (b == null);
2255:                    return true; // no direct band
2256:                case Attribute.EK_CBLE:
2257:                    assert (b == null);
2258:                    assertBandOKForElems(ab, e.body);
2259:                    return true; // no direct band
2260:                case Attribute.EK_REF:
2261:                    wantIntBand = false;
2262:                    assert (b instanceof  CPRefBand);
2263:                    assert (((CPRefBand) b).nullOK == e
2264:                            .flagTest(Attribute.EF_NULL));
2265:                    break;
2266:                default:
2267:                    assert (false);
2268:                }
2269:                assert (b.regularCoding == rc) : (e + " // " + b);
2270:                if (wantIntBand)
2271:                    assert (b instanceof  IntBand);
2272:                return true;
2273:            }
2274:
2275:            private Attribute.Layout predefineAttribute(int index, int ctype,
2276:                    Band[] ab, String name, String layout) {
2277:                // Use Attribute.find to get uniquification of layouts.
2278:                Attribute.Layout def = Attribute.find(ctype, name, layout)
2279:                        .layout();
2280:                //def.predef = true;
2281:                if (index >= 0) {
2282:                    setAttributeLayoutIndex(def, index);
2283:                }
2284:                if (ab == null) {
2285:                    ab = new Band[0];
2286:                }
2287:                assert (attrBandTable.get(def) == null); // no redef
2288:                attrBandTable.put(def, ab);
2289:                assert (def.bandCount == ab.length) : (def + " // " + Arrays
2290:                        .asList(ab));
2291:                // Let's make sure the band types match:
2292:                assert (assertBandOKForElems(ab, def.elems));
2293:                return def;
2294:            }
2295:
2296:            // This version takes bandPrefix/addHere instead of prebuilt Band[] ab.
2297:            private Attribute.Layout predefineAttribute(int index,
2298:                    String bandPrefix, MultiBand addHere, Attribute attr) {
2299:                //Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
2300:                Attribute.Layout def = attr.layout();
2301:                int ctype = def.ctype();
2302:                return predefineAttribute(index, ctype, makeNewAttributeBands(
2303:                        bandPrefix, def, addHere), def.name(), def.layout());
2304:            }
2305:
2306:            private void undefineAttribute(int index, int ctype) {
2307:                if (verbose > 1) {
2308:                    System.out.println("Removing predefined "
2309:                            + ATTR_CONTEXT_NAME[ctype] + " attribute on bit "
2310:                            + index);
2311:                }
2312:                List defList = attrDefs[ctype];
2313:                Attribute.Layout def = (Attribute.Layout) defList.get(index);
2314:                assert (def != null);
2315:                defList.set(index, null);
2316:                attrIndexTable.put(def, null);
2317:                // Clear the def bit.  (For predefs, it's already clear.)
2318:                assert (index < 64);
2319:                attrDefSeen[ctype] &= ~(1L << index);
2320:                attrFlagMask[ctype] &= ~(1L << index);
2321:                Band[] ab = (Band[]) attrBandTable.get(def);
2322:                for (int j = 0; j < ab.length; j++) {
2323:                    ab[j].doneWithUnusedBand();
2324:                }
2325:            }
2326:
2327:            // Bands which contain non-predefined attrs.
2328:            protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT];
2329:            {
2330:                attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands;
2331:                attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands;
2332:                attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands;
2333:                attrBands[ATTR_CONTEXT_CODE] = code_attr_bands;
2334:            }
2335:
2336:            // Create bands for all non-predefined attrs.
2337:            void makeNewAttributeBands() {
2338:                // Retract special flag bit bindings, if they were taken over.
2339:                adjustSpecialAttrMasks();
2340:
2341:                for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
2342:                    String cname = ATTR_CONTEXT_NAME[ctype];
2343:                    MultiBand xxx_attr_bands = attrBands[ctype];
2344:                    long defSeen = attrDefSeen[ctype];
2345:                    // Note: attrDefSeen is always a subset of attrFlagMask.
2346:                    assert ((defSeen & ~attrFlagMask[ctype]) == 0);
2347:                    for (int i = 0; i < attrDefs[ctype].size(); i++) {
2348:                        Attribute.Layout def = (Attribute.Layout) attrDefs[ctype]
2349:                                .get(i);
2350:                        if (def == null)
2351:                            continue; // unused flag bit
2352:                        if (def.bandCount == 0)
2353:                            continue; // empty attr
2354:                        if (i < attrIndexLimit[ctype]
2355:                                && !testBit(defSeen, 1L << i)) {
2356:                            // There are already predefined bands here.
2357:                            assert (attrBandTable.get(def) != null);
2358:                            continue;
2359:                        }
2360:                        int base = xxx_attr_bands.size();
2361:                        String pfx = cname + "_" + def.name() + "_"; // debug only
2362:                        if (verbose > 1)
2363:                            Utils.log.fine("Making new bands for " + def);
2364:                        Band[] newAB = makeNewAttributeBands(pfx, def,
2365:                                xxx_attr_bands);
2366:                        assert (newAB.length == def.bandCount);
2367:                        Band[] prevAB = (Band[]) attrBandTable.put(def, newAB);
2368:                        if (prevAB != null) {
2369:                            // We won't be using these predefined bands.
2370:                            for (int j = 0; j < prevAB.length; j++) {
2371:                                prevAB[j].doneWithUnusedBand();
2372:                            }
2373:                        }
2374:                    }
2375:                }
2376:                //System.out.println(prevForAssertMap);
2377:            }
2378:
2379:            private Band[] makeNewAttributeBands(String pfx,
2380:                    Attribute.Layout def, MultiBand addHere) {
2381:                int base = addHere.size();
2382:                makeNewAttributeBands(pfx, def.elems, addHere);
2383:                int nb = addHere.size() - base;
2384:                Band[] newAB = new Band[nb];
2385:                for (int i = 0; i < nb; i++) {
2386:                    newAB[i] = addHere.get(base + i);
2387:                }
2388:                return newAB;
2389:            }
2390:
2391:            // Recursive helper, operates on a "body" or other sequence of elems:
2392:            private void makeNewAttributeBands(String pfx,
2393:                    Attribute.Layout.Element[] elems, MultiBand ab) {
2394:                for (int i = 0; i < elems.length; i++) {
2395:                    Attribute.Layout.Element e = elems[i];
2396:                    String name = pfx + ab.size() + "_" + e.layout;
2397:                    {
2398:                        int tem;
2399:                        if ((tem = name.indexOf('[')) > 0)
2400:                            name = name.substring(0, tem);
2401:                        if ((tem = name.indexOf('(')) > 0)
2402:                            name = name.substring(0, tem);
2403:                        if (name.endsWith("H"))
2404:                            name = name.substring(0, name.length() - 1);
2405:                    }
2406:                    Band nb;
2407:                    switch (e.kind) {
2408:                    case Attribute.EK_INT:
2409:                        nb = newElemBand(e, name, ab);
2410:                        break;
2411:                    case Attribute.EK_BCI:
2412:                        if (!e.flagTest(Attribute.EF_DELTA)) {
2413:                            // PH:  transmit R(bci), store bci
2414:                            nb = ab.newIntBand(name, BCI5);
2415:                        } else {
2416:                            // POH:  transmit D(R(bci)), store bci
2417:                            nb = ab.newIntBand(name, BRANCH5);
2418:                        }
2419:                        // Note:  No case for BYTE1 here.
2420:                        break;
2421:                    case Attribute.EK_BCO:
2422:                        // OH:  transmit D(R(bci)), store D(bci)
2423:                        nb = ab.newIntBand(name, BRANCH5);
2424:                        // Note:  No case for BYTE1 here.
2425:                        break;
2426:                    case Attribute.EK_FLAG:
2427:                        assert (!e.flagTest(Attribute.EF_SIGN));
2428:                        nb = newElemBand(e, name, ab);
2429:                        break;
2430:                    case Attribute.EK_REPL:
2431:                        assert (!e.flagTest(Attribute.EF_SIGN));
2432:                        nb = newElemBand(e, name, ab);
2433:                        makeNewAttributeBands(pfx, e.body, ab);
2434:                        break;
2435:                    case Attribute.EK_UN:
2436:                        nb = newElemBand(e, name, ab);
2437:                        makeNewAttributeBands(pfx, e.body, ab);
2438:                        break;
2439:                    case Attribute.EK_CASE:
2440:                        if (!e.flagTest(Attribute.EF_BACK)) {
2441:                            // If it's not a duplicate body, make the bands.
2442:                            makeNewAttributeBands(pfx, e.body, ab);
2443:                        }
2444:                        continue; // no new band to make
2445:                    case Attribute.EK_REF:
2446:                        byte refKind = e.refKind;
2447:                        boolean nullOK = e.flagTest(Attribute.EF_NULL);
2448:                        nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK);
2449:                        // Note:  No case for BYTE1 here.
2450:                        break;
2451:                    case Attribute.EK_CALL:
2452:                        continue; // no new band to make
2453:                    case Attribute.EK_CBLE:
2454:                        makeNewAttributeBands(pfx, e.body, ab);
2455:                        continue; // no new band to make
2456:                    default:
2457:                        assert (false);
2458:                        continue;
2459:                    }
2460:                    if (verbose > 1) {
2461:                        Utils.log.fine("New attribute band " + nb);
2462:                    }
2463:                }
2464:            }
2465:
2466:            private Band newElemBand(Attribute.Layout.Element e, String name,
2467:                    MultiBand ab) {
2468:                if (e.flagTest(Attribute.EF_SIGN)) {
2469:                    return ab.newIntBand(name, SIGNED5);
2470:                } else if (e.len == 1) {
2471:                    return ab.newIntBand(name, BYTE1); // Not ByteBand, please.
2472:                } else {
2473:                    return ab.newIntBand(name, UNSIGNED5);
2474:                }
2475:            }
2476:
2477:            protected int setAttributeLayoutIndex(Attribute.Layout def,
2478:                    int index) {
2479:                int ctype = def.ctype;
2480:                assert (ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]);
2481:                List defList = attrDefs[ctype];
2482:                if (index == ATTR_INDEX_OVERFLOW) {
2483:                    // Overflow attribute.
2484:                    index = defList.size();
2485:                    defList.add(def);
2486:                    if (verbose > 0)
2487:                        Utils.log.info("Adding new attribute at " + def + ": "
2488:                                + index);
2489:                    attrIndexTable.put(def, new Integer(index));
2490:                    return index;
2491:                }
2492:
2493:                // Detect redefinitions:
2494:                if (testBit(attrDefSeen[ctype], 1L << index)) {
2495:                    throw new RuntimeException(
2496:                            "Multiple explicit definition at " + index + ": "
2497:                                    + def);
2498:                }
2499:                attrDefSeen[ctype] |= (1L << index);
2500:
2501:                // Adding a new fixed attribute.
2502:                assert (0 <= index && index < attrIndexLimit[ctype]);
2503:                if (verbose > (attrClassFileVersionMask == 0 ? 2 : 0))
2504:                    Utils.log.fine("Fixing new attribute at "
2505:                            + index
2506:                            + ": "
2507:                            + def
2508:                            + (defList.get(index) == null ? "" : "; replacing "
2509:                                    + defList.get(index)));
2510:                attrFlagMask[ctype] |= (1L << index);
2511:                // Remove index binding of any previous fixed attr.
2512:                attrIndexTable.put(defList.get(index), null);
2513:                defList.set(index, def);
2514:                attrIndexTable.put(def, new Integer(index));
2515:                return index;
2516:            }
2517:
2518:            // encodings found in the code_headers band
2519:            private static final int[][] shortCodeLimits = { { 12, 12 }, // s<12, l<12, e=0 [1..144]
2520:                    { 8, 8 }, //  s<8,  l<8, e=1 [145..208]
2521:                    { 7, 7 }, //  s<7,  l<7, e=2 [209..256]
2522:            };
2523:            public final int shortCodeHeader_h_limit = shortCodeLimits.length;
2524:
2525:            // return 0 if it won't encode, else a number in [1..255]
2526:            static int shortCodeHeader(Code code) {
2527:                int s = code.max_stack;
2528:                int l0 = code.max_locals;
2529:                int h = code.handler_class.length;
2530:                if (h >= shortCodeLimits.length)
2531:                    return LONG_CODE_HEADER;
2532:                int siglen = code.getMethod().getArgumentSize();
2533:                assert (l0 >= siglen); // enough locals for signature!
2534:                if (l0 < siglen)
2535:                    return LONG_CODE_HEADER;
2536:                int l1 = l0 - siglen; // do not count locals required by the signature
2537:                int lims = shortCodeLimits[h][0];
2538:                int liml = shortCodeLimits[h][1];
2539:                if (s >= lims || l1 >= liml)
2540:                    return LONG_CODE_HEADER;
2541:                int sc = shortCodeHeader_h_base(h);
2542:                sc += s + lims * l1;
2543:                if (sc > 255)
2544:                    return LONG_CODE_HEADER;
2545:                assert (shortCodeHeader_max_stack(sc) == s);
2546:                assert (shortCodeHeader_max_na_locals(sc) == l1);
2547:                assert (shortCodeHeader_handler_count(sc) == h);
2548:                return sc;
2549:            }
2550:
2551:            static final int LONG_CODE_HEADER = 0;
2552:
2553:            static int shortCodeHeader_handler_count(int sc) {
2554:                assert (sc > 0 && sc <= 255);
2555:                for (int h = 0;; h++) {
2556:                    if (sc < shortCodeHeader_h_base(h + 1))
2557:                        return h;
2558:                }
2559:            }
2560:
2561:            static int shortCodeHeader_max_stack(int sc) {
2562:                int h = shortCodeHeader_handler_count(sc);
2563:                int lims = shortCodeLimits[h][0];
2564:                return (sc - shortCodeHeader_h_base(h)) % lims;
2565:            }
2566:
2567:            static int shortCodeHeader_max_na_locals(int sc) {
2568:                int h = shortCodeHeader_handler_count(sc);
2569:                int lims = shortCodeLimits[h][0];
2570:                return (sc - shortCodeHeader_h_base(h)) / lims;
2571:            }
2572:
2573:            private static int shortCodeHeader_h_base(int h) {
2574:                assert (h <= shortCodeLimits.length);
2575:                int sc = 1;
2576:                for (int h0 = 0; h0 < h; h0++) {
2577:                    int lims = shortCodeLimits[h0][0];
2578:                    int liml = shortCodeLimits[h0][1];
2579:                    sc += lims * liml;
2580:                }
2581:                return sc;
2582:            }
2583:
2584:            // utilities for accessing the bc_label band:
2585:            protected void putLabel(IntBand bc_label, Code c, int pc,
2586:                    int targetPC) {
2587:                bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc));
2588:            }
2589:
2590:            protected int getLabel(IntBand bc_label, Code c, int pc) {
2591:                return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc));
2592:            }
2593:
2594:            protected CPRefBand getCPRefOpBand(int bc) {
2595:                switch (Instruction.getCPRefOpTag(bc)) {
2596:                case CONSTANT_Class:
2597:                    return bc_classref;
2598:                case CONSTANT_Fieldref:
2599:                    return bc_fieldref;
2600:                case CONSTANT_Methodref:
2601:                    return bc_methodref;
2602:                case CONSTANT_InterfaceMethodref:
2603:                    return bc_imethodref;
2604:                case CONSTANT_Literal:
2605:                    switch (bc) {
2606:                    case _ildc:
2607:                    case _ildc_w:
2608:                        return bc_intref;
2609:                    case _fldc:
2610:                    case _fldc_w:
2611:                        return bc_floatref;
2612:                    case _lldc2_w:
2613:                        return bc_longref;
2614:                    case _dldc2_w:
2615:                        return bc_doubleref;
2616:                    case _aldc:
2617:                    case _aldc_w:
2618:                        return bc_stringref;
2619:                    case _cldc:
2620:                    case _cldc_w:
2621:                        return bc_classref;
2622:                    }
2623:                    break;
2624:                }
2625:                assert (false);
2626:                return null;
2627:            }
2628:
2629:            protected CPRefBand selfOpRefBand(int self_bc) {
2630:                assert (Instruction.isSelfLinkerOp(self_bc));
2631:                int idx = (self_bc - _self_linker_op);
2632:                boolean isSuper = (idx >= _self_linker_super _flag);
2633:                if (isSuper)
2634:                    idx -= _self_linker_super _flag;
2635:                boolean isAload = (idx >= _self_linker_aload_flag);
2636:                if (isAload)
2637:                    idx -= _self_linker_aload_flag;
2638:                int origBC = _first_linker_op + idx;
2639:                boolean isField = Instruction.isFieldOp(origBC);
2640:                if (!isSuper)
2641:                    return isField ? bc_this field : bc_this method;
2642:                else
2643:                    return isField ? bc_super field : bc_super method;
2644:            }
2645:
2646:            ////////////////////////////////////////////////////////////////////
2647:
2648:            static int nextSeqForDebug;
2649:            static File dumpDir;
2650:
2651:            static OutputStream getDumpStream(Band b, String ext)
2652:                    throws IOException {
2653:                return getDumpStream(b.name, b.seqForDebug, ext, b);
2654:            }
2655:
2656:            static OutputStream getDumpStream(Index ix, String ext)
2657:                    throws IOException {
2658:                if (ix.size() == 0)
2659:                    return new ByteArrayOutputStream();
2660:                int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag];
2661:                return getDumpStream(ix.debugName, seq, ext, ix);
2662:            }
2663:
2664:            static OutputStream getDumpStream(String name, int seq, String ext,
2665:                    Object b) throws IOException {
2666:                if (dumpDir == null) {
2667:                    dumpDir = File.createTempFile("BD_", "", new File("."));
2668:                    dumpDir.delete();
2669:                    if (dumpDir.mkdir())
2670:                        Utils.log.info("Dumping bands to " + dumpDir);
2671:                }
2672:                name = name.replace('(', ' ').replace(')', ' ');
2673:                name = name.replace('/', ' ');
2674:                name = name.replace('*', ' ');
2675:                name = name.trim().replace(' ', '_');
2676:                name = ((10000 + seq) + "_" + name).substring(1);
2677:                File dumpFile = new File(dumpDir, name + ext);
2678:                Utils.log.info("Dumping " + b + " to " + dumpFile);
2679:                return new BufferedOutputStream(new FileOutputStream(dumpFile));
2680:            }
2681:
2682:            // DEBUG ONLY:  Validate me at each length change.
2683:            static boolean assertCanChangeLength(Band b) {
2684:                switch (b.phase) {
2685:                case COLLECT_PHASE:
2686:                case READ_PHASE:
2687:                    return true;
2688:                }
2689:                return false;
2690:            }
2691:
2692:            // DEBUG ONLY:  Validate a phase.
2693:            static boolean assertPhase(Band b, int phaseExpected) {
2694:                if (b.phase() != phaseExpected) {
2695:                    Utils.log.warning("phase expected " + phaseExpected
2696:                            + " was " + b.phase() + " in " + b);
2697:                    return false;
2698:                }
2699:                return true;
2700:            }
2701:
2702:            // DEBUG ONLY:  Tells whether verbosity is turned on.
2703:            static int verbose() {
2704:                return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
2705:            }
2706:
2707:            // DEBUG ONLY:  Validate me at each phase change.
2708:            static boolean assertPhaseChangeOK(Band b, int p0, int p1) {
2709:                switch (p0 * 10 + p1) {
2710:                /// Writing phases:
2711:                case NO_PHASE * 10 + COLLECT_PHASE:
2712:                    // Ready to collect data from the input classes.
2713:                    assert (!b.isReader());
2714:                    assert (b.capacity() >= 0);
2715:                    assert (b.length() == 0);
2716:                    return true;
2717:                case COLLECT_PHASE * 10 + FROZEN_PHASE:
2718:                case FROZEN_PHASE * 10 + FROZEN_PHASE:
2719:                    assert (b.length() == 0);
2720:                    return true;
2721:                case COLLECT_PHASE * 10 + WRITE_PHASE:
2722:                case FROZEN_PHASE * 10 + WRITE_PHASE:
2723:                    // Data is all collected.  Ready to write bytes to disk.
2724:                    return true;
2725:                case WRITE_PHASE * 10 + DONE_PHASE:
2726:                    // Done writing to disk.  Ready to reset, in principle.
2727:                    return true;
2728:
2729:                    /// Reading phases:
2730:                case NO_PHASE * 10 + EXPECT_PHASE:
2731:                    assert (b.isReader());
2732:                    assert (b.capacity() < 0);
2733:                    return true;
2734:                case EXPECT_PHASE * 10 + READ_PHASE:
2735:                    // Ready to read values from disk.
2736:                    assert (Math.max(0, b.capacity()) >= b.valuesExpected());
2737:                    assert (b.length() <= 0);
2738:                    return true;
2739:                case READ_PHASE * 10 + DISBURSE_PHASE:
2740:                    // Ready to disburse values.
2741:                    assert (b.valuesRemainingForDebug() == b.length());
2742:                    return true;
2743:                case DISBURSE_PHASE * 10 + DONE_PHASE:
2744:                    // Done disbursing values.  Ready to reset, in principle.
2745:                    assert (assertDoneDisbursing(b));
2746:                    return true;
2747:                }
2748:                if (p0 == p1)
2749:                    Utils.log.warning("Already in phase " + p0);
2750:                else
2751:                    Utils.log.warning("Unexpected phase " + p0 + " -> " + p1);
2752:                return false;
2753:            }
2754:
2755:            static private boolean assertDoneDisbursing(Band b) {
2756:                if (b.phase != DISBURSE_PHASE) {
2757:                    Utils.log.warning("assertDoneDisbursing: still in phase "
2758:                            + b.phase + ": " + b);
2759:                    if (verbose() <= 1)
2760:                        return false; // fail now
2761:                }
2762:                int left = b.valuesRemainingForDebug();
2763:                if (left > 0) {
2764:                    Utils.log.warning("assertDoneDisbursing: " + left
2765:                            + " values left in " + b);
2766:                    if (verbose() <= 1)
2767:                        return false; // fail now
2768:                }
2769:                if (b instanceof  MultiBand) {
2770:                    MultiBand mb = (MultiBand) b;
2771:                    for (int i = 0; i < mb.bandCount; i++) {
2772:                        Band sub = mb.bands[i];
2773:                        if (sub.phase != DONE_PHASE) {
2774:                            Utils.log
2775:                                    .warning("assertDoneDisbursing: sub-band still in phase "
2776:                                            + sub.phase + ": " + sub);
2777:                            if (verbose() <= 1)
2778:                                return false; // fail now
2779:                        }
2780:                    }
2781:                }
2782:                return true;
2783:            }
2784:
2785:            static private void printCDecl(Band b) {
2786:                if (b instanceof  MultiBand) {
2787:                    MultiBand mb = (MultiBand) b;
2788:                    for (int i = 0; i < mb.bandCount; i++) {
2789:                        printCDecl(mb.bands[i]);
2790:                    }
2791:                    return;
2792:                }
2793:                String ixS = "NULL";
2794:                if (b instanceof  CPRefBand) {
2795:                    Index ix = ((CPRefBand) b).index;
2796:                    if (ix != null)
2797:                        ixS = "INDEX(" + ix.debugName + ")";
2798:                }
2799:                Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5,
2800:                        UDELTA5, SIGNED5, DELTA5, MDELTA5 };
2801:                String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5",
2802:                        "UNSIGNED5", "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
2803:                Coding rc = b.regularCoding;
2804:                int rci = Arrays.asList(knownc).indexOf(rc);
2805:                String cstr;
2806:                if (rci >= 0)
2807:                    cstr = knowns[rci];
2808:                else
2809:                    cstr = "CODING" + rc.keyString();
2810:                System.out.println("  BAND_INIT(\"" + b.name() + "\"" + ", "
2811:                        + cstr + ", " + ixS + "),");
2812:            }
2813:
2814:            private HashMap prevForAssertMap;
2815:
2816:            // DEBUG ONLY:  Record something about the band order.
2817:            boolean notePrevForAssert(Band b, Band p) {
2818:                if (prevForAssertMap == null)
2819:                    prevForAssertMap = new HashMap();
2820:                prevForAssertMap.put(b, p);
2821:                return true;
2822:            }
2823:
2824:            // DEBUG ONLY:  Validate next input band.
2825:            private boolean assertReadyToReadFrom(Band b, InputStream in)
2826:                    throws IOException {
2827:                Band p = (Band) prevForAssertMap.get(b);
2828:                // Any previous band must be done reading before this one starts.
2829:                if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) {
2830:                    Utils.log.warning("Previous band not done reading.");
2831:                    Utils.log.info("    Previous band: " + p);
2832:                    Utils.log.info("        Next band: " + b);
2833:                    Thread.dumpStack();
2834:                    assert (verbose > 0); // die unless verbose is true
2835:                }
2836:                String name = b.name;
2837:                if (optDebugBands && !name.startsWith("(")) {
2838:                    // Verify synchronization between reader & writer:
2839:                    StringBuffer buf = new StringBuffer();
2840:                    int ch;
2841:                    while ((ch = in.read()) > 0)
2842:                        buf.append((char) ch);
2843:                    String inName = buf.toString();
2844:                    if (!inName.equals(name)) {
2845:                        StringBuffer sb = new StringBuffer();
2846:                        sb.append("Expected " + name + " but read: ");
2847:                        inName += (char) ch;
2848:                        while (inName.length() < 10)
2849:                            inName += (char) in.read();
2850:                        for (int i = 0; i < inName.length(); i++)
2851:                            sb.append(inName.charAt(i));
2852:                        Utils.log.warning(sb.toString());
2853:                        return false;
2854:                    }
2855:                }
2856:                return true;
2857:            }
2858:
2859:            // DEBUG ONLY:  Make sure a bunch of cprefs are correct.
2860:            private boolean assertValidCPRefs(CPRefBand b) {
2861:                if (b.index == null)
2862:                    return true;
2863:                int limit = b.index.size() + 1;
2864:                for (int i = 0; i < b.length(); i++) {
2865:                    int v = b.valueAtForDebug(i);
2866:                    if (v < 0 || v >= limit) {
2867:                        Utils.log.warning("CP ref out of range " + "[" + i
2868:                                + "] = " + v + " in " + b);
2869:                        return false;
2870:                    }
2871:                }
2872:                return true;
2873:            }
2874:
2875:            // DEBUG ONLY:  Maybe write a debugging cookie to next output band.
2876:            private boolean assertReadyToWriteTo(Band b, OutputStream out)
2877:                    throws IOException {
2878:                Band p = (Band) prevForAssertMap.get(b);
2879:                // Any previous band must be done writing before this one starts.
2880:                if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) {
2881:                    Utils.log.warning("Previous band not done writing.");
2882:                    Utils.log.info("    Previous band: " + p);
2883:                    Utils.log.info("        Next band: " + b);
2884:                    Thread.dumpStack();
2885:                    assert (verbose > 0); // die unless verbose is true
2886:                }
2887:                String name = b.name;
2888:                if (optDebugBands && !name.startsWith("(")) {
2889:                    // Verify synchronization between reader & writer:
2890:                    for (int j = 0; j < name.length(); j++) {
2891:                        out.write((byte) name.charAt(j));
2892:                    }
2893:                    out.write((byte) 0);
2894:                }
2895:                return true;
2896:            }
2897:
2898:            protected static boolean testBit(int flags, int bitMask) {
2899:                return (flags & bitMask) != 0;
2900:            }
2901:
2902:            protected static int setBit(int flags, int bitMask, boolean z) {
2903:                return z ? (flags | bitMask) : (flags & ~bitMask);
2904:            }
2905:
2906:            protected static boolean testBit(long flags, long bitMask) {
2907:                return (flags & bitMask) != 0;
2908:            }
2909:
2910:            protected static long setBit(long flags, long bitMask, boolean z) {
2911:                return z ? (flags | bitMask) : (flags & ~bitMask);
2912:            }
2913:
2914:            static void printArrayTo(PrintStream ps, int[] values, int start,
2915:                    int end) {
2916:                int len = end - start;
2917:                for (int i = 0; i < len; i++) {
2918:                    if (i % 10 == 0)
2919:                        ps.println();
2920:                    else
2921:                        ps.print(" ");
2922:                    ps.print(values[start + i]);
2923:                }
2924:                ps.println();
2925:            }
2926:
2927:            static void printArrayTo(PrintStream ps, Entry[] cpMap, int start,
2928:                    int end) {
2929:                StringBuffer buf = new StringBuffer();
2930:                int len = end - start;
2931:                for (int i = 0; i < len; i++) {
2932:                    String s = cpMap[start + i].stringValue();
2933:                    buf.setLength(0);
2934:                    for (int j = 0; j < s.length(); j++) {
2935:                        char ch = s.charAt(j);
2936:                        if (!(ch < ' ' || ch > '~' || ch == '\\')) {
2937:                            buf.append(ch);
2938:                        } else if (ch == '\n') {
2939:                            buf.append("\\n");
2940:                        } else if (ch == '\t') {
2941:                            buf.append("\\t");
2942:                        } else if (ch == '\r') {
2943:                            buf.append("\\r");
2944:                        } else {
2945:                            buf.append("\\x" + Integer.toHexString(ch));
2946:                        }
2947:                    }
2948:                    ps.println(buf);
2949:                }
2950:            }
2951:
2952:            // Utilities for reallocating:
2953:            protected static Object[] realloc(Object[] a, int len) {
2954:                java.lang.Class elt = a.getClass().getComponentType();
2955:                Object[] na = (Object[]) java.lang.reflect.Array.newInstance(
2956:                        elt, len);
2957:                System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2958:                return na;
2959:            }
2960:
2961:            protected static Object[] realloc(Object[] a) {
2962:                return realloc(a, Math.max(10, a.length * 2));
2963:            }
2964:
2965:            static private int[] noInts = {};
2966:
2967:            protected static int[] realloc(int[] a, int len) {
2968:                if (len == 0)
2969:                    return noInts;
2970:                if (a == null)
2971:                    return new int[len];
2972:                int[] na = new int[len];
2973:                System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2974:                return na;
2975:            }
2976:
2977:            protected static int[] realloc(int[] a) {
2978:                return realloc(a, Math.max(10, a.length * 2));
2979:            }
2980:
2981:            static private byte[] noBytes = {};
2982:
2983:            protected static byte[] realloc(byte[] a, int len) {
2984:                if (len == 0)
2985:                    return noBytes;
2986:                if (a == null)
2987:                    return new byte[len];
2988:                byte[] na = new byte[len];
2989:                System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
2990:                return na;
2991:            }
2992:
2993:            protected static byte[] realloc(byte[] a) {
2994:                return realloc(a, Math.max(10, a.length * 2));
2995:            }
2996:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.