aboutsummaryrefslogtreecommitdiff
path: root/core/objects.h
blob: 0c5a269ab50c3672fb1b23fcb519d81bac3fb806 (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
 * Support of object hierarchy.
 */

#ifndef OBJECTS_H
#define OBJECTS_H

std::string string_format(const char *format, ...);

// TODO: find more appropriate place for {
enum OperandSize : uint8_t {
	osByte,
	osWord,
	osDWord,
	osQWord,
	osTByte,
	osOWord,
	osXMMWord,
	osYMMWord,
	osFWord,
	osDefault = 0xff
};

enum MessageType {
	mtInformation,
	mtWarning,
	mtError,
	mtAdded,
	mtChanged,
	mtDeleted,
	mtScript,
};
// }

class IObject
{
public:
	virtual ~IObject() {}
	virtual int CompareWith(const IObject &) const { throw std::runtime_error("Abstract method"); }
};

class AddressableObject : public IObject
{
public:
	AddressableObject() : address_(0) {}
	AddressableObject(const AddressableObject &src) : address_(src.address_) {}
	AddressableObject &operator=(const AddressableObject &src) { address_ = src.address_; return *this; }

	using IObject::CompareWith;
	int CompareWith(const AddressableObject &other) const;
	uint64_t address() const { return address_; }
	void set_address(uint64_t address) { address_ = address; } 

protected:
	uint64_t address_;
};

template <typename Object>
class ObjectList : public IObject
{
	//not implemented
	ObjectList &operator=(const ObjectList &);
public:
	explicit ObjectList() : IObject() {}
	explicit ObjectList(const ObjectList &src) : IObject(src) {}
	virtual ~ObjectList() { clear(); }
	virtual void clear()
	{
		while (!v_.empty()) {
			delete v_.back();
		}
	}
	void Delete(size_t index)
	{
		if (index >= v_.size())
			throw std::runtime_error("subscript out of range");
		delete v_[index]; 
	}
	size_t count() const { return v_.size(); }
	Object *item(size_t index) const
	{ 
		if (index >= v_.size())
			throw std::runtime_error("subscript out of range");
		return v_[index]; 
	}
	void resize(size_t size) {
		v_.resize(size);
	}
	Object *last() const { return v_.empty() ? NULL : *v_.rbegin(); }
	static bool CompareObjects(const Object *obj1, const Object *obj2) { return obj1->CompareWith(*obj2) < 0; }
	void Sort() { std::sort(v_.begin(), v_.end(), CompareObjects); }
	typedef typename std::vector<Object*>::const_iterator const_iterator;
	typedef typename std::vector<Object*>::iterator iterator;
	size_t IndexOf(const Object *obj) const
	{
		const_iterator it = std::find(v_.begin(), v_.end(), obj);
		return (it == v_.end()) ? -1 : it - v_.begin();
	}

	size_t IndexOf(const Object *obj, size_t index) const
	{
		const_iterator it = std::find((v_.begin()+index), v_.end(), obj);
		return (it == v_.end()) ? -1 : it - v_.begin();
	}
	void SwapObjects(size_t i, size_t j) { std::swap(v_[i], v_[j]); }
	virtual void AddObject(Object *obj) { v_.push_back(obj); }
	virtual void InsertObject(size_t index, Object *obj) { v_.insert(v_.begin() + index, obj); }
	virtual void RemoveObject(Object *obj)
	{ 
		for (size_t i = count(); i > 0; i--) {
			if (item(i - 1) == obj) {
				erase(i - 1);
				break;
			}
		}
	}
	void erase(size_t index) { v_.erase(v_.begin() + index); }
	void assign(const std::list<Object*> &src) 
	{ 
		v_.clear(); 
		for (typename std::list<Object*>::const_iterator it = src.begin(); it != src.end(); it++) {
			v_.push_back(*it);
		}
	}

	const_iterator begin() const { return v_.begin(); }
	const_iterator end() const { return v_.end(); }

	iterator _begin() { return v_.begin(); }
	iterator _end() { return v_.end(); }

protected:
	void Reserve(size_t count) { v_.reserve(count); }
	std::vector<Object*> v_;
};

class Data
{
public:
	Data() {}
	Data(const std::vector<uint8_t> &src) { m_vData = src; }
	void PushByte(uint8_t value)   { m_vData.push_back(value);	}
	void PushDWord(uint32_t value) { PushBuff(&value, sizeof(value)); }
	void PushQWord(uint64_t value) { PushBuff(&value, sizeof(value)); }
	void PushWord(uint16_t value) { PushBuff(&value, sizeof(value)); }
	void PushBuff(const void *value, size_t nCount)	{ m_vData.insert(m_vData.end(), reinterpret_cast<const uint8_t *>(value), reinterpret_cast<const uint8_t *>(value) + nCount); }
	void InsertByte(size_t pos, uint8_t value) { m_vData.insert(m_vData.begin() + pos, value); }
	void InsertBuff(size_t pos, const void *buff, size_t nCount) { m_vData.insert(m_vData.begin() + pos, reinterpret_cast<const uint8_t *>(buff), reinterpret_cast<const uint8_t *>(buff) + nCount); }
	uint32_t ReadDWord(size_t nPosition) const { return *reinterpret_cast<const uint32_t *>(&m_vData[nPosition]); }
	void WriteDWord(size_t nPosition, uint32_t dwValue) { *reinterpret_cast<uint32_t *>(&m_vData[nPosition]) = dwValue; }
	size_t size() const { return m_vData.size(); }
	void clear() { m_vData.clear(); }
	bool empty() const { return m_vData.empty(); }
	void resize(size_t size) { m_vData.resize(size); }
	void resize(size_t size, uint8_t value) { m_vData.resize(size, value); }
	const uint8_t *data() const { return m_vData.data(); }
	const uint8_t &operator[](size_t pos) const
	{ 
		if (pos >= m_vData.size())
			throw std::runtime_error("subscript out of range");		
		return m_vData[pos]; 
	}
	uint8_t &operator[](size_t pos)
	{ 
		if (pos >= m_vData.size())
			throw std::runtime_error("subscript out of range");		
		return m_vData[pos]; 
	}
	bool operator < (const Data &right) const
	{
		return (size() != right.size()) ? (size() < right.size()) : (memcmp(data(), right.data(), size()) < 0);
	}
private:
	std::vector<uint8_t> m_vData;
};

class canceled_error : public std::runtime_error
{
public:
	explicit canceled_error(const std::string &message)
		: runtime_error(message) {}
};

class abort_error : public std::runtime_error
{
public:
	explicit abort_error(const std::string &message)
		: runtime_error(message) {}
};

#endif