src/share/classes/com/sun/tools/classfile/ConstantPool.java

Wed, 05 Aug 2009 07:43:50 -0700

author
jjg
date
Wed, 05 Aug 2009 07:43:50 -0700
changeset 349
bc0b1f404c40
parent 345
23505e6ea22d
child 422
e526e39579ae
permissions
-rw-r--r--

6868553: 6867671 breaks some tests
Reviewed-by: mcimadamore

jjg@46 1 /*
xdono@229 2 * Copyright 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
jjg@46 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@46 4 *
jjg@46 5 * This code is free software; you can redistribute it and/or modify it
jjg@46 6 * under the terms of the GNU General Public License version 2 only, as
jjg@46 7 * published by the Free Software Foundation. Sun designates this
jjg@46 8 * particular file as subject to the "Classpath" exception as provided
jjg@46 9 * by Sun in the LICENSE file that accompanied this code.
jjg@46 10 *
jjg@46 11 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@46 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@46 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@46 14 * version 2 for more details (a copy is included in the LICENSE file that
jjg@46 15 * accompanied this code).
jjg@46 16 *
jjg@46 17 * You should have received a copy of the GNU General Public License version
jjg@46 18 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@46 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@46 20 *
jjg@46 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
jjg@46 22 * CA 95054 USA or visit www.sun.com if you need additional information or
jjg@46 23 * have any questions.
jjg@46 24 */
jjg@46 25
jjg@46 26 package com.sun.tools.classfile;
jjg@46 27
jjg@345 28 import java.io.DataOutputStream;
jjg@46 29 import java.io.IOException;
jjg@345 30 import java.io.OutputStream;
jjg@282 31 import java.util.Iterator;
jjg@46 32
jjg@46 33 /**
jjg@46 34 * See JVMS3, section 4.5.
jjg@46 35 *
jjg@46 36 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
jjg@46 37 * you write code that depends on this, you do so at your own risk.
jjg@46 38 * This code and its internal interfaces are subject to change or
jjg@46 39 * deletion without notice.</b>
jjg@46 40 */
jjg@46 41 public class ConstantPool {
jjg@46 42
jjg@46 43 public class InvalidIndex extends ConstantPoolException {
jjg@198 44 private static final long serialVersionUID = -4350294289300939730L;
jjg@46 45 InvalidIndex(int index) {
jjg@46 46 super(index);
jjg@46 47 }
jjg@46 48
jjg@46 49 @Override
jjg@46 50 public String getMessage() {
jjg@46 51 // i18n
jjg@46 52 return "invalid index #" + index;
jjg@46 53 }
jjg@46 54 }
jjg@46 55
jjg@46 56 public class UnexpectedEntry extends ConstantPoolException {
jjg@198 57 private static final long serialVersionUID = 6986335935377933211L;
jjg@46 58 UnexpectedEntry(int index, int expected_tag, int found_tag) {
jjg@46 59 super(index);
jjg@46 60 this.expected_tag = expected_tag;
jjg@46 61 this.found_tag = found_tag;
jjg@46 62 }
jjg@46 63
jjg@46 64 @Override
jjg@46 65 public String getMessage() {
jjg@46 66 // i18n?
jjg@46 67 return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
jjg@46 68 }
jjg@46 69
jjg@46 70 public final int expected_tag;
jjg@46 71 public final int found_tag;
jjg@46 72 }
jjg@46 73
jjg@46 74 public class InvalidEntry extends ConstantPoolException {
jjg@198 75 private static final long serialVersionUID = 1000087545585204447L;
jjg@46 76 InvalidEntry(int index, int tag) {
jjg@46 77 super(index);
jjg@46 78 this.tag = tag;
jjg@46 79 }
jjg@46 80
jjg@46 81 @Override
jjg@46 82 public String getMessage() {
jjg@46 83 // i18n?
jjg@46 84 return "unexpected tag at #" + index + ": " + tag;
jjg@46 85 }
jjg@46 86
jjg@46 87 public final int tag;
jjg@46 88 }
jjg@46 89
jjg@46 90 public class EntryNotFound extends ConstantPoolException {
jjg@198 91 private static final long serialVersionUID = 2885537606468581850L;
jjg@46 92 EntryNotFound(Object value) {
jjg@46 93 super(-1);
jjg@46 94 this.value = value;
jjg@46 95 }
jjg@46 96
jjg@46 97 @Override
jjg@46 98 public String getMessage() {
jjg@46 99 // i18n?
jjg@46 100 return "value not found: " + value;
jjg@46 101 }
jjg@46 102
jjg@46 103 public final Object value;
jjg@46 104 }
jjg@46 105
jjg@46 106 public static final int CONSTANT_Utf8 = 1;
jjg@46 107 public static final int CONSTANT_Integer = 3;
jjg@46 108 public static final int CONSTANT_Float = 4;
jjg@46 109 public static final int CONSTANT_Long = 5;
jjg@46 110 public static final int CONSTANT_Double = 6;
jjg@46 111 public static final int CONSTANT_Class = 7;
jjg@46 112 public static final int CONSTANT_String = 8;
jjg@46 113 public static final int CONSTANT_Fieldref = 9;
jjg@46 114 public static final int CONSTANT_Methodref = 10;
jjg@46 115 public static final int CONSTANT_InterfaceMethodref = 11;
jjg@46 116 public static final int CONSTANT_NameAndType = 12;
jjg@46 117
jjg@46 118 ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
jjg@46 119 int count = cr.readUnsignedShort();
jjg@46 120 pool = new CPInfo[count];
jjg@46 121 for (int i = 1; i < count; i++) {
jjg@46 122 int tag = cr.readUnsignedByte();
jjg@46 123 switch (tag) {
jjg@46 124 case CONSTANT_Class:
jjg@46 125 pool[i] = new CONSTANT_Class_info(this, cr);
jjg@46 126 break;
jjg@46 127
jjg@46 128 case CONSTANT_Double:
jjg@46 129 pool[i] = new CONSTANT_Double_info(cr);
jjg@46 130 i++;
jjg@46 131 break;
jjg@46 132
jjg@46 133 case CONSTANT_Fieldref:
jjg@46 134 pool[i] = new CONSTANT_Fieldref_info(this, cr);
jjg@46 135 break;
jjg@46 136
jjg@46 137 case CONSTANT_Float:
jjg@46 138 pool[i] = new CONSTANT_Float_info(cr);
jjg@46 139 break;
jjg@46 140
jjg@46 141 case CONSTANT_Integer:
jjg@46 142 pool[i] = new CONSTANT_Integer_info(cr);
jjg@46 143 break;
jjg@46 144
jjg@46 145 case CONSTANT_InterfaceMethodref:
jjg@46 146 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
jjg@46 147 break;
jjg@46 148
jjg@46 149 case CONSTANT_Long:
jjg@46 150 pool[i] = new CONSTANT_Long_info(cr);
jjg@46 151 i++;
jjg@46 152 break;
jjg@46 153
jjg@46 154 case CONSTANT_Methodref:
jjg@46 155 pool[i] = new CONSTANT_Methodref_info(this, cr);
jjg@46 156 break;
jjg@46 157
jjg@46 158 case CONSTANT_NameAndType:
jjg@46 159 pool[i] = new CONSTANT_NameAndType_info(this, cr);
jjg@46 160 break;
jjg@46 161
jjg@46 162 case CONSTANT_String:
jjg@52 163 pool[i] = new CONSTANT_String_info(this, cr);
jjg@46 164 break;
jjg@46 165
jjg@46 166 case CONSTANT_Utf8:
jjg@46 167 pool[i] = new CONSTANT_Utf8_info(cr);
jjg@46 168 break;
jjg@46 169
jjg@46 170 default:
jjg@46 171 throw new InvalidEntry(i, tag);
jjg@46 172 }
jjg@46 173 }
jjg@46 174 }
jjg@46 175
jjg@46 176 public ConstantPool(CPInfo[] pool) {
jjg@46 177 this.pool = pool;
jjg@46 178 }
jjg@46 179
jjg@46 180 public int size() {
jjg@46 181 return pool.length;
jjg@46 182 }
jjg@46 183
jjg@345 184 public int byteLength() {
jjg@345 185 int length = 2;
jjg@345 186 for (int i = 1; i < size(); ) {
jjg@345 187 CPInfo cpInfo = pool[i];
jjg@345 188 length += cpInfo.byteLength();
jjg@345 189 i += cpInfo.size();
jjg@345 190 }
jjg@345 191 return length;
jjg@345 192 }
jjg@345 193
jjg@46 194 public CPInfo get(int index) throws InvalidIndex {
jjg@46 195 if (index <= 0 || index >= pool.length)
jjg@46 196 throw new InvalidIndex(index);
jjg@46 197 CPInfo info = pool[index];
jjg@46 198 if (info == null) {
jjg@46 199 // this occurs for indices referencing the "second half" of an
jjg@46 200 // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
jjg@46 201 throw new InvalidIndex(index);
jjg@46 202 }
jjg@46 203 return pool[index];
jjg@46 204 }
jjg@46 205
jjg@46 206 private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
jjg@46 207 CPInfo info = get(index);
jjg@46 208 if (info.getTag() != expected_type)
jjg@46 209 throw new UnexpectedEntry(index, expected_type, info.getTag());
jjg@46 210 return info;
jjg@46 211 }
jjg@46 212
jjg@46 213 public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 214 return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
jjg@46 215 }
jjg@46 216
jjg@46 217 public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 218 return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
jjg@46 219 }
jjg@46 220
jjg@46 221 public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 222 return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
jjg@46 223 }
jjg@46 224
jjg@46 225 public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
jjg@46 226 return getUTF8Info(index).value;
jjg@46 227 }
jjg@46 228
jjg@46 229 public int getUTF8Index(String value) throws EntryNotFound {
jjg@46 230 for (int i = 1; i < pool.length; i++) {
jjg@46 231 CPInfo info = pool[i];
jjg@46 232 if (info instanceof CONSTANT_Utf8_info &&
jjg@46 233 ((CONSTANT_Utf8_info) info).value.equals(value))
jjg@46 234 return i;
jjg@46 235 }
jjg@46 236 throw new EntryNotFound(value);
jjg@46 237 }
jjg@46 238
jjg@282 239 public Iterable<CPInfo> entries() {
jjg@282 240 return new Iterable<CPInfo>() {
jjg@282 241 public Iterator<CPInfo> iterator() {
jjg@282 242 return new Iterator<CPInfo>() {
jjg@282 243
jjg@282 244 public boolean hasNext() {
jjg@282 245 return next < pool.length;
jjg@282 246 }
jjg@282 247
jjg@282 248 public CPInfo next() {
jjg@282 249 current = pool[next];
jjg@282 250 switch (current.getTag()) {
jjg@282 251 case CONSTANT_Double:
jjg@282 252 case CONSTANT_Long:
jjg@282 253 next += 2;
jjg@282 254 break;
jjg@282 255 default:
jjg@282 256 next += 1;
jjg@282 257 }
jjg@282 258 return current;
jjg@282 259 }
jjg@282 260
jjg@282 261 public void remove() {
jjg@282 262 throw new UnsupportedOperationException();
jjg@282 263 }
jjg@282 264
jjg@282 265 private CPInfo current;
jjg@282 266 private int next = 1;
jjg@282 267
jjg@282 268 };
jjg@282 269 }
jjg@282 270 };
jjg@282 271 }
jjg@282 272
jjg@46 273 private CPInfo[] pool;
jjg@46 274
jjg@46 275 public interface Visitor<R,P> {
jjg@46 276 R visitClass(CONSTANT_Class_info info, P p);
jjg@46 277 R visitDouble(CONSTANT_Double_info info, P p);
jjg@46 278 R visitFieldref(CONSTANT_Fieldref_info info, P p);
jjg@46 279 R visitFloat(CONSTANT_Float_info info, P p);
jjg@46 280 R visitInteger(CONSTANT_Integer_info info, P p);
jjg@46 281 R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
jjg@46 282 R visitLong(CONSTANT_Long_info info, P p);
jjg@46 283 R visitNameAndType(CONSTANT_NameAndType_info info, P p);
jjg@46 284 R visitMethodref(CONSTANT_Methodref_info info, P p);
jjg@46 285 R visitString(CONSTANT_String_info info, P p);
jjg@46 286 R visitUtf8(CONSTANT_Utf8_info info, P p);
jjg@46 287 }
jjg@46 288
jjg@46 289 public static abstract class CPInfo {
jjg@46 290 CPInfo() {
jjg@46 291 this.cp = null;
jjg@46 292 }
jjg@46 293
jjg@46 294 CPInfo(ConstantPool cp) {
jjg@46 295 this.cp = cp;
jjg@46 296 }
jjg@46 297
jjg@46 298 public abstract int getTag();
jjg@46 299
jjg@282 300 /** The number of slots in the constant pool used by this entry.
jjg@282 301 * 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */
jjg@282 302 public int size() {
jjg@282 303 return 1;
jjg@282 304 }
jjg@282 305
jjg@345 306 public abstract int byteLength();
jjg@345 307
jjg@46 308 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
jjg@46 309
jjg@46 310 protected final ConstantPool cp;
jjg@46 311 }
jjg@46 312
jjg@46 313 public static abstract class CPRefInfo extends CPInfo {
jjg@46 314 protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
jjg@46 315 super(cp);
jjg@46 316 this.tag = tag;
jjg@46 317 class_index = cr.readUnsignedShort();
jjg@46 318 name_and_type_index = cr.readUnsignedShort();
jjg@46 319 }
jjg@46 320
jjg@46 321 protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
jjg@46 322 super(cp);
jjg@46 323 this.tag = tag;
jjg@46 324 this.class_index = class_index;
jjg@46 325 this.name_and_type_index = name_and_type_index;
jjg@46 326 }
jjg@46 327
jjg@46 328 public int getTag() {
jjg@46 329 return tag;
jjg@46 330 }
jjg@46 331
jjg@345 332 public int byteLength() {
jjg@345 333 return 5;
jjg@345 334 }
jjg@345 335
jjg@46 336 public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
jjg@46 337 return cp.getClassInfo(class_index);
jjg@46 338 }
jjg@46 339
jjg@46 340 public String getClassName() throws ConstantPoolException {
jjg@46 341 return cp.getClassInfo(class_index).getName();
jjg@46 342 }
jjg@46 343
jjg@46 344 public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
jjg@46 345 return cp.getNameAndTypeInfo(name_and_type_index);
jjg@46 346 }
jjg@46 347
jjg@46 348 public final int tag;
jjg@46 349 public final int class_index;
jjg@46 350 public final int name_and_type_index;
jjg@46 351 }
jjg@46 352
jjg@46 353 public static class CONSTANT_Class_info extends CPInfo {
jjg@46 354 CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 355 super(cp);
jjg@46 356 name_index = cr.readUnsignedShort();
jjg@46 357 }
jjg@46 358
jjg@46 359 public CONSTANT_Class_info(ConstantPool cp, int name_index) {
jjg@46 360 super(cp);
jjg@46 361 this.name_index = name_index;
jjg@46 362 }
jjg@46 363
jjg@46 364 public int getTag() {
jjg@46 365 return CONSTANT_Class;
jjg@46 366 }
jjg@46 367
jjg@345 368 public int byteLength() {
jjg@345 369 return 3;
jjg@345 370 }
jjg@345 371
jjg@46 372 public String getName() throws ConstantPoolException {
jjg@46 373 return cp.getUTF8Value(name_index);
jjg@46 374 }
jjg@46 375
jjg@281 376 public String getBaseName() throws ConstantPoolException {
jjg@281 377 String name = getName();
jjg@281 378 int index = name.indexOf("[L") + 1;
jjg@281 379 return name.substring(index);
jjg@281 380 }
jjg@281 381
jjg@281 382 public int getDimensionCount() throws ConstantPoolException {
jjg@281 383 String name = getName();
jjg@281 384 int count = 0;
jjg@281 385 while (name.charAt(count) == '[')
jjg@281 386 count++;
jjg@281 387 return count;
jjg@281 388 }
jjg@281 389
jjg@46 390 @Override
jjg@46 391 public String toString() {
jjg@46 392 return "CONSTANT_Class_info[name_index: " + name_index + "]";
jjg@46 393 }
jjg@46 394
jjg@46 395 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 396 return visitor.visitClass(this, data);
jjg@46 397 }
jjg@46 398
jjg@46 399 public final int name_index;
jjg@46 400 }
jjg@46 401
jjg@46 402 public static class CONSTANT_Double_info extends CPInfo {
jjg@46 403 CONSTANT_Double_info(ClassReader cr) throws IOException {
jjg@46 404 value = cr.readDouble();
jjg@46 405 }
jjg@46 406
jjg@46 407 public CONSTANT_Double_info(double value) {
jjg@46 408 this.value = value;
jjg@46 409 }
jjg@46 410
jjg@46 411 public int getTag() {
jjg@46 412 return CONSTANT_Double;
jjg@46 413 }
jjg@46 414
jjg@345 415 public int byteLength() {
jjg@345 416 return 9;
jjg@345 417 }
jjg@345 418
jjg@46 419 @Override
jjg@282 420 public int size() {
jjg@282 421 return 2;
jjg@282 422 }
jjg@282 423
jjg@282 424 @Override
jjg@46 425 public String toString() {
jjg@46 426 return "CONSTANT_Double_info[value: " + value + "]";
jjg@46 427 }
jjg@46 428
jjg@46 429 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 430 return visitor.visitDouble(this, data);
jjg@46 431 }
jjg@46 432
jjg@46 433 public final double value;
jjg@46 434 }
jjg@46 435
jjg@46 436 public static class CONSTANT_Fieldref_info extends CPRefInfo {
jjg@46 437 CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 438 super(cp, cr, CONSTANT_Fieldref);
jjg@46 439 }
jjg@46 440
jjg@46 441 public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
jjg@46 442 super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
jjg@46 443 }
jjg@46 444
jjg@46 445 @Override
jjg@46 446 public String toString() {
jjg@46 447 return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
jjg@46 448 }
jjg@46 449
jjg@46 450 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 451 return visitor.visitFieldref(this, data);
jjg@46 452 }
jjg@46 453 }
jjg@46 454
jjg@46 455 public static class CONSTANT_Float_info extends CPInfo {
jjg@46 456 CONSTANT_Float_info(ClassReader cr) throws IOException {
jjg@46 457 value = cr.readFloat();
jjg@46 458 }
jjg@46 459
jjg@46 460 public CONSTANT_Float_info(float value) {
jjg@46 461 this.value = value;
jjg@46 462 }
jjg@46 463
jjg@46 464 public int getTag() {
jjg@46 465 return CONSTANT_Float;
jjg@46 466 }
jjg@46 467
jjg@345 468 public int byteLength() {
jjg@345 469 return 5;
jjg@345 470 }
jjg@345 471
jjg@46 472 @Override
jjg@46 473 public String toString() {
jjg@46 474 return "CONSTANT_Float_info[value: " + value + "]";
jjg@46 475 }
jjg@46 476
jjg@46 477 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 478 return visitor.visitFloat(this, data);
jjg@46 479 }
jjg@46 480
jjg@46 481 public final float value;
jjg@46 482 }
jjg@46 483
jjg@46 484 public static class CONSTANT_Integer_info extends CPInfo {
jjg@46 485 CONSTANT_Integer_info(ClassReader cr) throws IOException {
jjg@46 486 value = cr.readInt();
jjg@46 487 }
jjg@46 488
jjg@46 489 public CONSTANT_Integer_info(int value) {
jjg@46 490 this.value = value;
jjg@46 491 }
jjg@46 492
jjg@46 493 public int getTag() {
jjg@46 494 return CONSTANT_Integer;
jjg@46 495 }
jjg@46 496
jjg@345 497 public int byteLength() {
jjg@345 498 return 5;
jjg@345 499 }
jjg@345 500
jjg@46 501 @Override
jjg@46 502 public String toString() {
jjg@46 503 return "CONSTANT_Integer_info[value: " + value + "]";
jjg@46 504 }
jjg@46 505
jjg@46 506 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 507 return visitor.visitInteger(this, data);
jjg@46 508 }
jjg@46 509
jjg@46 510 public final int value;
jjg@46 511 }
jjg@46 512
jjg@46 513 public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
jjg@46 514 CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 515 super(cp, cr, CONSTANT_InterfaceMethodref);
jjg@46 516 }
jjg@46 517
jjg@46 518 public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
jjg@46 519 super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
jjg@46 520 }
jjg@46 521
jjg@46 522 @Override
jjg@46 523 public String toString() {
jjg@46 524 return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
jjg@46 525 }
jjg@46 526
jjg@46 527 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 528 return visitor.visitInterfaceMethodref(this, data);
jjg@46 529 }
jjg@46 530 }
jjg@46 531
jjg@46 532 public static class CONSTANT_Long_info extends CPInfo {
jjg@46 533 CONSTANT_Long_info(ClassReader cr) throws IOException {
jjg@46 534 value = cr.readLong();
jjg@46 535 }
jjg@46 536
jjg@46 537 public CONSTANT_Long_info(long value) {
jjg@46 538 this.value = value;
jjg@46 539 }
jjg@46 540
jjg@46 541 public int getTag() {
jjg@46 542 return CONSTANT_Long;
jjg@46 543 }
jjg@46 544
jjg@46 545 @Override
jjg@282 546 public int size() {
jjg@282 547 return 2;
jjg@282 548 }
jjg@282 549
jjg@345 550 public int byteLength() {
jjg@345 551 return 9;
jjg@345 552 }
jjg@345 553
jjg@282 554 @Override
jjg@46 555 public String toString() {
jjg@46 556 return "CONSTANT_Long_info[value: " + value + "]";
jjg@46 557 }
jjg@46 558
jjg@46 559 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 560 return visitor.visitLong(this, data);
jjg@46 561 }
jjg@46 562
jjg@46 563 public final long value;
jjg@46 564 }
jjg@46 565
jjg@46 566 public static class CONSTANT_Methodref_info extends CPRefInfo {
jjg@46 567 CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 568 super(cp, cr, CONSTANT_Methodref);
jjg@46 569 }
jjg@46 570
jjg@46 571 public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
jjg@46 572 super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
jjg@46 573 }
jjg@46 574
jjg@46 575 @Override
jjg@46 576 public String toString() {
jjg@46 577 return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
jjg@46 578 }
jjg@46 579
jjg@46 580 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 581 return visitor.visitMethodref(this, data);
jjg@46 582 }
jjg@46 583 }
jjg@46 584
jjg@46 585 public static class CONSTANT_NameAndType_info extends CPInfo {
jjg@46 586 CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@46 587 super(cp);
jjg@46 588 name_index = cr.readUnsignedShort();
jjg@46 589 type_index = cr.readUnsignedShort();
jjg@46 590 }
jjg@46 591
jjg@46 592 public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
jjg@46 593 super(cp);
jjg@46 594 this.name_index = name_index;
jjg@46 595 this.type_index = type_index;
jjg@46 596 }
jjg@46 597
jjg@46 598 public int getTag() {
jjg@46 599 return CONSTANT_NameAndType;
jjg@46 600 }
jjg@46 601
jjg@345 602 public int byteLength() {
jjg@345 603 return 5;
jjg@345 604 }
jjg@345 605
jjg@46 606 public String getName() throws ConstantPoolException {
jjg@46 607 return cp.getUTF8Value(name_index);
jjg@46 608 }
jjg@46 609
jjg@46 610 public String getType() throws ConstantPoolException {
jjg@46 611 return cp.getUTF8Value(type_index);
jjg@46 612 }
jjg@46 613
jjg@46 614 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 615 return visitor.visitNameAndType(this, data);
jjg@46 616 }
jjg@46 617
jjg@300 618 @Override
jjg@300 619 public String toString() {
jjg@300 620 return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
jjg@300 621 }
jjg@300 622
jjg@46 623 public final int name_index;
jjg@46 624 public final int type_index;
jjg@46 625 }
jjg@46 626
jjg@46 627 public static class CONSTANT_String_info extends CPInfo {
jjg@52 628 CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {
jjg@52 629 super(cp);
jjg@46 630 string_index = cr.readUnsignedShort();
jjg@46 631 }
jjg@46 632
jjg@46 633 public CONSTANT_String_info(ConstantPool cp, int string_index) {
jjg@46 634 super(cp);
jjg@46 635 this.string_index = string_index;
jjg@46 636 }
jjg@46 637
jjg@46 638 public int getTag() {
jjg@46 639 return CONSTANT_String;
jjg@46 640 }
jjg@46 641
jjg@345 642 public int byteLength() {
jjg@345 643 return 3;
jjg@345 644 }
jjg@345 645
jjg@46 646 public String getString() throws ConstantPoolException {
jjg@46 647 return cp.getUTF8Value(string_index);
jjg@46 648 }
jjg@46 649
jjg@46 650 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 651 return visitor.visitString(this, data);
jjg@46 652 }
jjg@46 653
jjg@300 654 @Override
jjg@300 655 public String toString() {
jjg@300 656 return "CONSTANT_String_info[class_index: " + string_index + "]";
jjg@300 657 }
jjg@300 658
jjg@46 659 public final int string_index;
jjg@46 660 }
jjg@46 661
jjg@46 662 public static class CONSTANT_Utf8_info extends CPInfo {
jjg@46 663 CONSTANT_Utf8_info(ClassReader cr) throws IOException {
jjg@46 664 value = cr.readUTF();
jjg@46 665 }
jjg@46 666
jjg@46 667 public CONSTANT_Utf8_info(String value) {
jjg@46 668 this.value = value;
jjg@46 669 }
jjg@46 670
jjg@46 671 public int getTag() {
jjg@46 672 return CONSTANT_Utf8;
jjg@46 673 }
jjg@46 674
jjg@345 675 public int byteLength() {
jjg@345 676 class SizeOutputStream extends OutputStream {
jjg@345 677 @Override
jjg@345 678 public void write(int b) throws IOException {
jjg@345 679 size++;
jjg@345 680 }
jjg@345 681 int size;
jjg@345 682 }
jjg@345 683 SizeOutputStream sizeOut = new SizeOutputStream();
jjg@345 684 DataOutputStream out = new DataOutputStream(sizeOut);
jjg@345 685 try { out.writeUTF(value); } catch (IOException ignore) { }
jjg@345 686 return 1 + sizeOut.size;
jjg@345 687 }
jjg@345 688
jjg@46 689 @Override
jjg@46 690 public String toString() {
jjg@300 691 if (value.length() < 32 && isPrintableAscii(value))
jjg@300 692 return "CONSTANT_Utf8_info[value: \"" + value + "\"]";
jjg@300 693 else
jjg@300 694 return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";
jjg@300 695 }
jjg@300 696
jjg@300 697 static boolean isPrintableAscii(String s) {
jjg@300 698 for (int i = 0; i < s.length(); i++) {
jjg@300 699 char c = s.charAt(i);
jjg@300 700 if (c < 32 || c >= 127)
jjg@300 701 return false;
jjg@300 702 }
jjg@300 703 return true;
jjg@46 704 }
jjg@46 705
jjg@46 706 public <R, D> R accept(Visitor<R, D> visitor, D data) {
jjg@46 707 return visitor.visitUtf8(this, data);
jjg@46 708 }
jjg@46 709
jjg@46 710 public final String value;
jjg@46 711 }
jjg@46 712
jjg@46 713
jjg@46 714 }

mercurial