/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/** A constant pool parser.
*/
public class ConstantPoolParser {
final byte[] classFile;
final byte[] tags;
// these are filled in on first parse:
int endOffset;
// used to decode UTF8 array
/** Creates a constant pool parser.
* @param classFile an array of bytes containing a class.
* @throws InvalidConstantPoolFormatException if the header of the class has errors.
*/
}
/** Create a constant pool parser by loading the bytecodes of the
* class taken as argument.
*
* @param templateClass the class to parse.
*
* @throws IOException raised if an I/O occurs when loading
* the bytecode of the template class.
* @throws InvalidConstantPoolFormatException if the header of the class has errors.
*
* @see #ConstantPoolParser(byte[])
* @see AnonymousClassLoader#readClassFile(Class)
*/
public ConstantPoolParser(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
}
/** Creates an empty patch to patch the class file
* used by the current parser.
* @return a new class patch.
*/
return new ConstantPoolPatch(this);
}
/** Report the tag of the indicated CP entry.
* @param index
* @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc.
*/
getEndOffset(); // trigger an exception if we haven't parsed yet
}
/** Report the length of the constant pool. */
public int getLength() {
return firstHeader[4];
}
/** Report the offset, within the class file, of the start of the constant pool. */
public int getStartOffset() {
}
/** Report the offset, within the class file, of the end of the constant pool. */
public int getEndOffset() {
if (endOffset == 0)
throw new IllegalStateException("class file has not yet been parsed");
return endOffset;
}
/** Report the CP index of this class's own name. */
public int getThisClassIndex() {
getEndOffset(); // provoke exception if not yet parsed
return secondHeader[1];
}
/** Report the total size of the class file. */
public int getTailLength() {
}
/** Write the head (header plus constant pool)
* of the class file to the indicated stream.
*/
}
/** Write the head (header plus constant pool)
* of the class file to the indicated stream,
* incorporating the non-null entries of the given array
* as patches.
*/
// this will be useful to partially emulate the class loader on old JVMs
throw new UnsupportedOperationException("Not yet implemented");
}
/** Write the tail (everything after the constant pool)
* of the class file to the indicated stream.
*/
}
char[] result = new char[5];
if (magic != 0xCAFEBABE)
// skip major, minor version
if (len < 1)
throw new InvalidConstantPoolFormatException("constant pool length < 1");
return result;
}
/** Parse the constant pool of the class
* calling a method visit* each time a constant pool entry is parsed.
*
* The order of the calls to visit* is not guaranteed to be the same
* than the order of the constant pool entry in the bytecode array.
*
* @param visitor
* @throws InvalidConstantPoolFormatException
*/
try {
} catch(BufferUnderflowException e) {
throw new InvalidConstantPoolFormatException(e);
}
if (endOffset == 0) {
secondHeader = new char[4];
}
}
}
return charArray;
}
private void parseConstantPool(ByteBuffer buffer, Object[] values, ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
switch (tag) {
case CONSTANT_Utf8:
break;
case CONSTANT_Integer:
i++;
break;
case CONSTANT_Float:
i++;
break;
case CONSTANT_Long:
i+=2;
break;
case CONSTANT_Double:
i+=2;
break;
case CONSTANT_Class: // fall through:
case CONSTANT_String:
break;
case CONSTANT_Fieldref: // fall through:
case CONSTANT_Methodref: // fall through:
case CONSTANT_InterfaceMethodref: // fall through:
case CONSTANT_NameAndType:
break;
default:
}
}
}
// clean out the int[] values, which are temporary
//System.out.println("CP resolve pass: "+beg+".."+end);
if (!(value instanceof int[]))
continue;
switch (tag) {
case CONSTANT_String:
break;
case CONSTANT_Class: {
// use the external form favored by Class.forName:
break;
}
case CONSTANT_NameAndType: {
break;
}
case CONSTANT_Fieldref: // fall through:
case CONSTANT_Methodref: // fall through:
case CONSTANT_InterfaceMethodref: {
!(nameAndType instanceof String[])) {
// one more pass is needed
continue;
}
nameAndTypeArray[0],
nameAndTypeArray[1],
}
break;
default:
continue;
}
}
}
}
}
}
private static String getUTF8(ByteBuffer buffer, int utfLen, char[] charArray) throws InvalidConstantPoolFormatException {
int index = 0;
if (c > 127) {
}
}
}
private static String getUTF8Extended(ByteBuffer buffer, int utfLimit, char[] charArray, int index) throws InvalidConstantPoolFormatException {
switch (c >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
/* 0xxxxxxx*/
break;
case 12: case 13:
/* 110x xxxx 10xx xxxx*/
throw new InvalidConstantPoolFormatException(
(c2 & 0x3F));
break;
case 14:
/* 1110 xxxx 10xx xxxx 10xx xxxx */
throw new InvalidConstantPoolFormatException(
break;
default:
/* 10xx xxxx, 1111 xxxx */
throw new InvalidConstantPoolFormatException(
}
}
// The number of chars produced may be less than utflen
}
}