first scanner /parser copied from the jdt java version
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / classfmt / ClassFileStruct.java
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
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.classfmt;
12
13 abstract public class ClassFileStruct implements ClassFileConstants {
14         byte[] reference;
15         int structOffset;
16 public ClassFileStruct(byte classFileBytes[], int off) {
17         reference = classFileBytes;
18         structOffset = off;
19 }
20 public ClassFileStruct (byte classFileBytes[], int off, boolean verifyStructure) {
21         reference = classFileBytes;
22         structOffset = off;
23 }
24 public double doubleAt(int relativeOffset) {
25         return (Double.longBitsToDouble(this.i8At(relativeOffset)));
26 }
27 public float floatAt(int relativeOffset) {
28         return (Float.intBitsToFloat(this.i4At(relativeOffset)));
29 }
30 public int i1At(int relativeOffset) {
31         return reference[relativeOffset + structOffset];
32 }
33 public int i2At(int relativeOffset) {
34         int position = relativeOffset + structOffset;
35         return (reference[position++] << 8) + (reference[position] & 0xFF);
36 }
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);
40 }
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));
44 }
45 public static String printTypeModifiers(int modifiers) {
46
47         java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
48         java.io.PrintWriter print = new java.io.PrintWriter(out);
49
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$
56         print.flush();
57         return out.toString();
58 }
59 public int u1At(int relativeOffset) {
60         return (reference[relativeOffset + structOffset] & 0xFF);
61 }
62 public int u2At(int relativeOffset) {
63         int position = relativeOffset + structOffset;
64         return ((reference[position++] & 0xFF) << 8) + (reference[position] & 0xFF);
65 }
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));
69 }
70 public char[] utf8At(int relativeOffset, int bytesAvailable) {
71         int x, y, z;
72         int length = bytesAvailable;
73         char outputBuf[] = new char[bytesAvailable];
74         int outputPos = 0;
75         int readOffset = structOffset + relativeOffset;
76         
77         while (length != 0) {
78                 x = reference[readOffset++] & 0xFF;
79                 length--;
80                 if ((0x80 & x) != 0) {
81                         y = this.reference[readOffset++] & 0xFF;
82                         length--;
83                         if ((x & 0x20) != 0) {
84                                 z = this.reference[readOffset++] & 0xFF;
85                                 length--;
86                                 x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
87                         } else {
88                                 x = ((x & 0x1F) << 6) + (y & 0x3F);
89                         }
90                 }
91                 outputBuf[outputPos++] = (char) x;
92         }
93
94         if (outputPos != bytesAvailable) {
95                 System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
96         }
97         return outputBuf;
98 }
99
100 protected void reset() {
101         this.reference = null;
102 }
103
104 public char[] utf8At(int relativeOffset, int bytesAvailable, boolean testValidity) throws ClassFormatException {
105         int x, y, z;
106         int length = bytesAvailable;
107         char outputBuf[] = new char[bytesAvailable];
108         int outputPos = 0;
109         int readOffset = structOffset + relativeOffset;
110         
111         while (length != 0) {
112                 x = reference[readOffset++] & 0xFF;
113                 length--;
114                 if ((0x80 & x) != 0) {
115                         if (testValidity) {
116                                 if ((0x40 & x) == 0) {
117                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
118                                 }
119                                 if (length < 1) {
120                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
121                                 }
122                         }
123                         y = this.reference[readOffset++] & 0xFF;
124                         length--;
125                         if (testValidity) {
126                                 if ((y & 0xC0) != 0x80) {
127                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
128                                 }
129                         }
130                         if ((x & 0x20) != 0) {
131                                 if (testValidity && (length < 1)) {
132                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
133                                 }
134                                 z = this.reference[readOffset++] & 0xFF;
135                                 length--;
136                                 if (testValidity && ((z & 0xC0) != 0x80)) {
137                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
138                                 }
139                                 x = ((x & 0x1F) << 12) + ((y & 0x3F) << 6) + (z & 0x3F);
140                                 if (testValidity && (x < 0x0800)) {
141                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
142                                 }
143                         } else {
144                                 x = ((x & 0x1F) << 6) + (y & 0x3F);
145                                 if (testValidity && !((x == 0) || (x >= 0x80))) {
146                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
147                                 }
148                         }
149                 } else {
150                         if (testValidity && x == 0) {
151                                         throw new ClassFormatException(ClassFormatException.ErrMalformedUtf8);
152                         }
153                 }
154                 outputBuf[outputPos++] = (char) x;
155         }
156
157         if (outputPos != bytesAvailable) {
158                 System.arraycopy(outputBuf, 0, (outputBuf = new char[outputPos]), 0, outputPos);
159         }
160         return outputBuf;
161 }
162 public static void verifyMethodNameAndSignature(char[] name, char[] signature) throws ClassFormatException {
163
164         // ensure name is not empty 
165         if (name.length == 0) {
166                 throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
167         }
168
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);
178                         }
179                 } else {
180                         throw new ClassFormatException(ClassFormatException.ErrInvalidMethodName);
181                 }
182         }
183 }
184 }