1 /*******************************************************************************
2 * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v0.5
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v05.html
9 * IBM Corporation - initial API and implementation
10 ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.classfmt;
13 abstract public class ClassFileStruct implements ClassFileConstants {
16 public ClassFileStruct(byte classFileBytes[], int off) {
17 reference = classFileBytes;
20 public ClassFileStruct (byte classFileBytes[], int off, boolean verifyStructure) {
21 reference = classFileBytes;
24 public double doubleAt(int relativeOffset) {
25 return (Double.longBitsToDouble(this.i8At(relativeOffset)));
27 public float floatAt(int relativeOffset) {
28 return (Float.intBitsToFloat(this.i4At(relativeOffset)));
30 public int i1At(int relativeOffset) {
31 return reference[relativeOffset + structOffset];
33 public int i2At(int relativeOffset) {
34 int position = relativeOffset + structOffset;
35 return (reference[position++] << 8) + (reference[position] & 0xFF);
37 public int i4At(int relativeOffset) {
38 int position = relativeOffset + structOffset;
39 return ((reference[position++] & 0xFF) << 24) + ((reference[position++] & 0xFF) << 16) + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
41 public long i8At(int relativeOffset) {
42 int position = relativeOffset + structOffset;
43 return (((long) (reference[position++] & 0xFF)) << 56) + (((long) (reference[position++] & 0xFF)) << 48) + (((long) (reference[position++] & 0xFF)) << 40) + (((long) (reference[position++] & 0xFF)) << 32) + (((long) (reference[position++] & 0xFF)) << 24) + (((long) (reference[position++] & 0xFF)) << 16) + (((long) (reference[position++] & 0xFF)) << 8) + ((long) (reference[position++] & 0xFF));
45 public static String printTypeModifiers(int modifiers) {
47 java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
48 java.io.PrintWriter print = new java.io.PrintWriter(out);
50 if ((modifiers & AccPublic) != 0) print.print("public "); //$NON-NLS-1$
51 if ((modifiers & AccPrivate) != 0) print.print("private "); //$NON-NLS-1$
52 if ((modifiers & AccFinal) != 0) print.print("final "); //$NON-NLS-1$
53 if ((modifiers & AccSuper) != 0) print.print("super "); //$NON-NLS-1$
54 if ((modifiers & AccInterface) != 0) print.print("interface "); //$NON-NLS-1$
55 if ((modifiers & AccAbstract) != 0) print.print("abstract "); //$NON-NLS-1$
57 return out.toString();
59 public int u1At(int relativeOffset) {
60 return (reference[relativeOffset + structOffset] & 0xFF);
62 public int u2At(int relativeOffset) {
63 int position = relativeOffset + structOffset;
64 return ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
66 public long u4At(int relativeOffset) {
67 int position = relativeOffset + structOffset;
68 return (((reference[position++] & 0xFFL) << 24) + ((reference[position++] & 0xFF) << 16) + ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF));
70 public char[] utf8At(int relativeOffset, int bytesAvailable) {
72 int length = bytesAvailable;
73 char outputBuf[] = new char[bytesAvailable];
75 int readOffset = structOffset + relativeOffset;
78 x = reference[readOffset++] & 0xFF;
80 if ((0x80 & x) != 0) {
81 y = this.reference[readOffset++] & 0xFF;
83 if ((x & 0x20) != 0) {
84 z = this.reference[readOffset++] & 0xFF;
86 x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
88 x = ((x & 0x1F) << 6) + (y & 0x3F);
91 outputBuf[outputPos++] = (char) x;
94 if (outputPos != bytesAvailable) {
95 System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
100 protected void reset() {
101 this.reference = null;
104 public char[] utf8At(int relativeOffset, int bytesAvailable, boolean testValidity) throws ClassFormatException {
106 int length = bytesAvailable;
107 char outputBuf[] = new char[bytesAvailable];
109 int readOffset = structOffset + relativeOffset;
111 while (length != 0) {
112 x = reference[readOffset++] & 0xFF;
114 if ((0x80 & x) != 0) {
116 if ((0x40 & x) == 0) {
117 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
120 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
123 y = this.reference[readOffset++] & 0xFF;
126 if ((y & 0xC0) != 0x80) {
127 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
130 if ((x & 0x20) != 0) {
131 if (testValidity && (length < 1)) {
132 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
134 z = this.reference[readOffset++] & 0xFF;
136 if (testValidity && ((z & 0xC0) != 0x80)) {
137 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
139 x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
140 if (testValidity && (x < 0x0800)) {
141 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
144 x = ((x & 0x1F) << 6) + (y & 0x3F);
145 if (testValidity && !((x == 0) || (x >= 0x80))) {
146 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
150 if (testValidity && x == 0) {
151 throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
154 outputBuf[outputPos++] = (char) x;
157 if (outputPos != bytesAvailable) {
158 System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
162 public static void verifyMethodNameAndSignature(char[] name, char[] signature) throws ClassFormatException {
164 // ensure name is not empty
165 if (name.length == 0) {
166 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
169 // if name begins with the < character it must be clinit or init
170 if (name[0] == '<') {
171 if (new String(name).equals("<clinit>") || new String(name).equals("<init>")) { //$NON-NLS-2$ //$NON-NLS-1$
172 int signatureLength = signature.length;
173 if (!((signatureLength > 2)
174 && (signature[0] == '(')
175 && (signature[signatureLength - 2] == ')')
176 && (signature[signatureLength - 1] == 'V'))) {
177 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodSignature);
180 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);