#pragma once #include "membuffer.h" #include "constants.h" #include "annotations.h" #include namespace java { /** * Class representing a Java .class file */ class classfile : public util::membuffer { public: classfile(char *data, std::size_t size) : membuffer(data, size) { valid = false; is_synthetic = false; read_be(magic); if (magic != 0xCAFEBABE) throw new classfile_exception(); read_be(minor_version); read_be(major_version); constants.load(*this); read_be(access_flags); read_be(this_class); read_be(super_class); // Interfaces uint16_t iface_count = 0; read_be(iface_count); while (iface_count) { uint16_t iface; read_be(iface); interfaces.push_back(iface); iface_count--; } // Fields // read fields (and attributes from inside fields) (and possible inner classes. yay for // recursion!) // for now though, we will ignore all attributes /* * field_info * { * u2 access_flags; * u2 name_index; * u2 descriptor_index; * u2 attributes_count; * attribute_info attributes[attributes_count]; * } */ uint16_t field_count = 0; read_be(field_count); while (field_count) { // skip field stuff skip(6); // and skip field attributes uint16_t attr_count = 0; read_be(attr_count); while (attr_count) { skip(2); uint32_t attr_length = 0; read_be(attr_length); skip(attr_length); attr_count--; } field_count--; } // class methods /* * method_info * { * u2 access_flags; * u2 name_index; * u2 descriptor_index; * u2 attributes_count; * attribute_info attributes[attributes_count]; * } */ uint16_t method_count = 0; read_be(method_count); while (method_count) { skip(6); // and skip method attributes uint16_t attr_count = 0; read_be(attr_count); while (attr_count) { skip(2); uint32_t attr_length = 0; read_be(attr_length); skip(attr_length); attr_count--; } method_count--; } // class attributes // there are many kinds of attributes. this is just the generic wrapper structure. // type is decided by attribute name. extensions to the standard are *possible* // class annotations are one kind of a attribute (one per class) /* * attribute_info * { * u2 attribute_name_index; * u4 attribute_length; * u1 info[attribute_length]; * } */ uint16_t class_attr_count = 0; read_be(class_attr_count); while (class_attr_count) { uint16_t name_idx = 0; read_be(name_idx); uint32_t attr_length = 0; read_be(attr_length); auto name = constants[name_idx]; if (name.str_data == "RuntimeVisibleAnnotations") { uint16_t num_annotations = 0; read_be(num_annotations); while (num_annotations) { visible_class_annotations.push_back(annotation::read(*this, constants)); num_annotations--; } } else skip(attr_length); class_attr_count--; } valid = true; } ; bool valid; bool is_synthetic; uint32_t magic; uint16_t minor_version; uint16_t major_version; constant_pool constants; uint16_t access_flags; uint16_t this_class; uint16_t super_class; // interfaces this class implements ? must be. investigate. std::vector interfaces; // FIXME: doesn't free up memory on delete java::annotation_table visible_class_annotations; }; }