1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
9 #include <anna/core/functions.hpp>
10 #include <anna/core/util/Variable.hpp>
15 anna_assign_enum(Variable::Type) = {
16 "Unused0", "String", "Integer", "Unused1", "Boolean", "Integer64", "Block", "Float", "Double", "Custom", NULL
19 Variable::Variable(const char* name, const Type::_v type) :
24 anna_memset(&a_value, 0, sizeof(a_value));
27 case Type::String: a_value.a_string = new std::string; break;
28 case Type::Integer: a_value.a_integer = &a_aux.integer; break;
29 case Type::Integer64: a_value.a_longInteger = &a_aux.longInteger; break;
30 case Type::Boolean: a_value.a_boolean = &a_aux.boolean; break;
31 case Type::Block: a_value.a_dataBlock = new DataBlock(true); break;
32 case Type::Float: a_value.a_float = &a_aux.theFloat; break;
33 case Type::Double: a_value.a_double = &a_aux.theDouble; break;
34 case Type::Custom: a_value.a_custom = NULL; break;
39 Variable::~Variable() {
40 if(a_isOwner == false)
45 delete a_value.a_string;
46 a_value.a_string = NULL;
49 delete a_value.a_dataBlock;
50 a_value.a_dataBlock = NULL;
56 void Variable::setValue(const char* value)
57 throw(RuntimeException) {
58 verifyMatchType(Type::String, ANNA_FILE_LOCATION);
60 *a_value.a_string = value;
63 void Variable::setValue(const int value)
64 throw(RuntimeException) {
65 verifyMatchType(Type::Integer, ANNA_FILE_LOCATION);
67 *a_value.a_integer = value;
70 void Variable::setValue(const S64 value)
71 throw(RuntimeException) {
72 verifyMatchType(Type::Integer64, ANNA_FILE_LOCATION);
74 *a_value.a_longInteger = value;
77 void Variable::setValue(const bool value)
78 throw(RuntimeException) {
79 verifyMatchType(Type::Boolean, ANNA_FILE_LOCATION);
81 *a_value.a_boolean = value;
84 void Variable::setValue(const DataBlock& value)
85 throw(RuntimeException) {
86 verifyMatchType(Type::Block, ANNA_FILE_LOCATION);
88 if(a_value.a_dataBlock->deepCopy() == false) {
89 string msg("Variable: ");
91 msg += " | Datablock requires deep copy";
92 throw RuntimeException(msg, ANNA_FILE_LOCATION);
96 *a_value.a_dataBlock = value;
99 void Variable::setValue(const float value)
100 throw(RuntimeException) {
101 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
103 if(a_type == Type::Float) {
105 *a_value.a_float = value;
106 } else if(a_type == Type::Double) {
108 *a_value.a_double = value;
112 void Variable::setValue(const double value)
113 throw(RuntimeException) {
114 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
116 if(a_type == Type::Float) {
118 *a_value.a_float = value;
119 } else if(a_type == Type::Double) {
121 *a_value.a_double = value;
125 const char* Variable::getStringValue() const
126 throw(RuntimeException) {
127 verifyIsNotNull(ANNA_FILE_LOCATION);
128 verifyMatchType(Type::String, ANNA_FILE_LOCATION);
129 return a_value.a_string->c_str();
132 int Variable::getIntegerValue() const
133 throw(RuntimeException) {
134 verifyIsNotNull(ANNA_FILE_LOCATION);
135 verifyMatchType(Type::Integer, ANNA_FILE_LOCATION);
136 return *a_value.a_integer;
139 S64 Variable::getInteger64Value() const
140 throw(RuntimeException) {
142 verifyIsNotNull(ANNA_FILE_LOCATION);
143 verifyMatchSomeType(Type::Integer, Type::Integer64, ANNA_FILE_LOCATION);
146 case Type::Integer: result = *a_value.a_integer; break;
147 case Type::Integer64: result = *a_value.a_longInteger; break;
154 bool Variable::getBooleanValue() const
155 throw(RuntimeException) {
156 verifyIsNotNull(ANNA_FILE_LOCATION);
157 verifyMatchType(Type::Boolean, ANNA_FILE_LOCATION);
158 return *a_value.a_boolean;
161 const DataBlock& Variable::getDataBlockValue() const
162 throw(RuntimeException) {
163 verifyIsNotNull(ANNA_FILE_LOCATION);
164 verifyMatchType(Type::Block, ANNA_FILE_LOCATION);
165 return *a_value.a_dataBlock;
168 float Variable::getFloatValue() const
169 throw(RuntimeException) {
171 verifyIsNotNull(ANNA_FILE_LOCATION);
172 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
175 case Type::Float: result = *a_value.a_float; break;
176 case Type::Double: result = (float) *a_value.a_double; break;
183 double Variable::getDoubleValue() const
184 throw(RuntimeException) {
186 verifyIsNotNull(ANNA_FILE_LOCATION);
187 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
190 case Type::Float: result = (double) *a_value.a_float; break;
191 case Type::Double: result = *a_value.a_double; break;
198 String Variable::asString() const
200 String result("anna::Variable { Name: ");
202 result << " | Type: " << Type::asNotNullCString(a_type);
203 result += " | Value: ";
209 case Type::String: result += a_value.a_string->c_str(); break;
210 case Type::Integer: result += functions::asString(*a_value.a_integer); break;
211 case Type::Integer64: result += functions::asString(*a_value.a_longInteger); break;
212 case Type::Boolean: result += functions::asString(*a_value.a_boolean); break;
213 case Type::Block: result += functions::asString(*a_value.a_dataBlock); break;
214 case Type::Float: result += functions::asString("%f", *a_value.a_float); break;
215 case Type::Double: result += functions::asString("%g", *a_value.a_double); break;
216 case Type::Custom: result += functions::asHexString(anna_ptrnumber_cast(a_value.a_custom)); break;
221 return result += " }";
224 void* Variable::buffer() const
229 case Type::String: result = const_cast <char*>(a_value.a_string->data()); break;
230 case Type::Integer: result = a_value.a_integer; break;
231 case Type::Integer64: result = a_value.a_longInteger; break;
232 case Type::Boolean: result = a_value.a_boolean; break;
233 case Type::Block: result = const_cast <char*>(a_value.a_dataBlock->getData()); break;
234 case Type::Float: result = a_value.a_float; break;
235 case Type::Double: result = a_value.a_double; break;
236 case Type::Custom: result = a_value.a_custom; break;
243 void* Variable::getReference() const
248 case Type::String: result = a_value.a_string; break;
249 case Type::Integer: result = a_value.a_integer; break;
250 case Type::Integer64: result = a_value.a_longInteger; break;
251 case Type::Boolean: result = a_value.a_boolean; break;
252 case Type::Block: result = a_value.a_dataBlock; break;
253 case Type::Float: result = a_value.a_float; break;
254 case Type::Double: result = a_value.a_double; break;
255 case Type::Custom: result = a_value.a_custom; break;
262 void Variable::verifyMatchType(const Type::_v type, const char* file, const int lineno) const
263 throw(RuntimeException) {
265 String msg("Variable: ");
266 msg << a_name << " | " << Type::asNotNullCString(type) << " mismatch data type";
267 throw RuntimeException(msg, file, lineno);
271 void Variable::verifyMatchSomeType(const Type::_v firstType, const Type::_v secondType, const char* file, const int lineno) const
272 throw(RuntimeException) {
273 if(a_type != firstType && a_type != secondType) {
274 String msg("Variable: ");
275 msg << a_name << " | Neihter " << Type::asNotNullCString(firstType);
276 msg << " nor " << Type::asNotNullCString(secondType) << " matches with data type";
277 throw RuntimeException(msg, file, lineno);
281 void Variable::verifyIsNotNull(const char* file, const int lineno) const
282 throw(RuntimeException) {
283 if(a_isNull == true) {
284 String msg("Variable: ");
285 msg << a_name << " | Variable does not have assigned value";
286 throw RuntimeException(msg, file, lineno);