1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #include <anna/core/functions.hpp>
38 #include <anna/core/util/Variable.hpp>
43 anna_assign_enum(Variable::Type) = {
44 "Unused0", "String", "Integer", "Unused1", "Boolean", "Integer64", "Block", "Float", "Double", "Custom", NULL
47 Variable::Variable(const char* name, const Type::_v type) :
52 anna_memset(&a_value, 0, sizeof(a_value));
55 case Type::String: a_value.a_string = new std::string; break;
56 case Type::Integer: a_value.a_integer = &a_aux.integer; break;
57 case Type::Integer64: a_value.a_longInteger = &a_aux.longInteger; break;
58 case Type::Boolean: a_value.a_boolean = &a_aux.boolean; break;
59 case Type::Block: a_value.a_dataBlock = new DataBlock(true); break;
60 case Type::Float: a_value.a_float = &a_aux.theFloat; break;
61 case Type::Double: a_value.a_double = &a_aux.theDouble; break;
62 case Type::Custom: a_value.a_custom = NULL; break;
67 Variable::~Variable() {
68 if(a_isOwner == false)
73 delete a_value.a_string;
74 a_value.a_string = NULL;
77 delete a_value.a_dataBlock;
78 a_value.a_dataBlock = NULL;
84 void Variable::setValue(const char* value)
85 throw(RuntimeException) {
86 verifyMatchType(Type::String, ANNA_FILE_LOCATION);
88 *a_value.a_string = value;
91 void Variable::setValue(const int value)
92 throw(RuntimeException) {
93 verifyMatchType(Type::Integer, ANNA_FILE_LOCATION);
95 *a_value.a_integer = value;
98 void Variable::setValue(const S64 value)
99 throw(RuntimeException) {
100 verifyMatchType(Type::Integer64, ANNA_FILE_LOCATION);
102 *a_value.a_longInteger = value;
105 void Variable::setValue(const bool value)
106 throw(RuntimeException) {
107 verifyMatchType(Type::Boolean, ANNA_FILE_LOCATION);
109 *a_value.a_boolean = value;
112 void Variable::setValue(const DataBlock& value)
113 throw(RuntimeException) {
114 verifyMatchType(Type::Block, ANNA_FILE_LOCATION);
116 if(a_value.a_dataBlock->deepCopy() == false) {
117 string msg("Variable: ");
119 msg += " | Datablock requires deep copy";
120 throw RuntimeException(msg, ANNA_FILE_LOCATION);
124 *a_value.a_dataBlock = value;
127 void Variable::setValue(const float value)
128 throw(RuntimeException) {
129 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
131 if(a_type == Type::Float) {
133 *a_value.a_float = value;
134 } else if(a_type == Type::Double) {
136 *a_value.a_double = value;
140 void Variable::setValue(const double value)
141 throw(RuntimeException) {
142 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
144 if(a_type == Type::Float) {
146 *a_value.a_float = value;
147 } else if(a_type == Type::Double) {
149 *a_value.a_double = value;
153 const char* Variable::getStringValue() const
154 throw(RuntimeException) {
155 verifyIsNotNull(ANNA_FILE_LOCATION);
156 verifyMatchType(Type::String, ANNA_FILE_LOCATION);
157 return a_value.a_string->c_str();
160 int Variable::getIntegerValue() const
161 throw(RuntimeException) {
162 verifyIsNotNull(ANNA_FILE_LOCATION);
163 verifyMatchType(Type::Integer, ANNA_FILE_LOCATION);
164 return *a_value.a_integer;
167 S64 Variable::getInteger64Value() const
168 throw(RuntimeException) {
170 verifyIsNotNull(ANNA_FILE_LOCATION);
171 verifyMatchSomeType(Type::Integer, Type::Integer64, ANNA_FILE_LOCATION);
174 case Type::Integer: result = *a_value.a_integer; break;
175 case Type::Integer64: result = *a_value.a_longInteger; break;
182 bool Variable::getBooleanValue() const
183 throw(RuntimeException) {
184 verifyIsNotNull(ANNA_FILE_LOCATION);
185 verifyMatchType(Type::Boolean, ANNA_FILE_LOCATION);
186 return *a_value.a_boolean;
189 const DataBlock& Variable::getDataBlockValue() const
190 throw(RuntimeException) {
191 verifyIsNotNull(ANNA_FILE_LOCATION);
192 verifyMatchType(Type::Block, ANNA_FILE_LOCATION);
193 return *a_value.a_dataBlock;
196 float Variable::getFloatValue() const
197 throw(RuntimeException) {
199 verifyIsNotNull(ANNA_FILE_LOCATION);
200 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
203 case Type::Float: result = *a_value.a_float; break;
204 case Type::Double: result = (float) *a_value.a_double; break;
211 double Variable::getDoubleValue() const
212 throw(RuntimeException) {
214 verifyIsNotNull(ANNA_FILE_LOCATION);
215 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
218 case Type::Float: result = (double) *a_value.a_float; break;
219 case Type::Double: result = *a_value.a_double; break;
226 String Variable::asString() const
228 String result("anna::Variable { Name: ");
230 result << " | Type: " << Type::asNotNullCString(a_type);
231 result += " | Value: ";
237 case Type::String: result += a_value.a_string->c_str(); break;
238 case Type::Integer: result += functions::asString(*a_value.a_integer); break;
239 case Type::Integer64: result += functions::asString(*a_value.a_longInteger); break;
240 case Type::Boolean: result += functions::asString(*a_value.a_boolean); break;
241 case Type::Block: result += functions::asString(*a_value.a_dataBlock); break;
242 case Type::Float: result += functions::asString("%f", *a_value.a_float); break;
243 case Type::Double: result += functions::asString("%g", *a_value.a_double); break;
244 case Type::Custom: result += functions::asHexString(anna_ptrnumber_cast(a_value.a_custom)); break;
249 return result += " }";
252 void* Variable::buffer() const
257 case Type::String: result = const_cast <char*>(a_value.a_string->data()); break;
258 case Type::Integer: result = a_value.a_integer; break;
259 case Type::Integer64: result = a_value.a_longInteger; break;
260 case Type::Boolean: result = a_value.a_boolean; break;
261 case Type::Block: result = const_cast <char*>(a_value.a_dataBlock->getData()); break;
262 case Type::Float: result = a_value.a_float; break;
263 case Type::Double: result = a_value.a_double; break;
264 case Type::Custom: result = a_value.a_custom; break;
271 void* Variable::getReference() const
276 case Type::String: result = a_value.a_string; break;
277 case Type::Integer: result = a_value.a_integer; break;
278 case Type::Integer64: result = a_value.a_longInteger; break;
279 case Type::Boolean: result = a_value.a_boolean; break;
280 case Type::Block: result = a_value.a_dataBlock; break;
281 case Type::Float: result = a_value.a_float; break;
282 case Type::Double: result = a_value.a_double; break;
283 case Type::Custom: result = a_value.a_custom; break;
290 void Variable::verifyMatchType(const Type::_v type, const char* file, const int lineno) const
291 throw(RuntimeException) {
293 String msg("Variable: ");
294 msg << a_name << " | " << Type::asNotNullCString(type) << " mismatch data type";
295 throw RuntimeException(msg, file, lineno);
299 void Variable::verifyMatchSomeType(const Type::_v firstType, const Type::_v secondType, const char* file, const int lineno) const
300 throw(RuntimeException) {
301 if(a_type != firstType && a_type != secondType) {
302 String msg("Variable: ");
303 msg << a_name << " | Neihter " << Type::asNotNullCString(firstType);
304 msg << " nor " << Type::asNotNullCString(secondType) << " matches with data type";
305 throw RuntimeException(msg, file, lineno);
309 void Variable::verifyIsNotNull(const char* file, const int lineno) const
310 throw(RuntimeException) {
311 if(a_isNull == true) {
312 String msg("Variable: ");
313 msg << a_name << " | Variable does not have assigned value";
314 throw RuntimeException(msg, file, lineno);