/** * Read the class file header. * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. */ void readHeader(DataInputStream in) throws IOException { int magic = in.readInt(); if (magic != 0xCAFEBABE) { throw new ClassFormatError("Bad magic number."); } int major = in.readUnsignedShort(); int minor = in.readUnsignedShort(); }
/** * Constructor. This constructor parses the class file from the byte array * * @param code A byte array containing the class data */ public ClassFile(File classFileSource, byte[] code, ExtensionInfo ext) { this.classFileSource = classFileSource; this.extensionInfo = ext; try { ByteArrayInputStream bin = new ByteArrayInputStream(code); DataInputStream in = new DataInputStream(bin); read(in); in.close(); bin.close(); } catch (IOException e) { throw new InternalCompilerError("I/O exception on ByteArrayInputStream"); } }
/** * Read the class's name, superclass, and interfaces. * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. */ void readClassInfo(DataInputStream in) throws IOException { int index; thisClass = in.readUnsignedShort(); superClass = in.readUnsignedShort(); int numInterfaces = in.readUnsignedShort(); interfaces = new int[numInterfaces]; for (int i = 0; i < numInterfaces; i++) { interfaces[i] = in.readUnsignedShort(); } }
/** * Read a constant from the constant pool. * * @param in The stream from which to read. * @return The constant. * @exception IOException If an error occurs while reading. */ Constant readConstant(DataInputStream in) throws IOException { int tag = in.readUnsignedByte(); Object value; switch (tag) { case Constant.CLASS: case Constant.STRING: case Constant.METHOD_TYPE: // @since 1.8 value = Integer.valueOf(in.readUnsignedShort()); break; case Constant.FIELD_REF: case Constant.METHOD_REF: case Constant.INTERFACE_METHOD_REF: case Constant.NAME_AND_TYPE: case Constant.INVOKE_DYNAMIC: // @since 1.8 value = new int[2]; ((int[]) value)[0] = in.readUnsignedShort(); ((int[]) value)[1] = in.readUnsignedShort(); break; case Constant.INTEGER: value = Integer.valueOf(in.readInt()); break; case Constant.FLOAT: value = Float.valueOf(in.readFloat()); break; case Constant.LONG: // Longs take up 2 constant pool entries. value = Long.valueOf(in.readLong()); break; case Constant.DOUBLE: // Doubles take up 2 constant pool entries. value = Double.valueOf(in.readDouble()); break; case Constant.UTF8: value = in.readUTF(); break; case Constant.METHOD_HANDLE: // @since 1.8 value = new int[2]; ((int[]) value)[0] = in.readUnsignedByte(); ((int[]) value)[1] = in.readUnsignedShort(); break; default: throw new ClassFormatError("Invalid constant tag: " + tag); } return new Constant(tag, value); }
/** * Read the class's methods. * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. */ void readMethods(DataInputStream in) throws IOException { int numMethods = in.readUnsignedShort(); methods = new Method[numMethods]; for (int i = 0; i < numMethods; i++) { methods[i] = createMethod(in); } }
/** * Read the class's fields. * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. */ void readFields(DataInputStream in) throws IOException { int numFields = in.readUnsignedShort(); fields = new Field[numFields]; for (int i = 0; i < numFields; i++) { fields[i] = createField(in); } }
/** * Read the class's attributes. Since none of the attributes are required, just read the length of * each attribute and skip that many bytes. * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. */ public void readAttributes(DataInputStream in) throws IOException { int numAttributes = in.readUnsignedShort(); attrs = new Attribute[numAttributes]; for (int i = 0; i < numAttributes; i++) { int nameIndex = in.readUnsignedShort(); int length = in.readInt(); String name = (String) constants[nameIndex].value(); Attribute a = createAttribute(in, name, nameIndex, length); if (a != null) { attrs[i] = a; } else { long n = in.skip(length); if (n != length) { throw new EOFException(); } } } }
/** * Read the class's constant pool. Constants in the constant pool are modeled by an array of * <tt>reflect.Constant</tt>/ * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. * @see Constant * @see #constants */ void readConstantPool(DataInputStream in) throws IOException { int count = in.readUnsignedShort(); constants = new Constant[count]; // The first constant is reserved for internal use by the JVM. constants[0] = null; // Read the constants. for (int i = 1; i < count; i++) { constants[i] = readConstant(in); switch (constants[i].tag()) { case Constant.LONG: case Constant.DOUBLE: // Longs and doubles take up 2 constant pool entries. constants[++i] = null; break; } } }
/** * Read the class's access flags. * * @param in The stream from which to read. * @exception IOException If an error occurs while reading. */ void readAccessFlags(DataInputStream in) throws IOException { modifiers = in.readUnsignedShort(); }