mirror of
https://github.com/MultiMC/MultiMC5.git
synced 2024-11-20 08:10:11 +00:00
252 lines
7.0 KiB
C
252 lines
7.0 KiB
C
|
#pragma once
|
||
|
#include "classfile.h"
|
||
|
#include <map>
|
||
|
#include <vector>
|
||
|
|
||
|
namespace java
|
||
|
{
|
||
|
enum element_value_type : uint8_t
|
||
|
{
|
||
|
INVALID = 0,
|
||
|
STRING = 's',
|
||
|
ENUM_CONSTANT = 'e',
|
||
|
CLASS = 'c',
|
||
|
ANNOTATION = '@',
|
||
|
ARRAY = '[', // one array dimension
|
||
|
PRIMITIVE_INT = 'I', // integer
|
||
|
PRIMITIVE_BYTE = 'B', // signed byte
|
||
|
PRIMITIVE_CHAR = 'C', // Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16
|
||
|
PRIMITIVE_DOUBLE = 'D', // double-precision floating-point value
|
||
|
PRIMITIVE_FLOAT = 'F', // single-precision floating-point value
|
||
|
PRIMITIVE_LONG = 'J', // long integer
|
||
|
PRIMITIVE_SHORT = 'S', // signed short
|
||
|
PRIMITIVE_BOOLEAN = 'Z' // true or false
|
||
|
};
|
||
|
/**
|
||
|
* The element_value structure is a discriminated union representing the value of an element-value pair.
|
||
|
* It is used to represent element values in all attributes that describe annotations
|
||
|
* - RuntimeVisibleAnnotations
|
||
|
* - RuntimeInvisibleAnnotations
|
||
|
* - RuntimeVisibleParameterAnnotations
|
||
|
* - RuntimeInvisibleParameterAnnotations).
|
||
|
*
|
||
|
* The element_value structure has the following format:
|
||
|
*/
|
||
|
class element_value
|
||
|
{
|
||
|
protected:
|
||
|
element_value_type type;
|
||
|
constant_pool & pool;
|
||
|
|
||
|
public:
|
||
|
element_value(element_value_type type, constant_pool & pool): type(type), pool(pool) {};
|
||
|
|
||
|
element_value_type getElementValueType()
|
||
|
{
|
||
|
return type;
|
||
|
}
|
||
|
|
||
|
virtual std::string toString() = 0;
|
||
|
|
||
|
static element_value * readElementValue(util::membuffer & input, constant_pool & pool);
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Each value of the annotations table represents a single runtime-visible annotation on a program element.
|
||
|
* The annotation structure has the following format:
|
||
|
*/
|
||
|
class annotation
|
||
|
{
|
||
|
public:
|
||
|
typedef std::vector< std::pair<uint16_t, element_value * > > value_list;
|
||
|
protected:
|
||
|
/**
|
||
|
* The value of the type_index item must be a valid index into the constant_pool table.
|
||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||
|
* representing a field descriptor representing the annotation type corresponding
|
||
|
* to the annotation represented by this annotation structure.
|
||
|
*/
|
||
|
uint16_t type_index;
|
||
|
/**
|
||
|
* map between element_name_index and value.
|
||
|
*
|
||
|
* The value of the element_name_index item must be a valid index into the constant_pool table.
|
||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure representing
|
||
|
* a valid field descriptor (§4.3.2) that denotes the name of the annotation type element represented
|
||
|
* by this element_value_pairs entry.
|
||
|
*/
|
||
|
value_list name_val_pairs;
|
||
|
/**
|
||
|
* Reference to the parent constant pool
|
||
|
*/
|
||
|
constant_pool & pool;
|
||
|
public:
|
||
|
annotation(uint16_t type_index, constant_pool& pool):type_index(type_index), pool(pool) {};
|
||
|
~annotation()
|
||
|
{
|
||
|
for(unsigned i = 0 ; i < name_val_pairs.size(); i++)
|
||
|
{
|
||
|
delete name_val_pairs[i].second;
|
||
|
}
|
||
|
}
|
||
|
void add_pair(uint16_t key, element_value * value)
|
||
|
{
|
||
|
name_val_pairs.push_back(std::make_pair(key, value));
|
||
|
};
|
||
|
value_list::const_iterator begin()
|
||
|
{
|
||
|
return name_val_pairs.cbegin();
|
||
|
}
|
||
|
value_list::const_iterator end()
|
||
|
{
|
||
|
return name_val_pairs.cend();
|
||
|
}
|
||
|
std::string toString();
|
||
|
static annotation * read(util::membuffer & input, constant_pool & pool);
|
||
|
};
|
||
|
typedef std::vector<annotation *> annotation_table;
|
||
|
|
||
|
|
||
|
/// type for simple value annotation elements
|
||
|
class element_value_simple : public element_value
|
||
|
{
|
||
|
protected:
|
||
|
/// index of the constant in the constant pool
|
||
|
uint16_t index;
|
||
|
public:
|
||
|
element_value_simple(element_value_type type, uint16_t index , constant_pool& pool):
|
||
|
element_value(type, pool), index(index)
|
||
|
{
|
||
|
// TODO: verify consistency
|
||
|
};
|
||
|
uint16_t getIndex()
|
||
|
{
|
||
|
return index;
|
||
|
}
|
||
|
virtual std::string toString()
|
||
|
{
|
||
|
return pool[index].toString();
|
||
|
};
|
||
|
};
|
||
|
/// The enum_const_value item is used if the tag item is 'e'.
|
||
|
class element_value_enum : public element_value
|
||
|
{
|
||
|
protected:
|
||
|
/**
|
||
|
* The value of the type_name_index item must be a valid index into the constant_pool table.
|
||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||
|
* representing a valid field descriptor (§4.3.2) that denotes the internal form of the binary
|
||
|
* name (§4.2.1) of the type of the enum constant represented by this element_value structure.
|
||
|
*/
|
||
|
uint16_t typeIndex;
|
||
|
/**
|
||
|
* The value of the const_name_index item must be a valid index into the constant_pool table.
|
||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||
|
* representing the simple name of the enum constant represented by this element_value structure.
|
||
|
*/
|
||
|
uint16_t valueIndex;
|
||
|
public:
|
||
|
element_value_enum(element_value_type type, uint16_t typeIndex, uint16_t valueIndex, constant_pool& pool):
|
||
|
element_value(type, pool), typeIndex(typeIndex), valueIndex(valueIndex)
|
||
|
{
|
||
|
// TODO: verify consistency
|
||
|
}
|
||
|
uint16_t getValueIndex()
|
||
|
{
|
||
|
return valueIndex;
|
||
|
}
|
||
|
uint16_t getTypeIndex()
|
||
|
{
|
||
|
return typeIndex;
|
||
|
}
|
||
|
virtual std::string toString()
|
||
|
{
|
||
|
return "enum value";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
class element_value_class : public element_value
|
||
|
{
|
||
|
protected:
|
||
|
/**
|
||
|
* The class_info_index item must be a valid index into the constant_pool table.
|
||
|
* The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure
|
||
|
* representing the return descriptor (§4.3.3) of the type that is reified by the class
|
||
|
* represented by this element_value structure.
|
||
|
*
|
||
|
* For example, 'V' for Void.class, 'Ljava/lang/Object;' for Object, etc.
|
||
|
*
|
||
|
* Or in plain english, you can store type information in annotations. Yay.
|
||
|
*/
|
||
|
uint16_t classIndex;
|
||
|
public:
|
||
|
element_value_class(element_value_type type, uint16_t classIndex, constant_pool& pool):
|
||
|
element_value(type, pool), classIndex(classIndex)
|
||
|
{
|
||
|
// TODO: verify consistency
|
||
|
}
|
||
|
uint16_t getIndex()
|
||
|
{
|
||
|
return classIndex;
|
||
|
}
|
||
|
virtual std::string toString()
|
||
|
{
|
||
|
return "class";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/// nested annotations... yay
|
||
|
class element_value_annotation : public element_value
|
||
|
{
|
||
|
private:
|
||
|
annotation * nestedAnnotation;
|
||
|
public:
|
||
|
element_value_annotation(element_value_type type, annotation * nestedAnnotation, constant_pool& pool):
|
||
|
element_value(type, pool), nestedAnnotation(nestedAnnotation)
|
||
|
{};
|
||
|
~element_value_annotation()
|
||
|
{
|
||
|
if(nestedAnnotation)
|
||
|
{
|
||
|
delete nestedAnnotation;
|
||
|
nestedAnnotation = nullptr;
|
||
|
}
|
||
|
}
|
||
|
virtual std::string toString()
|
||
|
{
|
||
|
return "nested annotation";
|
||
|
};
|
||
|
};
|
||
|
|
||
|
/// and arrays!
|
||
|
class element_value_array : public element_value
|
||
|
{
|
||
|
public:
|
||
|
typedef std::vector <element_value *> elem_vec;
|
||
|
protected:
|
||
|
elem_vec values;
|
||
|
public:
|
||
|
element_value_array ( element_value_type type, std::vector <element_value *>& values, constant_pool& pool ):
|
||
|
element_value(type, pool), values(values)
|
||
|
{};
|
||
|
~element_value_array ()
|
||
|
{
|
||
|
for(unsigned i = 0; i < values.size();i++)
|
||
|
{
|
||
|
delete values[i];
|
||
|
}
|
||
|
};
|
||
|
elem_vec::const_iterator begin()
|
||
|
{
|
||
|
return values.cbegin();
|
||
|
}
|
||
|
elem_vec::const_iterator end()
|
||
|
{
|
||
|
return values.cend();
|
||
|
}
|
||
|
virtual std::string toString()
|
||
|
{
|
||
|
return "array";
|
||
|
};
|
||
|
};
|
||
|
}
|