Source Code Cross Referenced for ConstantPool.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-2003 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:
0031:        /**
0032:         * Representation of constant pool entries and indexes.
0033:         * @author John Rose
0034:         * @version 1.25, 05/05/07
0035:         */
0036:        abstract class ConstantPool implements  Constants {
0037:            private ConstantPool() {
0038:            } // do not instantiate
0039:
0040:            static int verbose() {
0041:                return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
0042:            }
0043:
0044:            // Uniquification tables for factory methods:
0045:            private static final HashMap utf8Entries = new HashMap();
0046:            private static final HashMap classEntries = new HashMap();
0047:            private static final HashMap literalEntries = new HashMap();
0048:            private static final HashMap signatureEntries = new HashMap();
0049:            private static final HashMap descriptorEntries = new HashMap();
0050:            private static final HashMap memberEntries = new HashMap();
0051:
0052:            /** Factory for Utf8 string constants.
0053:             *  Used for well-known strings like "SourceFile", "<init>", etc.
0054:             *  Also used to back up more complex constant pool entries, like Class.
0055:             */
0056:            public static synchronized Utf8Entry getUtf8Entry(String value) {
0057:                Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
0058:                if (e == null) {
0059:                    e = new Utf8Entry(value);
0060:                    utf8Entries.put(e.stringValue(), e);
0061:                }
0062:                return e;
0063:            }
0064:
0065:            /** Factory for Class constants. */
0066:            public static synchronized ClassEntry getClassEntry(String name) {
0067:                ClassEntry e = (ClassEntry) classEntries.get(name);
0068:                if (e == null) {
0069:                    e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
0070:                    assert (name.equals(e.stringValue()));
0071:                    classEntries.put(e.stringValue(), e);
0072:                }
0073:                return e;
0074:            }
0075:
0076:            /** Factory for literal constants (String, Integer, etc.). */
0077:            public static synchronized LiteralEntry getLiteralEntry(
0078:                    Comparable value) {
0079:                LiteralEntry e = (LiteralEntry) literalEntries.get(value);
0080:                if (e == null) {
0081:                    if (value instanceof  String)
0082:                        e = new StringEntry(getUtf8Entry((String) value));
0083:                    else
0084:                        e = new NumberEntry((Number) value);
0085:                    literalEntries.put(value, e);
0086:                }
0087:                return e;
0088:            }
0089:
0090:            /** Factory for literal constants (String, Integer, etc.). */
0091:            public static synchronized StringEntry getStringEntry(String value) {
0092:                return (StringEntry) getLiteralEntry(value);
0093:            }
0094:
0095:            /** Factory for signature (type) constants. */
0096:            public static synchronized SignatureEntry getSignatureEntry(
0097:                    String type) {
0098:                SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
0099:                if (e == null) {
0100:                    e = new SignatureEntry(type);
0101:                    assert (e.stringValue().equals(type));
0102:                    signatureEntries.put(type, e);
0103:                }
0104:                return e;
0105:            }
0106:
0107:            // Convenience overloading.
0108:            public static SignatureEntry getSignatureEntry(Utf8Entry formRef,
0109:                    ClassEntry[] classRefs) {
0110:                return getSignatureEntry(SignatureEntry.stringValueOf(formRef,
0111:                        classRefs));
0112:            }
0113:
0114:            /** Factory for descriptor (name-and-type) constants. */
0115:            public static synchronized DescriptorEntry getDescriptorEntry(
0116:                    Utf8Entry nameRef, SignatureEntry typeRef) {
0117:                String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
0118:                DescriptorEntry e = (DescriptorEntry) descriptorEntries
0119:                        .get(key);
0120:                if (e == null) {
0121:                    e = new DescriptorEntry(nameRef, typeRef);
0122:                    assert (e.stringValue().equals(key)) : (e.stringValue()
0123:                            + " != " + (key));
0124:                    descriptorEntries.put(key, e);
0125:                }
0126:                return e;
0127:            }
0128:
0129:            // Convenience overloading.
0130:            public static DescriptorEntry getDescriptorEntry(Utf8Entry nameRef,
0131:                    Utf8Entry typeRef) {
0132:                return getDescriptorEntry(nameRef, getSignatureEntry(typeRef
0133:                        .stringValue()));
0134:            }
0135:
0136:            /** Factory for member reference constants. */
0137:            public static synchronized MemberEntry getMemberEntry(byte tag,
0138:                    ClassEntry classRef, DescriptorEntry descRef) {
0139:                String key = MemberEntry.stringValueOf(tag, classRef, descRef);
0140:                MemberEntry e = (MemberEntry) memberEntries.get(key);
0141:                if (e == null) {
0142:                    e = new MemberEntry(tag, classRef, descRef);
0143:                    assert (e.stringValue().equals(key)) : (e.stringValue()
0144:                            + " != " + (key));
0145:                    memberEntries.put(key, e);
0146:                }
0147:                return e;
0148:            }
0149:
0150:            /** Entries in the constant pool. */
0151:            public static abstract class Entry implements  Comparable {
0152:                protected final byte tag; // a CONSTANT_foo code
0153:                protected int valueHash; // cached hashCode
0154:
0155:                protected Entry(byte tag) {
0156:                    this .tag = tag;
0157:                }
0158:
0159:                public final byte getTag() {
0160:                    return tag;
0161:                }
0162:
0163:                public Entry getRef(int i) {
0164:                    return null;
0165:                }
0166:
0167:                public boolean sameTagAs(Object o) {
0168:                    return (o instanceof  Entry) && ((Entry) o).tag == tag;
0169:                }
0170:
0171:                public boolean eq(Entry that) { // same reference
0172:                    assert (that != null);
0173:                    return this  == that || this .equals(that);
0174:                }
0175:
0176:                // Equality of Entries is value-based.
0177:                public abstract boolean equals(Object o);
0178:
0179:                public final int hashCode() {
0180:                    if (valueHash == 0) {
0181:                        valueHash = computeValueHash();
0182:                        if (valueHash == 0)
0183:                            valueHash = 1;
0184:                    }
0185:                    return valueHash;
0186:                }
0187:
0188:                protected abstract int computeValueHash();
0189:
0190:                public abstract int compareTo(Object o);
0191:
0192:                protected int super CompareTo(Object o) {
0193:                    Entry that = (Entry) o;
0194:
0195:                    if (this .tag != that.tag) {
0196:                        return TAG_ORDER[this .tag] - TAG_ORDER[that.tag];
0197:                    }
0198:
0199:                    return 0; // subclasses must refine this
0200:                }
0201:
0202:                public final boolean isDoubleWord() {
0203:                    return tag == CONSTANT_Double || tag == CONSTANT_Long;
0204:                }
0205:
0206:                public final boolean tagMatches(int tag) {
0207:                    return (this .tag == tag);
0208:                }
0209:
0210:                public String toString() {
0211:                    String valuePrint = stringValue();
0212:                    if (verbose() > 4) {
0213:                        if (valueHash != 0)
0214:                            valuePrint += " hash=" + valueHash;
0215:                        valuePrint += " id=" + System.identityHashCode(this );
0216:                    }
0217:                    return tagName(tag) + "=" + valuePrint;
0218:                }
0219:
0220:                public abstract String stringValue();
0221:            }
0222:
0223:            public static class Utf8Entry extends Entry {
0224:                final String value;
0225:
0226:                Utf8Entry(String value) {
0227:                    super (CONSTANT_Utf8);
0228:                    this .value = value.intern();
0229:                    hashCode(); // force computation of valueHash
0230:                }
0231:
0232:                protected int computeValueHash() {
0233:                    return value.hashCode();
0234:                }
0235:
0236:                public boolean equals(Object o) {
0237:                    if (!sameTagAs(o))
0238:                        return false;
0239:                    // Use reference equality of interned strings:
0240:                    return ((Utf8Entry) o).value == value;
0241:                }
0242:
0243:                public int compareTo(Object o) {
0244:                    int x = super CompareTo(o);
0245:                    if (x == 0) {
0246:                        x = value.compareTo(((Utf8Entry) o).value);
0247:                    }
0248:                    return x;
0249:                }
0250:
0251:                public String stringValue() {
0252:                    return value;
0253:                }
0254:            }
0255:
0256:            static boolean isMemberTag(byte tag) {
0257:                switch (tag) {
0258:                case CONSTANT_Fieldref:
0259:                case CONSTANT_Methodref:
0260:                case CONSTANT_InterfaceMethodref:
0261:                    return true;
0262:                }
0263:                return false;
0264:            }
0265:
0266:            static byte numberTagOf(Number value) {
0267:                if (value instanceof  Integer)
0268:                    return CONSTANT_Integer;
0269:                if (value instanceof  Float)
0270:                    return CONSTANT_Float;
0271:                if (value instanceof  Long)
0272:                    return CONSTANT_Long;
0273:                if (value instanceof  Double)
0274:                    return CONSTANT_Double;
0275:                throw new RuntimeException("bad literal value " + value);
0276:            }
0277:
0278:            public static abstract class LiteralEntry extends Entry {
0279:                protected LiteralEntry(byte tag) {
0280:                    super (tag);
0281:                }
0282:
0283:                public abstract Comparable literalValue();
0284:            }
0285:
0286:            public static class NumberEntry extends LiteralEntry {
0287:                final Number value;
0288:
0289:                NumberEntry(Number value) {
0290:                    super (numberTagOf(value));
0291:                    this .value = value;
0292:                    hashCode(); // force computation of valueHash
0293:                }
0294:
0295:                protected int computeValueHash() {
0296:                    return value.hashCode();
0297:                }
0298:
0299:                public boolean equals(Object o) {
0300:                    if (!sameTagAs(o))
0301:                        return false;
0302:                    return (((NumberEntry) o).value).equals(value);
0303:                }
0304:
0305:                public int compareTo(Object o) {
0306:                    int x = super CompareTo(o);
0307:                    if (x == 0) {
0308:                        x = ((Comparable) value)
0309:                                .compareTo(((NumberEntry) o).value);
0310:                    }
0311:                    return x;
0312:                }
0313:
0314:                public Number numberValue() {
0315:                    return value;
0316:                }
0317:
0318:                public Comparable literalValue() {
0319:                    return (Comparable) value;
0320:                }
0321:
0322:                public String stringValue() {
0323:                    return value.toString();
0324:                }
0325:            }
0326:
0327:            public static class StringEntry extends LiteralEntry {
0328:                final Utf8Entry ref;
0329:
0330:                public Entry getRef(int i) {
0331:                    return i == 0 ? ref : null;
0332:                }
0333:
0334:                StringEntry(Entry ref) {
0335:                    super (CONSTANT_String);
0336:                    this .ref = (Utf8Entry) ref;
0337:                    hashCode(); // force computation of valueHash
0338:                }
0339:
0340:                protected int computeValueHash() {
0341:                    return ref.hashCode() + tag;
0342:                }
0343:
0344:                public boolean equals(Object o) {
0345:                    if (!sameTagAs(o))
0346:                        return false;
0347:                    return ((StringEntry) o).ref.eq(ref);
0348:                }
0349:
0350:                public int compareTo(Object o) {
0351:                    int x = super CompareTo(o);
0352:                    if (x == 0) {
0353:                        x = ref.compareTo(((StringEntry) o).ref);
0354:                    }
0355:                    return x;
0356:                }
0357:
0358:                public Comparable literalValue() {
0359:                    return ref.stringValue();
0360:                }
0361:
0362:                public String stringValue() {
0363:                    return ref.stringValue();
0364:                }
0365:            }
0366:
0367:            public static class ClassEntry extends Entry {
0368:                final Utf8Entry ref;
0369:
0370:                public Entry getRef(int i) {
0371:                    return i == 0 ? ref : null;
0372:                }
0373:
0374:                protected int computeValueHash() {
0375:                    return ref.hashCode() + tag;
0376:                }
0377:
0378:                ClassEntry(Entry ref) {
0379:                    super (CONSTANT_Class);
0380:                    this .ref = (Utf8Entry) ref;
0381:                    hashCode(); // force computation of valueHash
0382:                }
0383:
0384:                public boolean equals(Object o) {
0385:                    if (!sameTagAs(o))
0386:                        return false;
0387:                    return ((ClassEntry) o).ref.eq(ref);
0388:                }
0389:
0390:                public int compareTo(Object o) {
0391:                    int x = super CompareTo(o);
0392:                    if (x == 0) {
0393:                        x = ref.compareTo(((ClassEntry) o).ref);
0394:                    }
0395:                    return x;
0396:                }
0397:
0398:                public String stringValue() {
0399:                    return ref.stringValue();
0400:                }
0401:            }
0402:
0403:            public static class DescriptorEntry extends Entry {
0404:                final Utf8Entry nameRef;
0405:                final SignatureEntry typeRef;
0406:
0407:                public Entry getRef(int i) {
0408:                    if (i == 0)
0409:                        return nameRef;
0410:                    if (i == 1)
0411:                        return typeRef;
0412:                    return null;
0413:                }
0414:
0415:                DescriptorEntry(Entry nameRef, Entry typeRef) {
0416:                    super (CONSTANT_NameandType);
0417:                    if (typeRef instanceof  Utf8Entry) {
0418:                        typeRef = getSignatureEntry(typeRef.stringValue());
0419:                    }
0420:                    this .nameRef = (Utf8Entry) nameRef;
0421:                    this .typeRef = (SignatureEntry) typeRef;
0422:                    hashCode(); // force computation of valueHash
0423:                }
0424:
0425:                protected int computeValueHash() {
0426:                    int hc2 = typeRef.hashCode();
0427:                    return (nameRef.hashCode() + (hc2 << 8)) ^ hc2;
0428:                }
0429:
0430:                public boolean equals(Object o) {
0431:                    if (!sameTagAs(o))
0432:                        return false;
0433:                    DescriptorEntry that = (DescriptorEntry) o;
0434:                    return this .nameRef.eq(that.nameRef)
0435:                            && this .typeRef.eq(that.typeRef);
0436:                }
0437:
0438:                public int compareTo(Object o) {
0439:                    int x = super CompareTo(o);
0440:                    if (x == 0) {
0441:                        DescriptorEntry that = (DescriptorEntry) o;
0442:                        // Primary key is typeRef, not nameRef.
0443:                        x = this .typeRef.compareTo(that.typeRef);
0444:                        if (x == 0)
0445:                            x = this .nameRef.compareTo(that.nameRef);
0446:                    }
0447:                    return x;
0448:                }
0449:
0450:                public String stringValue() {
0451:                    return stringValueOf(nameRef, typeRef);
0452:                }
0453:
0454:                static String stringValueOf(Entry nameRef, Entry typeRef) {
0455:                    return typeRef.stringValue() + "," + nameRef.stringValue();
0456:                }
0457:
0458:                public String prettyString() {
0459:                    return nameRef.stringValue() + typeRef.prettyString();
0460:                }
0461:
0462:                public boolean isMethod() {
0463:                    return typeRef.isMethod();
0464:                }
0465:
0466:                public byte getLiteralTag() {
0467:                    return typeRef.getLiteralTag();
0468:                }
0469:            }
0470:
0471:            public static class MemberEntry extends Entry {
0472:                final ClassEntry classRef;
0473:                final DescriptorEntry descRef;
0474:
0475:                public Entry getRef(int i) {
0476:                    if (i == 0)
0477:                        return classRef;
0478:                    if (i == 1)
0479:                        return descRef;
0480:                    return null;
0481:                }
0482:
0483:                protected int computeValueHash() {
0484:                    int hc2 = descRef.hashCode();
0485:                    return (classRef.hashCode() + (hc2 << 8)) ^ hc2;
0486:                }
0487:
0488:                MemberEntry(byte tag, ClassEntry classRef,
0489:                        DescriptorEntry descRef) {
0490:                    super (tag);
0491:                    assert (isMemberTag(tag));
0492:                    this .classRef = classRef;
0493:                    this .descRef = descRef;
0494:                    hashCode(); // force computation of valueHash
0495:                }
0496:
0497:                public boolean equals(Object o) {
0498:                    if (!sameTagAs(o))
0499:                        return false;
0500:                    MemberEntry that = (MemberEntry) o;
0501:                    return this .classRef.eq(that.classRef)
0502:                            && this .descRef.eq(that.descRef);
0503:                }
0504:
0505:                public int compareTo(Object o) {
0506:                    int x = super CompareTo(o);
0507:                    if (x == 0) {
0508:                        MemberEntry that = (MemberEntry) o;
0509:                        // Primary key is classRef.
0510:                        x = this .classRef.compareTo(that.classRef);
0511:                        if (x == 0)
0512:                            x = this .descRef.compareTo(that.descRef);
0513:                    }
0514:                    return x;
0515:                }
0516:
0517:                public String stringValue() {
0518:                    return stringValueOf(tag, classRef, descRef);
0519:                }
0520:
0521:                static String stringValueOf(byte tag, ClassEntry classRef,
0522:                        DescriptorEntry descRef) {
0523:                    assert (isMemberTag(tag));
0524:                    String pfx;
0525:                    switch (tag) {
0526:                    case CONSTANT_Fieldref:
0527:                        pfx = "Field:";
0528:                        break;
0529:                    case CONSTANT_Methodref:
0530:                        pfx = "Method:";
0531:                        break;
0532:                    case CONSTANT_InterfaceMethodref:
0533:                        pfx = "IMethod:";
0534:                        break;
0535:                    default:
0536:                        pfx = tag + "???";
0537:                        break;
0538:                    }
0539:                    return pfx + classRef.stringValue() + ","
0540:                            + descRef.stringValue();
0541:                }
0542:
0543:                public boolean isMethod() {
0544:                    return descRef.isMethod();
0545:                }
0546:            }
0547:
0548:            public static class SignatureEntry extends Entry {
0549:                final Utf8Entry formRef;
0550:                final ClassEntry[] classRefs;
0551:                String value;
0552:                Utf8Entry asUtf8Entry;
0553:
0554:                public Entry getRef(int i) {
0555:                    if (i == 0)
0556:                        return formRef;
0557:                    return i - 1 < classRefs.length ? classRefs[i - 1] : null;
0558:                }
0559:
0560:                SignatureEntry(String value) {
0561:                    super (CONSTANT_Signature);
0562:                    value = value.intern(); // always do this
0563:                    this .value = value;
0564:                    String[] parts = structureSignature(value);
0565:                    formRef = getUtf8Entry(parts[0]);
0566:                    classRefs = new ClassEntry[parts.length - 1];
0567:                    for (int i = 1; i < parts.length; i++)
0568:                        classRefs[i - 1] = getClassEntry(parts[i]);
0569:                    hashCode(); // force computation of valueHash
0570:                }
0571:
0572:                protected int computeValueHash() {
0573:                    stringValue(); // force computation of value
0574:                    return value.hashCode() + tag;
0575:                }
0576:
0577:                public Utf8Entry asUtf8Entry() {
0578:                    if (asUtf8Entry == null) {
0579:                        asUtf8Entry = getUtf8Entry(stringValue());
0580:                    }
0581:                    return asUtf8Entry;
0582:                }
0583:
0584:                public boolean equals(Object o) {
0585:                    if (!sameTagAs(o))
0586:                        return false;
0587:                    return ((SignatureEntry) o).value == value;
0588:                }
0589:
0590:                public int compareTo(Object o) {
0591:                    int x = super CompareTo(o);
0592:                    if (x == 0) {
0593:                        SignatureEntry that = (SignatureEntry) o;
0594:                        x = compareSignatures(this .value, that.value);
0595:                    }
0596:                    return x;
0597:                }
0598:
0599:                public String stringValue() {
0600:                    if (value == null) {
0601:                        value = stringValueOf(formRef, classRefs);
0602:                    }
0603:                    return value;
0604:                }
0605:
0606:                static String stringValueOf(Utf8Entry formRef,
0607:                        ClassEntry[] classRefs) {
0608:                    String[] parts = new String[1 + classRefs.length];
0609:                    parts[0] = formRef.stringValue();
0610:                    for (int i = 1; i < parts.length; i++)
0611:                        parts[i] = classRefs[i - 1].stringValue();
0612:                    return flattenSignature(parts).intern();
0613:                }
0614:
0615:                public int computeSize(boolean countDoublesTwice) {
0616:                    String form = formRef.stringValue();
0617:                    int min = 0;
0618:                    int max = 1;
0619:                    if (isMethod()) {
0620:                        min = 1;
0621:                        max = form.indexOf(')');
0622:                    }
0623:                    int size = 0;
0624:                    for (int i = min; i < max; i++) {
0625:                        switch (form.charAt(i)) {
0626:                        case 'D':
0627:                        case 'J':
0628:                            if (countDoublesTwice)
0629:                                size++;
0630:                            break;
0631:                        case '[':
0632:                            // Skip rest of array info.
0633:                            while (form.charAt(i) == '[')
0634:                                ++i;
0635:                            break;
0636:                        case ';':
0637:                            continue;
0638:                        default:
0639:                            assert (0 <= JAVA_SIGNATURE_CHARS.indexOf(form
0640:                                    .charAt(i)));
0641:                            break;
0642:                        }
0643:                        size++;
0644:                    }
0645:                    return size;
0646:                }
0647:
0648:                public boolean isMethod() {
0649:                    return formRef.stringValue().charAt(0) == '(';
0650:                }
0651:
0652:                public byte getLiteralTag() {
0653:                    switch (formRef.stringValue().charAt(0)) {
0654:                    case 'L':
0655:                        return CONSTANT_String;
0656:                    case 'I':
0657:                        return CONSTANT_Integer;
0658:                    case 'J':
0659:                        return CONSTANT_Long;
0660:                    case 'F':
0661:                        return CONSTANT_Float;
0662:                    case 'D':
0663:                        return CONSTANT_Double;
0664:                    case 'B':
0665:                    case 'S':
0666:                    case 'C':
0667:                    case 'Z':
0668:                        return CONSTANT_Integer;
0669:                    }
0670:                    assert (false);
0671:                    return CONSTANT_None;
0672:                }
0673:
0674:                public String prettyString() {
0675:                    String s;
0676:                    if (isMethod()) {
0677:                        s = formRef.stringValue();
0678:                        s = s.substring(0, 1 + s.indexOf(')'));
0679:                    } else {
0680:                        s = "/" + formRef.stringValue();
0681:                    }
0682:                    int i;
0683:                    while ((i = s.indexOf(';')) >= 0)
0684:                        s = s.substring(0, i) + s.substring(i + 1);
0685:                    return s;
0686:                }
0687:            }
0688:
0689:            static int compareSignatures(String s1, String s2) {
0690:                return compareSignatures(s1, s2, null, null);
0691:            }
0692:
0693:            static int compareSignatures(String s1, String s2, String[] p1,
0694:                    String[] p2) {
0695:                final int S1_COMES_FIRST = -1;
0696:                final int S2_COMES_FIRST = +1;
0697:                char c1 = s1.charAt(0);
0698:                char c2 = s2.charAt(0);
0699:                // fields before methods (because there are fewer of them)
0700:                if (c1 != '(' && c2 == '(')
0701:                    return S1_COMES_FIRST;
0702:                if (c2 != '(' && c1 == '(')
0703:                    return S2_COMES_FIRST;
0704:                if (p1 == null)
0705:                    p1 = structureSignature(s1);
0706:                if (p2 == null)
0707:                    p2 = structureSignature(s2);
0708:                /*
0709:                 // non-classes before classes (because there are fewer of them)
0710:                 if (p1.length == 1 && p2.length > 1)  return S1_COMES_FIRST;
0711:                 if (p2.length == 1 && p1.length > 1)  return S2_COMES_FIRST;
0712:                 // all else being equal, use the same comparison as for Utf8 strings
0713:                 return s1.compareTo(s2);
0714:                 */
0715:                if (p1.length != p2.length)
0716:                    return p1.length - p2.length;
0717:                int length = p1.length;
0718:                for (int i = length; --i >= 0;) {
0719:                    int res = p1[i].compareTo(p2[i]);
0720:                    if (res != 0)
0721:                        return res;
0722:                }
0723:                assert (s1.equals(s2));
0724:                return 0;
0725:            }
0726:
0727:            static int countClassParts(Utf8Entry formRef) {
0728:                int num = 0;
0729:                String s = formRef.stringValue();
0730:                for (int i = 0; i < s.length(); i++) {
0731:                    if (s.charAt(i) == 'L')
0732:                        ++num;
0733:                }
0734:                return num;
0735:            }
0736:
0737:            static String flattenSignature(String[] parts) {
0738:                String form = parts[0];
0739:                if (parts.length == 1)
0740:                    return form;
0741:                int len = form.length();
0742:                for (int i = 1; i < parts.length; i++) {
0743:                    len += parts[i].length();
0744:                }
0745:                char[] sig = new char[len];
0746:                int j = 0;
0747:                int k = 1;
0748:                for (int i = 0; i < form.length(); i++) {
0749:                    char ch = form.charAt(i);
0750:                    sig[j++] = ch;
0751:                    if (ch == 'L') {
0752:                        String cls = parts[k++];
0753:                        cls.getChars(0, cls.length(), sig, j);
0754:                        j += cls.length();
0755:                        //sig[j++] = ';';
0756:                    }
0757:                }
0758:                assert (j == len);
0759:                assert (k == parts.length);
0760:                return new String(sig);
0761:            }
0762:
0763:            static private int skipClassNameChars(String sig, int i) {
0764:                int len = sig.length();
0765:                for (; i < len; i++) {
0766:                    char ch = sig.charAt(i);
0767:                    if (ch <= ' ')
0768:                        break;
0769:                    if (ch >= ';' && ch <= '@')
0770:                        break;
0771:                }
0772:                return i;
0773:            }
0774:
0775:            static String[] structureSignature(String sig) {
0776:                sig = sig.intern();
0777:
0778:                int formLen = 0;
0779:                int nparts = 1;
0780:                for (int i = 0; i < sig.length(); i++) {
0781:                    char ch = sig.charAt(i);
0782:                    formLen++;
0783:                    if (ch == 'L') {
0784:                        nparts++;
0785:                        int i2 = skipClassNameChars(sig, i + 1);
0786:                        i = i2 - 1; // keep the semicolon in the form
0787:                        int i3 = sig.indexOf('<', i + 1);
0788:                        if (i3 > 0 && i3 < i2)
0789:                            i = i3 - 1;
0790:                    }
0791:                }
0792:                char[] form = new char[formLen];
0793:                if (nparts == 1) {
0794:                    String[] parts = { sig };
0795:                    return parts;
0796:                }
0797:                String[] parts = new String[nparts];
0798:                int j = 0;
0799:                int k = 1;
0800:                for (int i = 0; i < sig.length(); i++) {
0801:                    char ch = sig.charAt(i);
0802:                    form[j++] = ch;
0803:                    if (ch == 'L') {
0804:                        int i2 = skipClassNameChars(sig, i + 1);
0805:                        parts[k++] = sig.substring(i + 1, i2);
0806:                        i = i2;
0807:                        --i; // keep the semicolon in the form
0808:                    }
0809:                }
0810:                assert (j == formLen);
0811:                assert (k == parts.length);
0812:                parts[0] = new String(form);
0813:                //assert(flattenSignature(parts).equals(sig));
0814:                return parts;
0815:            }
0816:
0817:            // Handy constants:
0818:            protected static final Entry[] noRefs = {};
0819:            protected static final ClassEntry[] noClassRefs = {};
0820:
0821:            /** An Index is a mapping between CP entries and small integers. */
0822:            public static class Index extends AbstractList {
0823:                protected String debugName;
0824:                protected Entry[] cpMap;
0825:                protected boolean flattenSigs;
0826:
0827:                protected Entry[] getMap() {
0828:                    return cpMap;
0829:                }
0830:
0831:                protected Index(String debugName) {
0832:                    this .debugName = debugName;
0833:                }
0834:
0835:                protected Index(String debugName, Entry[] cpMap) {
0836:                    this (debugName);
0837:                    setMap(cpMap);
0838:                }
0839:
0840:                protected void setMap(Entry[] cpMap) {
0841:                    clearIndex();
0842:                    this .cpMap = cpMap;
0843:                }
0844:
0845:                protected Index(String debugName, Collection cpMapList) {
0846:                    this (debugName);
0847:                    setMap(cpMapList);
0848:                }
0849:
0850:                protected void setMap(Collection cpMapList) {
0851:                    cpMap = new Entry[cpMapList.size()];
0852:                    cpMapList.toArray(cpMap);
0853:                    setMap(cpMap);
0854:                }
0855:
0856:                public int size() {
0857:                    return cpMap.length;
0858:                }
0859:
0860:                public Object get(int i) {
0861:                    return cpMap[i];
0862:                }
0863:
0864:                public Entry getEntry(int i) {
0865:                    // same as get(), with covariant return type
0866:                    return cpMap[i];
0867:                }
0868:
0869:                // Find index of e in cpMap, or return -1 if none.
0870:                //
0871:                // As a special hack, if flattenSigs, signatures are
0872:                // treated as equivalent entries of cpMap.  This is wrong
0873:                // fron a Collection point of view, because contains()
0874:                // reports true for signatures, but the iterator()
0875:                // never produces them!
0876:                private int findIndexOf(Entry e) {
0877:                    if (indexKey == null)
0878:                        initializeIndex();
0879:                    int probe = findIndexLocation(e);
0880:                    if (indexKey[probe] != e) {
0881:                        if (flattenSigs && e.tag == CONSTANT_Signature) {
0882:                            SignatureEntry se = (SignatureEntry) e;
0883:                            return findIndexOf(se.asUtf8Entry());
0884:                        }
0885:                        return -1;
0886:                    }
0887:                    int index = indexValue[probe];
0888:                    assert (e.equals(cpMap[index]));
0889:                    return index;
0890:                }
0891:
0892:                public boolean contains(Entry e) {
0893:                    return findIndexOf(e) >= 0;
0894:                }
0895:
0896:                // Find index of e in cpMap.  Should not return -1.
0897:                public int indexOf(Entry e) {
0898:                    int index = findIndexOf(e);
0899:                    if (index < 0 && verbose() > 0) {
0900:                        System.out.println("not found: " + e);
0901:                        System.out.println("       in: " + this .dumpString());
0902:                        Thread.dumpStack();
0903:                    }
0904:                    assert (index >= 0);
0905:                    return index;
0906:                }
0907:
0908:                public boolean contains(Object e) {
0909:                    return findIndexOf((Entry) e) >= 0;
0910:                }
0911:
0912:                public int indexOf(Object e) {
0913:                    return findIndexOf((Entry) e);
0914:                }
0915:
0916:                public int lastIndexOf(Object e) {
0917:                    return indexOf(e);
0918:                }
0919:
0920:                public boolean assertIsSorted() {
0921:                    for (int i = 1; i < cpMap.length; i++) {
0922:                        if (cpMap[i - 1].compareTo(cpMap[i]) > 0) {
0923:                            System.out.println("Not sorted at " + (i - 1) + "/"
0924:                                    + i + ": " + this .dumpString());
0925:                            return false;
0926:                        }
0927:                    }
0928:                    return true;
0929:                }
0930:
0931:                // internal hash table
0932:                protected Entry[] indexKey;
0933:                protected int[] indexValue;
0934:
0935:                protected void clearIndex() {
0936:                    indexKey = null;
0937:                    indexValue = null;
0938:                }
0939:
0940:                private int findIndexLocation(Entry e) {
0941:                    int size = indexKey.length;
0942:                    int hash = e.hashCode();
0943:                    int probe = hash & (size - 1);
0944:                    int stride = ((hash >>> 8) | 1) & (size - 1);
0945:                    for (;;) {
0946:                        Entry e1 = indexKey[probe];
0947:                        if (e1 == e || e1 == null)
0948:                            return probe;
0949:                        probe += stride;
0950:                        if (probe >= size)
0951:                            probe -= size;
0952:                    }
0953:                }
0954:
0955:                private void initializeIndex() {
0956:                    if (verbose() > 2)
0957:                        System.out.println("initialize Index " + debugName
0958:                                + " [" + size() + "]");
0959:                    int hsize0 = (int) ((cpMap.length + 10) * 1.5);
0960:                    int hsize = 1;
0961:                    while (hsize < hsize0)
0962:                        hsize <<= 1;
0963:                    indexKey = new Entry[hsize];
0964:                    indexValue = new int[hsize];
0965:                    for (int i = 0; i < cpMap.length; i++) {
0966:                        Entry e = cpMap[i];
0967:                        if (e == null)
0968:                            continue;
0969:                        int probe = findIndexLocation(e);
0970:                        assert (indexKey[probe] == null); // e has unique index
0971:                        indexKey[probe] = e;
0972:                        indexValue[probe] = i;
0973:                    }
0974:                }
0975:
0976:                public Object[] toArray(Object[] a) {
0977:                    int sz = size();
0978:                    if (a.length < sz)
0979:                        return super .toArray(a);
0980:                    System.arraycopy(cpMap, 0, a, 0, sz);
0981:                    if (a.length > sz)
0982:                        a[sz] = null;
0983:                    return a;
0984:                }
0985:
0986:                public Object[] toArray() {
0987:                    return toArray(new Entry[size()]);
0988:                }
0989:
0990:                public Object clone() {
0991:                    return new Index(debugName, (Entry[]) cpMap.clone());
0992:                }
0993:
0994:                public String toString() {
0995:                    return "Index " + debugName + " [" + size() + "]";
0996:                }
0997:
0998:                public String dumpString() {
0999:                    String s = toString();
1000:                    s += " {\n";
1001:                    for (int i = 0; i < cpMap.length; i++) {
1002:                        s += "    " + i + ": " + cpMap[i] + "\n";
1003:                    }
1004:                    s += "}";
1005:                    return s;
1006:                }
1007:            }
1008:
1009:            // Index methods.
1010:
1011:            public static Index makeIndex(String debugName, Entry[] cpMap) {
1012:                return new Index(debugName, cpMap);
1013:            }
1014:
1015:            public static Index makeIndex(String debugName, Collection cpMapList) {
1016:                return new Index(debugName, cpMapList);
1017:            }
1018:
1019:            /** Sort this index (destructively) into canonical order. */
1020:            public static void sort(Index ix) {
1021:                // %%% Should move this into class Index.
1022:                ix.clearIndex();
1023:                Arrays.sort(ix.cpMap);
1024:                if (verbose() > 2)
1025:                    System.out.println("sorted " + ix.dumpString());
1026:            }
1027:
1028:            /** Return a set of indexes partitioning these entries.
1029:             *  The keys array must of length this.size(), and marks entries.
1030:             *  The result array is as long as one plus the largest key value.
1031:             *  Entries with a negative key are dropped from the partition.
1032:             */
1033:            public static Index[] partition(Index ix, int[] keys) {
1034:                // %%% Should move this into class Index.
1035:                ArrayList parts = new ArrayList();
1036:                Entry[] cpMap = ix.cpMap;
1037:                assert (keys.length == cpMap.length);
1038:                for (int i = 0; i < keys.length; i++) {
1039:                    int key = keys[i];
1040:                    if (key < 0)
1041:                        continue;
1042:                    while (key >= parts.size())
1043:                        parts.add(null);
1044:                    ArrayList part = (ArrayList) parts.get(key);
1045:                    if (part == null) {
1046:                        parts.set(key, part = new ArrayList());
1047:                    }
1048:                    part.add(cpMap[i]);
1049:                }
1050:                Index[] indexes = new Index[parts.size()];
1051:                for (int key = 0; key < indexes.length; key++) {
1052:                    ArrayList part = (ArrayList) parts.get(key);
1053:                    if (part == null)
1054:                        continue;
1055:                    indexes[key] = new Index(ix.debugName + "/part#" + key,
1056:                            part);
1057:                    assert (indexes[key].indexOf(part.get(0)) == 0);
1058:                }
1059:                return indexes;
1060:            }
1061:
1062:            public static Index[] partitionByTag(Index ix) {
1063:                // Partition by tag.
1064:                Entry[] cpMap = ix.cpMap;
1065:                int[] keys = new int[cpMap.length];
1066:                for (int i = 0; i < keys.length; i++) {
1067:                    Entry e = cpMap[i];
1068:                    keys[i] = (e == null) ? -1 : e.tag;
1069:                }
1070:                Index[] byTag = partition(ix, keys);
1071:                for (int tag = 0; tag < byTag.length; tag++) {
1072:                    if (byTag[tag] == null)
1073:                        continue;
1074:                    byTag[tag].debugName = tagName(tag);
1075:                }
1076:                if (byTag.length < CONSTANT_Limit) {
1077:                    Index[] longer = new Index[CONSTANT_Limit];
1078:                    System.arraycopy(byTag, 0, longer, 0, byTag.length);
1079:                    byTag = longer;
1080:                }
1081:                return byTag;
1082:            }
1083:
1084:            /** Coherent group of constant pool indexes. */
1085:            public static class IndexGroup {
1086:                private Index indexUntyped;
1087:                private Index[] indexByTag = new Index[CONSTANT_Limit];
1088:                private int[] untypedFirstIndexByTag;
1089:                private int totalSize;
1090:                private Index[][] indexByTagAndClass;
1091:
1092:                /** Index of all CP entries of all types, in definition order. */
1093:                public Index getUntypedIndex() {
1094:                    if (indexUntyped == null) {
1095:                        untypedIndexOf(null); // warm up untypedFirstIndexByTag
1096:                        Entry[] cpMap = new Entry[totalSize];
1097:                        for (int tag = 0; tag < indexByTag.length; tag++) {
1098:                            Index ix = indexByTag[tag];
1099:                            if (ix == null)
1100:                                continue;
1101:                            int ixLen = ix.cpMap.length;
1102:                            if (ixLen == 0)
1103:                                continue;
1104:                            int fillp = untypedFirstIndexByTag[tag];
1105:                            assert (cpMap[fillp] == null);
1106:                            assert (cpMap[fillp + ixLen - 1] == null);
1107:                            System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen);
1108:                        }
1109:                        indexUntyped = new Index("untyped", cpMap);
1110:                    }
1111:                    return indexUntyped;
1112:                }
1113:
1114:                public int untypedIndexOf(Entry e) {
1115:                    if (untypedFirstIndexByTag == null) {
1116:                        untypedFirstIndexByTag = new int[CONSTANT_Limit];
1117:                        int fillp = 0;
1118:                        for (int i = 0; i < TAGS_IN_ORDER.length; i++) {
1119:                            byte tag = TAGS_IN_ORDER[i];
1120:                            Index ix = indexByTag[tag];
1121:                            if (ix == null)
1122:                                continue;
1123:                            int ixLen = ix.cpMap.length;
1124:                            untypedFirstIndexByTag[tag] = fillp;
1125:                            fillp += ixLen;
1126:                        }
1127:                        totalSize = fillp;
1128:                    }
1129:                    if (e == null)
1130:                        return -1;
1131:                    int tag = e.tag;
1132:                    Index ix = indexByTag[tag];
1133:                    if (ix == null)
1134:                        return -1;
1135:                    int idx = ix.findIndexOf(e);
1136:                    if (idx >= 0)
1137:                        idx += untypedFirstIndexByTag[tag];
1138:                    return idx;
1139:                }
1140:
1141:                public void initIndexByTag(byte tag, Index ix) {
1142:                    assert (indexByTag[tag] == null); // do not init twice
1143:                    Entry[] cpMap = ix.cpMap;
1144:                    for (int i = 0; i < cpMap.length; i++) {
1145:                        // It must be a homogeneous Entry set.
1146:                        assert (cpMap[i].tag == tag);
1147:                    }
1148:                    if (tag == CONSTANT_Utf8) {
1149:                        // Special case:  First Utf8 must always be empty string.
1150:                        assert (cpMap.length == 0 || cpMap[0].stringValue()
1151:                                .equals(""));
1152:                    }
1153:                    indexByTag[tag] = ix;
1154:                    // decache indexes derived from this one:
1155:                    untypedFirstIndexByTag = null;
1156:                    indexUntyped = null;
1157:                    if (indexByTagAndClass != null)
1158:                        indexByTagAndClass[tag] = null;
1159:                }
1160:
1161:                /** Index of all CP entries of a given tag. */
1162:                public Index getIndexByTag(byte tag) {
1163:                    if (tag == CONSTANT_All) {
1164:                        return getUntypedIndex();
1165:                    }
1166:                    Index ix = indexByTag[tag];
1167:                    if (ix == null) {
1168:                        // Make an empty one by default.
1169:                        ix = new Index(tagName(tag), new Entry[0]);
1170:                        indexByTag[tag] = ix;
1171:                    }
1172:                    return ix;
1173:                }
1174:
1175:                /** Index of all CP entries of a given tag and class. */
1176:                public Index getMemberIndex(byte tag, ClassEntry classRef) {
1177:                    if (indexByTagAndClass == null)
1178:                        indexByTagAndClass = new Index[CONSTANT_Limit][];
1179:                    Index allClasses = getIndexByTag(CONSTANT_Class);
1180:                    Index[] perClassIndexes = indexByTagAndClass[tag];
1181:                    if (perClassIndexes == null) {
1182:                        // Create the partition now.
1183:                        // Divide up all entries of the given tag according to their class.
1184:                        Index allMembers = getIndexByTag(tag);
1185:                        int[] whichClasses = new int[allMembers.size()];
1186:                        for (int i = 0; i < whichClasses.length; i++) {
1187:                            MemberEntry e = (MemberEntry) allMembers.get(i);
1188:                            int whichClass = allClasses.indexOf(e.classRef);
1189:                            whichClasses[i] = whichClass;
1190:                        }
1191:                        perClassIndexes = partition(allMembers, whichClasses);
1192:                        for (int i = 0; i < perClassIndexes.length; i++)
1193:                            assert (perClassIndexes[i] == null || perClassIndexes[i]
1194:                                    .assertIsSorted());
1195:                        indexByTagAndClass[tag] = perClassIndexes;
1196:                    }
1197:                    int whichClass = allClasses.indexOf(classRef);
1198:                    return perClassIndexes[whichClass];
1199:                }
1200:
1201:                // Given the sequence of all methods of the given name and class,
1202:                // produce the ordinal of this particular given overloading.
1203:                public int getOverloadingIndex(MemberEntry methodRef) {
1204:                    Index ix = getMemberIndex(methodRef.tag, methodRef.classRef);
1205:                    Utf8Entry nameRef = methodRef.descRef.nameRef;
1206:                    int ord = 0;
1207:                    for (int i = 0; i < ix.cpMap.length; i++) {
1208:                        MemberEntry e = (MemberEntry) ix.cpMap[i];
1209:                        if (e.equals(methodRef))
1210:                            return ord;
1211:                        if (e.descRef.nameRef.equals(nameRef))
1212:                            // Found a different overloading.  Increment the ordinal.
1213:                            ord++;
1214:                    }
1215:                    throw new RuntimeException("should not reach here");
1216:                }
1217:
1218:                // Inverse of getOverloadingIndex
1219:                public MemberEntry getOverloadingForIndex(byte tag,
1220:                        ClassEntry classRef, String name, int which) {
1221:                    assert (name == name.intern());
1222:                    Index ix = getMemberIndex(tag, classRef);
1223:                    int ord = 0;
1224:                    for (int i = 0; i < ix.cpMap.length; i++) {
1225:                        MemberEntry e = (MemberEntry) ix.cpMap[i];
1226:                        if (e.descRef.nameRef.stringValue() == name) {
1227:                            if (ord == which)
1228:                                return e;
1229:                            ord++;
1230:                        }
1231:                    }
1232:                    throw new RuntimeException("should not reach here");
1233:                }
1234:
1235:                public boolean haveNumbers() {
1236:                    for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) {
1237:                        switch (tag) {
1238:                        case CONSTANT_Integer:
1239:                        case CONSTANT_Float:
1240:                        case CONSTANT_Long:
1241:                        case CONSTANT_Double:
1242:                            break;
1243:                        default:
1244:                            assert (false);
1245:                        }
1246:                        if (getIndexByTag(tag).size() > 0)
1247:                            return true;
1248:                    }
1249:                    return false;
1250:                }
1251:
1252:            }
1253:
1254:            /** Close the set cpRefs under the getRef(*) relation.
1255:             *  Also, if flattenSigs, replace all signatures in cpRefs
1256:             *  by their equivalent Utf8s.
1257:             *  Also, discard null from cpRefs.
1258:             */
1259:            public static void completeReferencesIn(Set cpRefs,
1260:                    boolean flattenSigs) {
1261:                cpRefs.remove(null);
1262:                for (ListIterator work = new ArrayList(cpRefs)
1263:                        .listIterator(cpRefs.size()); work.hasPrevious();) {
1264:                    Entry e = (Entry) work.previous();
1265:                    work.remove(); // pop stack
1266:                    assert (e != null);
1267:                    if (flattenSigs && e.tag == CONSTANT_Signature) {
1268:                        SignatureEntry se = (SignatureEntry) e;
1269:                        Utf8Entry ue = se.asUtf8Entry();
1270:                        // Totally replace e by se.
1271:                        cpRefs.remove(se);
1272:                        cpRefs.add(ue);
1273:                        e = ue; // do not descend into the sig
1274:                    }
1275:                    // Recursively add the refs of e to cpRefs:
1276:                    for (int i = 0;; i++) {
1277:                        Entry re = e.getRef(i);
1278:                        if (re == null)
1279:                            break; // no more refs in e
1280:                        if (cpRefs.add(re)) // output the ref
1281:                            work.add(re); // push stack, if a new ref
1282:                    }
1283:                }
1284:            }
1285:
1286:            static double percent(int num, int den) {
1287:                return (int) ((10000.0 * num) / den + 0.5) / 100.0;
1288:            }
1289:
1290:            public static String tagName(int tag) {
1291:                switch (tag) {
1292:                case CONSTANT_Utf8:
1293:                    return "Utf8";
1294:                case CONSTANT_Integer:
1295:                    return "Integer";
1296:                case CONSTANT_Float:
1297:                    return "Float";
1298:                case CONSTANT_Long:
1299:                    return "Long";
1300:                case CONSTANT_Double:
1301:                    return "Double";
1302:                case CONSTANT_Class:
1303:                    return "Class";
1304:                case CONSTANT_String:
1305:                    return "String";
1306:                case CONSTANT_Fieldref:
1307:                    return "Fieldref";
1308:                case CONSTANT_Methodref:
1309:                    return "Methodref";
1310:                case CONSTANT_InterfaceMethodref:
1311:                    return "InterfaceMethodref";
1312:                case CONSTANT_NameandType:
1313:                    return "NameandType";
1314:
1315:                    // pseudo-tags:
1316:                case CONSTANT_All:
1317:                    return "*All";
1318:                case CONSTANT_None:
1319:                    return "*None";
1320:                case CONSTANT_Signature:
1321:                    return "*Signature";
1322:                }
1323:                return "tag#" + tag;
1324:            }
1325:
1326:            // archive constant pool definition order
1327:            static final byte TAGS_IN_ORDER[] = {
1328:                    CONSTANT_Utf8,
1329:                    CONSTANT_Integer, // cp_Int
1330:                    CONSTANT_Float, CONSTANT_Long, CONSTANT_Double,
1331:                    CONSTANT_String, CONSTANT_Class, CONSTANT_Signature,
1332:                    CONSTANT_NameandType, // cp_Descr
1333:                    CONSTANT_Fieldref, // cp_Field
1334:                    CONSTANT_Methodref, // cp_Method
1335:                    CONSTANT_InterfaceMethodref // cp_Imethod
1336:            };
1337:            static final byte TAG_ORDER[];
1338:            static {
1339:                TAG_ORDER = new byte[CONSTANT_Limit];
1340:                for (int i = 0; i < TAGS_IN_ORDER.length; i++) {
1341:                    TAG_ORDER[TAGS_IN_ORDER[i]] = (byte) (i + 1);
1342:                }
1343:                /*
1344:                System.out.println("TAG_ORDER[] = {");
1345:                for (int i = 0; i < TAG_ORDER.length; i++)
1346:                    System.out.println("  "+TAG_ORDER[i]+",");
1347:                System.out.println("};");
1348:                 */
1349:            }
1350:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.