Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package serp.bytecode.lowlevel;
import java.io.*;
/**
* Efficient representation of the constant pool as a table. This class
* can be used to parse out bits of information from bytecode without
* instantiating a full {@link serp.bytecode.BCClass}.
*
* @author Abe White
*/
public class ConstantPoolTable {
private byte[] _bytecode = null;
private int[] _table = null;
private int _idx = 0;
/**
* Constructor; supply class bytecode.
*/
public ConstantPoolTable(byte[] b) {
_bytecode = b;
_table = new int[readUnsignedShort(b, 8)];
_idx = parse(b, _table);
}
/**
* Constructor; supply input stream to bytecode.
*/
public ConstantPoolTable(InputStream in) throws IOException {
this(toByteArray(in));
}
/**
* Allows static computation of the byte index after the constant
* pool without caching constant pool information.
*/
public static int getEndIndex(byte[] b) {
return parse(b, null);
}
/**
* Parse class bytecode, returning end index of pool.
*/
private static int parse(byte[] b, int[] table) {
// each entry is the index in the byte array of the data for a const
// pool entry
int entries = (table == null) ? readUnsignedShort(b, 8) : table.length;
int idx = 10;
for (int i = 1; i < entries; i++) {
if (table != null)
table[i] = idx + 1; // skip entry type
switch (b[idx]) {
case 1: // utf8
idx += (3 + readUnsignedShort(b, idx + 1));
break;
case 3: // integer
case 4: // float
case 9: // field
case 10: // method
case 11: // interface method
case 18: // invoke dynamic
case 12: // name
idx += 5;
break;
case 5: // long
case 6: // double
idx += 9;
i++; // wide entry
break;
case 15: // method handle
idx += 4;
break;
case 16: // method type
default:
idx += 3;
}
}
return idx;
}
/**
* Read a byte value at the given offset into the given bytecode.
*/
public static int readByte(byte[] b, int idx) {
return b[idx] & 0xFF;
}
/**
* Read an unsigned short value at the given offset into the given bytecode.
*/
public static int readUnsignedShort(byte[] b, int idx) {
return (readByte(b, idx) << 8) | readByte(b, idx + 1);
}
/**
* Read an int value at the given offset into the given bytecode.
*/
public static int readInt(byte[] b, int idx) {
return (readByte(b, idx) << 24) | (readByte(b, idx + 1) << 16)
| (readByte(b, idx + 2) << 8) | readByte(b, idx + 3);
}
/**
* Read a long value at the given offset into the given bytecode.
*/
public static long readLong(byte[] b, int idx) {
return (readInt(b, idx) << 32) | readInt(b, idx + 4);
}
/**
* Read a UTF-8 string value at the given offset into the given bytecode.
*/
public static String readString(byte[] b, int idx) {
int len = readUnsignedShort(b, idx);
try {
return new String(b, idx + 2, len, "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new ClassFormatError(uee.toString());
}
}
/**
* Read the contents of the given stream.
*/
private static byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
for (int r; (r = in.read(buf)) != -1; bout.write(buf, 0, r));
return bout.toByteArray();
}
/**
* Return the index into the bytecode of the end of the constant pool.
*/
public int getEndIndex() {
return _idx;
}
/**
* Return the given table entry.
*/
public int get(int idx) {
return _table[idx];
}
/**
* Read a byte value at the given offset.
*/
public int readByte(int idx) {
return readByte(_bytecode, idx);
}
/**
* Read an unsigned short value at the given offset.
*/
public int readUnsignedShort(int idx) {
return readUnsignedShort(_bytecode, idx);
}
/**
* Read an int value at the given offset.
*/
public int readInt(int idx) {
return readInt(_bytecode, idx);
}
/**
* Read a long value at the given offset.
*/
public long readLong(int idx) {
return readLong(_bytecode, idx);
}
/**
* Read a UTF-8 string value at the given offset.
*/
public String readString(int idx) {
return readString(_bytecode, idx);
}
}