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;
66 Variable::~Variable() {
67 if(a_isOwner == false)
72 delete a_value.a_string;
73 a_value.a_string = NULL;
76 delete a_value.a_dataBlock;
77 a_value.a_dataBlock = NULL;
82 void Variable::setValue(const char* value)
83 throw(RuntimeException) {
84 verifyMatchType(Type::String, ANNA_FILE_LOCATION);
86 *a_value.a_string = value;
89 void Variable::setValue(const int value)
90 throw(RuntimeException) {
91 verifyMatchType(Type::Integer, ANNA_FILE_LOCATION);
93 *a_value.a_integer = value;
96 void Variable::setValue(const S64 value)
97 throw(RuntimeException) {
98 verifyMatchType(Type::Integer64, ANNA_FILE_LOCATION);
100 *a_value.a_longInteger = value;
103 void Variable::setValue(const bool value)
104 throw(RuntimeException) {
105 verifyMatchType(Type::Boolean, ANNA_FILE_LOCATION);
107 *a_value.a_boolean = value;
110 void Variable::setValue(const DataBlock& value)
111 throw(RuntimeException) {
112 verifyMatchType(Type::Block, ANNA_FILE_LOCATION);
114 if(a_value.a_dataBlock->deepCopy() == false) {
115 string msg("Variable: ");
117 msg += " | Datablock requires deep copy";
118 throw RuntimeException(msg, ANNA_FILE_LOCATION);
122 *a_value.a_dataBlock = value;
125 void Variable::setValue(const float value)
126 throw(RuntimeException) {
127 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
129 if(a_type == Type::Float) {
131 *a_value.a_float = value;
132 } else if(a_type == Type::Double) {
134 *a_value.a_double = value;
138 void Variable::setValue(const double value)
139 throw(RuntimeException) {
140 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
142 if(a_type == Type::Float) {
144 *a_value.a_float = value;
145 } else if(a_type == Type::Double) {
147 *a_value.a_double = value;
151 const char* Variable::getStringValue() const
152 throw(RuntimeException) {
153 verifyIsNotNull(ANNA_FILE_LOCATION);
154 verifyMatchType(Type::String, ANNA_FILE_LOCATION);
155 return a_value.a_string->c_str();
158 int Variable::getIntegerValue() const
159 throw(RuntimeException) {
160 verifyIsNotNull(ANNA_FILE_LOCATION);
161 verifyMatchType(Type::Integer, ANNA_FILE_LOCATION);
162 return *a_value.a_integer;
165 S64 Variable::getInteger64Value() const
166 throw(RuntimeException) {
168 verifyIsNotNull(ANNA_FILE_LOCATION);
169 verifyMatchSomeType(Type::Integer, Type::Integer64, ANNA_FILE_LOCATION);
172 case Type::Integer: result = *a_value.a_integer; break;
173 case Type::Integer64: result = *a_value.a_longInteger; break;
179 bool Variable::getBooleanValue() const
180 throw(RuntimeException) {
181 verifyIsNotNull(ANNA_FILE_LOCATION);
182 verifyMatchType(Type::Boolean, ANNA_FILE_LOCATION);
183 return *a_value.a_boolean;
186 const DataBlock& Variable::getDataBlockValue() const
187 throw(RuntimeException) {
188 verifyIsNotNull(ANNA_FILE_LOCATION);
189 verifyMatchType(Type::Block, ANNA_FILE_LOCATION);
190 return *a_value.a_dataBlock;
193 float Variable::getFloatValue() const
194 throw(RuntimeException) {
196 verifyIsNotNull(ANNA_FILE_LOCATION);
197 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
200 case Type::Float: result = *a_value.a_float; break;
201 case Type::Double: result = (float) *a_value.a_double; break;
207 double Variable::getDoubleValue() const
208 throw(RuntimeException) {
210 verifyIsNotNull(ANNA_FILE_LOCATION);
211 verifyMatchSomeType(Type::Float, Type::Double, ANNA_FILE_LOCATION);
214 case Type::Float: result = (double) *a_value.a_float; break;
215 case Type::Double: result = *a_value.a_double; break;
221 String Variable::asString() const
223 String result("anna::Variable { Name: ");
225 result << " | Type: " << Type::asNotNullCString(a_type);
226 result += " | Value: ";
232 case Type::String: result += a_value.a_string->c_str(); break;
233 case Type::Integer: result += functions::asString(*a_value.a_integer); break;
234 case Type::Integer64: result += functions::asString(*a_value.a_longInteger); break;
235 case Type::Boolean: result += functions::asString(*a_value.a_boolean); break;
236 case Type::Block: result += functions::asString(*a_value.a_dataBlock); break;
237 case Type::Float: result += functions::asString("%f", *a_value.a_float); break;
238 case Type::Double: result += functions::asString("%g", *a_value.a_double); break;
239 case Type::Custom: result += functions::asHexString(anna_ptrnumber_cast(a_value.a_custom)); break;
243 return result += " }";
246 void* Variable::buffer() const
251 case Type::String: result = const_cast <char*>(a_value.a_string->data()); break;
252 case Type::Integer: result = a_value.a_integer; break;
253 case Type::Integer64: result = a_value.a_longInteger; break;
254 case Type::Boolean: result = a_value.a_boolean; break;
255 case Type::Block: result = const_cast <char*>(a_value.a_dataBlock->getData()); break;
256 case Type::Float: result = a_value.a_float; break;
257 case Type::Double: result = a_value.a_double; break;
258 case Type::Custom: result = a_value.a_custom; break;
264 void* Variable::getReference() const
269 case Type::String: result = a_value.a_string; break;
270 case Type::Integer: result = a_value.a_integer; break;
271 case Type::Integer64: result = a_value.a_longInteger; break;
272 case Type::Boolean: result = a_value.a_boolean; break;
273 case Type::Block: result = a_value.a_dataBlock; break;
274 case Type::Float: result = a_value.a_float; break;
275 case Type::Double: result = a_value.a_double; break;
276 case Type::Custom: result = a_value.a_custom; break;
282 void Variable::verifyMatchType(const Type::_v type, const char* file, const int lineno) const
283 throw(RuntimeException) {
285 String msg("Variable: ");
286 msg << a_name << " | " << Type::asNotNullCString(type) << " mismatch data type";
287 throw RuntimeException(msg, file, lineno);
291 void Variable::verifyMatchSomeType(const Type::_v firstType, const Type::_v secondType, const char* file, const int lineno) const
292 throw(RuntimeException) {
293 if(a_type != firstType && a_type != secondType) {
294 String msg("Variable: ");
295 msg << a_name << " | Neihter " << Type::asNotNullCString(firstType);
296 msg << " nor " << Type::asNotNullCString(secondType) << " matches with data type";
297 throw RuntimeException(msg, file, lineno);
301 void Variable::verifyIsNotNull(const char* file, const int lineno) const
302 throw(RuntimeException) {
303 if(a_isNull == true) {
304 String msg("Variable: ");
305 msg << a_name << " | Variable does not have assigned value";
306 throw RuntimeException(msg, file, lineno);