forked from falltergeist/int2ssl
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathOpcode.cpp
157 lines (129 loc) · 3.75 KB
/
Opcode.cpp
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
/**
*
* Copyright (c) 2005-2009 Anchorite (TeamX), <[email protected]>
* Copyright (c) 2014-2015 Nirran, phobos2077
* Copyright (c) 2015 alexeevdv <[email protected]>
* Distributed under the GNU GPL v3. For full terms see the file license.txt
*
*/
// C++ standard includes
#include <iostream>
#include <fstream>
#include <algorithm>
// int2ssl includes
#include "Opcode.h"
#include "Utility.h"
// Third party includes
extern int g_nFalloutVersion;
extern std::ifstream g_ifstream;
COpcode::COpcode() :
m_wOperator(O_NOOP),
m_ulArgument(0)
{
}
COpcode::COpcode(const COpcode& opcode) :
m_wOperator(opcode.m_wOperator),
m_ulArgument(opcode.m_ulArgument)
{
}
COpcode::~COpcode()
{
}
COpcode& COpcode::operator = (const COpcode& opcode)
{
m_wOperator = opcode.m_wOperator;
m_ulArgument = opcode.m_ulArgument;
return (*this);
}
void COpcode::Serialize()
{
g_ifstream.read((char*)&m_wOperator, sizeof(m_wOperator));
std::reverse((char*)&m_wOperator, (char*)&m_wOperator + sizeof(m_wOperator));
if (!g_ifstream)
{
printf("Error: Unable read opcode\n");
throw std::exception();
}
if ((m_wOperator < O_OPERATOR) ||
((m_wOperator >= O_END_OP) &&
(m_wOperator != O_STRINGOP) &&
(m_wOperator != O_FLOATOP)&&
(m_wOperator != O_INTOP)))
{
printf("Error: Invalid opcode at 0x%08x\n", (uint32_t)g_ifstream.tellg() - 2);
throw std::exception();
}
if ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP))
{
g_ifstream.read((char*)&m_ulArgument, sizeof(m_ulArgument));
std::reverse((char*)&m_ulArgument, (char*)&m_ulArgument + sizeof(m_ulArgument));
if (!g_ifstream)
{
std::cout << "Error: Unable read opcode argument" << std::endl;
throw std::exception();
}
}
}
void COpcode::Expect(uint16_t wOperator, bool bArgumentFound, uint32_t ulArgument)
{
Serialize();
if (m_wOperator != wOperator)
{
printf("Error: Unexpected opcode (0x%04X expected, but 0x%04X found)\n", wOperator, m_wOperator);
throw std::exception();
}
if (bArgumentFound && ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP)))
{
if (m_ulArgument != ulArgument)
{
printf("Error: Unexpected argument of opcode. (0x%08X expected, but 0x%08X found)\n", ulArgument, m_ulArgument);
throw std::exception();
}
}
}
bool COpcode::HasArgument() const
{
return ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP));
}
int COpcode::GetSize() const
{
if ((m_wOperator == O_STRINGOP) || (m_wOperator == O_FLOATOP) || (m_wOperator == O_INTOP))
{
return OPERATOR_SIZE + ARGUMENT_SIZE;
}
else
{
return OPERATOR_SIZE;
}
}
uint16_t COpcode::GetOperator() const
{
return m_wOperator;
}
void COpcode::SetOperator(uint16_t op)
{
m_wOperator = op;
}
uint32_t COpcode::GetArgument() const
{
return m_ulArgument;
}
const COpcode::COpcodeAttributes COpcode::GetAttributes() const
{
static CF1OpcodeAttributesMap f1OpcodeAttributes;
static CF2OpcodeAttributesMap f2OpcodeAttributes;
COpcodeAttributes result;
if (g_nFalloutVersion == 1)
{
if (f1OpcodeAttributes.Lookup(m_wOperator, result))
{
return result;
}
}
if (!f2OpcodeAttributes.Lookup(m_wOperator, result))
{
printf("Error: Attempt to obtain attributes of unknown opcode\n");
throw std::exception();
}
return result;
}