summaryrefslogtreecommitdiffstats
path: root/java/annotations.cpp
blob: fc0c98fa7dae96fddd46cdb74a9ae98697e7e853 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "classfile.h"
#include "annotations.h"
#include <sstream>

namespace java
{
	std::string annotation::toString()
	{
		std::ostringstream ss;
		ss << "Annotation type : " << type_index << " - " << pool[type_index].str_data << std::endl;
		ss << "Contains " << name_val_pairs.size() << " pairs:" << std::endl;
		for(unsigned i = 0; i < name_val_pairs.size(); i++)
		{
			std::pair<uint16_t, element_value *> &val = name_val_pairs[i];
			auto name_idx = val.first;
			ss << pool[name_idx].str_data << "(" << name_idx << ")" << " = " << val.second->toString() << std::endl;
		}
		return ss.str();
	}

	annotation * annotation::read (util::membuffer& input, constant_pool& pool)
	{
		uint16_t type_index = 0;
		input.read_be(type_index);
		annotation * ann = new annotation(type_index,pool);
		
		uint16_t num_pairs = 0;
		input.read_be(num_pairs);
		while(num_pairs)
		{
			uint16_t name_idx = 0;
			// read name index
			input.read_be(name_idx);
			auto elem = element_value::readElementValue(input,pool);
			// read value
			ann->add_pair(name_idx, elem);
			num_pairs --;
		}
		return ann;
	}
	
	element_value* element_value::readElementValue ( util::membuffer& input, java::constant_pool& pool )
	{
		element_value_type type = INVALID;
		input.read(type);
		uint16_t index = 0;
		uint16_t index2 = 0;
		std::vector <element_value *> vals;
		switch (type)
		{
		case PRIMITIVE_BYTE:
		case PRIMITIVE_CHAR:
		case PRIMITIVE_DOUBLE:
		case PRIMITIVE_FLOAT:
		case PRIMITIVE_INT:
		case PRIMITIVE_LONG:
		case PRIMITIVE_SHORT:
		case PRIMITIVE_BOOLEAN:
		case STRING:
			input.read_be(index);
			return new element_value_simple(type, index, pool);
		case ENUM_CONSTANT:
			input.read_be(index);
			input.read_be(index2);
			return new element_value_enum(type, index, index2, pool);
		case CLASS: // Class
			input.read_be(index);
			return new element_value_class(type, index, pool);
		case ANNOTATION: // Annotation
			// FIXME: runtime visibility info needs to be passed from parent
			return new element_value_annotation(ANNOTATION, annotation::read(input, pool), pool);
		case ARRAY: // Array
			input.read_be(index);
			for (int i = 0; i < index; i++)
			{
				vals.push_back(element_value::readElementValue(input, pool));
			}
			return new element_value_array(ARRAY, vals, pool);
		default:
			throw new java::classfile_exception();
		}
	}
}