bug in RC
[anna.git] / include / anna / core / util / Variable.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 #ifndef anna_core_util_Variable_hpp
10 #define anna_core_util_Variable_hpp
11
12 #include <anna/core/util/defines.hpp>
13 #include <anna/core/RuntimeException.hpp>
14 #include <anna/core/define.autoenum.hpp>
15 #include <anna/core/util/String.hpp>
16 #include <anna/core/DataBlock.hpp>
17
18 namespace anna {
19
20 /**
21    Recubrimiento de variables de usuario.
22
23    Establece un recubrimiento sobre los tipos de variables soportados por el nucleo
24 */
25 class Variable {
26 public:
27   /**
28      Enumeracion con los tipos de datos que podemos asociar a un mensaje interno.
29   */
30   struct Type {
31     enum _v {
32       None = -1,
33       Unused0,
34       String, /**< Cadena de type std::string. */
35       Integer, /**< Numero entero de type int. */
36       Unused1,
37       Integer64, /**< Numero entero de tipo enterno de 64 bits */
38       Boolean = 5, /**< Dato de tipo bool. */
39       Block = 6, /**< Objeto de tipo DataBlock. */
40       Float, /**< Número en coma flotante de 32 bits */
41       Double, /**< Número en coma flotante de 64 bits */
42       Custom /** Tipo particular definido por el usuario */
43     };
44     anna_declare_enum(Type)
45   };
46
47   // Constructores
48   /**
49      Constructor para inicializar una instancia de tipo cadena.
50
51     @param name Nombre logico que recibe este variable.
52     @param value Referencia a la variable que estamos recubriendo con esta instancia.
53   */
54   Variable(const char* name, std::string& value) :
55     a_name(name),
56     a_isNull(false),
57     a_type(Type::String),
58     a_isOwner(false) {
59     a_value.a_string = &value;
60   }
61
62
63   /**
64   * Constructor para inicializar una instancia de type entero.
65   *
66   * @param name Nombre logico que recibe este variable.
67   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
68   */
69   Variable(const char* name, int& value) :
70     a_name(name),
71     a_isNull(false),
72     a_type(Type::Integer),
73     a_isOwner(false) {
74     value = 0;
75     a_value.a_integer = &value;
76   }
77
78   /**
79   * Constructor para inicializar una instancia de type long.
80   *
81   * @param name Nombre logico que recibe este variable.
82   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
83   */
84   Variable(const char* name, S64& value) :
85     a_name(name),
86     a_isNull(false),
87     a_type(Type::Integer64),
88     a_isOwner(false) {
89     value = 0;
90     a_value.a_longInteger = &value;
91   }
92
93   /**
94   * Constructor para inicializar una instancia de type BOOLEAN.
95   *
96   * @param name Nombre logico que recibe este variable.
97   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
98   */
99   Variable(const char* name, bool& value) :
100     a_name(name),
101     a_isNull(false),
102     a_type(Type::Boolean),
103     a_isOwner(false) {
104     value = false;
105     a_value.a_boolean = &value;
106   }
107
108   /**
109   * Constructor para inicializar una instancia de type BLOQUE_MEMORIA.
110   *
111   * @param name Nombre logico que recibe este variable.
112   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
113   */
114   Variable(const char* name, DataBlock& value) :
115     a_name(name),
116     a_isNull(false),
117     a_type(Type::Block),
118     a_isOwner(false) {
119     a_value.a_dataBlock = &value;
120   }
121
122   /**
123   * Constructor para inicializar una instancia de type float.
124   *
125   * @param name Nombre logico que recibe este variable.
126   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
127   */
128   Variable(const char* name, float& value) :
129     a_name(name),
130     a_isNull(false),
131     a_type(Type::Float),
132     a_isOwner(false) {
133     value = 0;
134     a_value.a_float = &value;
135   }
136
137   /**
138   * Constructor para inicializar una instancia de type double.
139   *
140   * @param name Nombre logico que recibe este variable.
141   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
142   */
143   Variable(const char* name, double& value) :
144     a_name(name),
145     a_isNull(false),
146     a_type(Type::Double),
147     a_isOwner(false) {
148     value = 0;
149     a_value.a_double = &value;
150   }
151
152   /**
153   * Constructor para inicializar una instancia de un tipo definido por el usuario.
154   *
155   * @param name Nombre logico que recibe este variable.
156   * @param value Referencia a la variable que estamos recubriendo con esta instancia.
157   */
158   Variable(const char* name, void* value) :
159     a_name(name),
160     a_isNull(false),
161     a_type(Type::Custom),
162     a_isOwner(false) {
163     a_value.a_custom = value;
164   }
165
166   /**
167      Constructor.
168      @param name Nombre logico que recibe esta variable.
169      @param type Tipo de dato de esta variable.
170   */
171   Variable(const char* name, const Type::_v type);
172
173   /**
174      Destructor
175   */
176   virtual ~Variable();
177
178   // Accesores
179   /**
180      Devuelve el tipo del dato al que recubre esta variable.
181      @return El tipo del dato al que recubre esta variable.
182   */
183   Type::_v getType() const throw() { return a_type; }
184
185   /**
186      Devuelve el nombre logico asociado a esta variable.
187      \return Nombre logico asociado a esta variable.
188   */
189   const char* getName() const throw() { return a_name.c_str(); }
190
191   /**
192      Devuelve \em false si esta marcado como nulo o \em true en otro caso.
193      @return \em false si esta marcado como nulo o \em true en otro caso.
194   */
195   bool isNull() const throw() { return a_isNull; }
196
197   /**
198      Devuelve el valor alfabetico asociado a esta variable.
199      @return Si la variable indicada en el contructor de esta instancia puede interpretarse como
200      una string devolvera su contenido, en otro caso lanzara una excepcion para indicar el error.
201   */
202   const char* getStringValue() const throw(RuntimeException);
203
204   /**
205      Devuelve el valor numerico asociado a esta variable.
206      @return Si la variable indicada en el contructor de esta instancia puede interpretarse como
207      un entero de 32 bits devolvera su contenido, en otro caso lanzara una excepcion para indicar el error.
208   */
209   int getIntegerValue() const throw(RuntimeException);
210
211   /**
212      Devuelve el valor numerico asociado a esta variable.
213      @return Si la variable indicada en el contructor de esta instancia puede interpretarse como
214      un entero de 64 bits devolvera su contenido, en otro caso lanzara una excepcion para indicar el error.
215   */
216   S64 getInteger64Value() const throw(RuntimeException);
217
218   /**
219      Devuelve el valor booleano asociado a esta variable.
220      @return Si la variable indicada en el contructor de esta instancia puede interpretarse como
221      un booleano y este es distinto de cero devolvera true en otro caso devolvera false.
222      indicar el error.
223   */
224   bool getBooleanValue() const throw(RuntimeException) ;
225
226   /**
227      Devuelve el bloque de memoria asociado a esta variable.
228      @return Si la variable indicada en el contructor de esta instancia era de type  DataBlock
229      devolvera el contenido de esta, en otro caso lanzara una excepcion.
230   */
231   const DataBlock& getDataBlockValue() const throw(RuntimeException) ;
232
233   /**
234      Devuelve el valor numerico asociado a esta variable.
235      @return Si la variable indicada en el contructor de esta instancia puede interpretarse como
236      un entero en coma flotante devolvera su contenido, en otro caso lanzara una excepcion para indicar el error.
237   */
238   float getFloatValue() const throw(RuntimeException);
239
240   /**
241      Devuelve el valor numerico asociado a esta variable.
242      @return Si la variable indicada en el contructor de esta instancia puede interpretarse como
243      un entero en coma flotante devolvera su contenido, en otro caso lanzara una excepcion para indicar el error.
244   */
245   double getDoubleValue() const throw(RuntimeException);
246
247   /**
248    * Devuelve el valor de un elemento definido por el usuario.
249    */
250   void* getCustom() throw(RuntimeException) {
251     verifyMatchType(Type::Custom, ANNA_FILE_LOCATION);
252     return a_value.a_custom;
253   }
254
255   /**
256    * Devuelve el valor de un elemento definido por el usuario.
257    */
258   const void* getCustom() const throw(RuntimeException) {
259     verifyMatchType(Type::Custom, ANNA_FILE_LOCATION);
260     return a_value.a_custom;
261   }
262
263   /**
264    * Devuelve el valor de un elemento definido por el usuario.
265    */
266   void setCustom(void* value) throw(RuntimeException) {
267     verifyMatchType(Type::Custom, ANNA_FILE_LOCATION);
268     a_isNull = (value == NULL);
269     a_value.a_custom = value;
270   }
271
272   /**
273      Interpreta el valor asociado a esta variable como un valor entero.
274      \warning No se realiza ninguna comprobacion semantica.
275   */
276   int getInteger() const throw() { return *a_value.a_integer; }
277
278   /**
279      Interpreta el valor asociado a esta variable como un valor entero largo.
280      \warning No se realiza ninguna comprobacion semantica.
281   */
282   S64 getInteger64() const throw() { return *a_value.a_longInteger; }
283
284   /**
285      Interpreta el valor asociado a esta variable como un valor booleano.
286      \warning No se realiza ninguna comprobacion semantica.
287   */
288   bool getBoolean() const throw() { return *a_value.a_boolean; }
289
290   /**
291      Interpreta el valor asociado a esta variable como un valor bloque de datos.
292      \warning No se realiza ninguna comprobacion semantica.
293   */
294   const DataBlock& getDataBlock() const throw() { return *a_value.a_dataBlock; }
295
296   /**
297      Interpreta el valor asociado a esta variable como un valor en coma flotante de 32 bits
298      \warning No se realiza ninguna comprobacion semantica.
299   */
300   float getFloat() const throw() { return *a_value.a_float; }
301
302   /**
303      Interpreta el valor asociado a esta variable como un valor en coma flotante de 64 bits
304      \warning No se realiza ninguna comprobacion semantica.
305   */
306   double getDouble() const throw() { return *a_value.a_double; }
307
308   // Modificadores
309   /**
310   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
311   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
312   * variable devolvera una excepcion de ejecucion indicado la anomalia.
313   *
314   * @param value Valor que tomara la variable a la que recubre este variable.
315   */
316   void setValue(const char* value) throw(RuntimeException);
317
318   /**
319   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
320   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
321   * variable devolvera una excepcion de ejecucion indicado la anomalia.
322   *
323   * @param value Valor que tomara la variable a la que recubre este variable.
324   */
325   void setCharPointer(const char* value) throw(RuntimeException);
326
327   /**
328   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
329   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
330   * variable devolvera una excepcion de ejecucion indicado la anomalia.
331   *
332   * @param value Valor que tomara la variable a la que recubre este variable.
333   */
334   void setValue(const int value) throw(RuntimeException);
335
336   /**
337   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
338   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
339   * variable devolvera una excepcion de ejecucion indicado la anomalia.
340   *
341   * @param value Valor que tomara la variable a la que recubre este variable.
342   */
343   void setValue(const S64 value) throw(RuntimeException) ;
344
345   /**
346   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
347   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
348   * variable devolvera una excepcion de ejecucion indicado la anomalia.
349   *
350   * @param value Valor que tomara la variable a la que recubre este variable.
351   */
352   void setValue(const bool value) throw(RuntimeException);
353
354   /**
355   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
356   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
357   * variable devolvera una excepcion de ejecucion indicado la anomalia.
358   *
359   * @param value Valor que tomara la variable a la que recubre este variable.
360   */
361   void setValue(const DataBlock& value) throw(RuntimeException) ;
362
363   /**
364   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
365   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
366   * variable devolvera una excepcion de ejecucion indicado la anomalia.
367   *
368   * @param value Valor que tomara la variable a la que recubre este variable.
369   */
370   void setValue(const float value) throw(RuntimeException) ;
371
372   /**
373   * Establece el valor de la variable a la que recubre. Si la variable estaba marcada como nula la desmarca.
374   * Si el type de dato que deseamos establecer no coincide con el type de dato indicado al crear esta
375   * variable devolvera una excepcion de ejecucion indicado la anomalia.
376   *
377   * @param value Valor que tomara la variable a la que recubre este variable.
378   */
379   void setValue(const double value) throw(RuntimeException) ;
380
381   /**
382      Marca/Desmarca la variable como nula.
383      @param isNull Indica la nueva marca de la variable.
384   */
385   void setNull(const bool isNull = true) throw() { a_isNull = isNull; }
386
387   /**
388      Establece el valor asociado a esta variable como un valor entero.
389      \warning No se realiza ninguna comprobacion semantica.
390   */
391   void setInteger(const int value) throw() { *a_value.a_integer = value; a_isNull = false; }
392
393   /**
394      Establece el valor asociado a esta variable como un valor entero largo.
395      \warning No se realiza ninguna comprobacion semantica.
396   */
397   void setLong(const S64 value) throw() { *a_value.a_longInteger = value; a_isNull = false; }
398
399   /**
400      Establece el valor asociado a esta variable como un valor booleano.
401      \warning No se realiza ninguna comprobacion semantica.
402   */
403   void setBoolean(const bool value) throw() { *a_value.a_boolean = value; a_isNull = false; }
404
405   /**
406      Interpreta el valor asociado a esta variable como un valor bloque de datos.
407      \warning No se realiza ninguna comprobacion semantica.
408   */
409   void setDataBlock(const DataBlock& value) throw() { *a_value.a_dataBlock = value; a_isNull = false; }
410
411   /**
412      Interpreta el valor asociado a esta variable como número en coma flotante.
413      \warning No se realiza ninguna comprobacion semantica.
414   */
415   void setFloat(const float value) throw() { *a_value.a_float = value; a_isNull = false; }
416
417   /**
418      Interpreta el valor asociado a esta variable como número en coma flotante.
419      \warning No se realiza ninguna comprobacion semantica.
420   */
421   void setDouble(const double value) throw() { *a_value.a_double = value; a_isNull = false; }
422
423   /**
424      @return \em true si la variable recibida tiene el mismo nombre que esta instancia o \em false
425      en otro caso.
426   */
427   bool isEqual(const Variable& right) const throw() { return a_name == right.a_name; }
428
429   /**
430      Devuelve una cadena con informacion relevante de esta instancia.
431      \return Una cadena con informacion relevante de esta instancia.
432   */
433   virtual String asString() const throw();
434
435 protected:
436   /**
437      Devuelve la direccion de memoria de la variable C++ a sociada a esta variable logica.
438      \return La direccion de memoria de la variable C++ a sociada a esta variable logica.
439      \warning La forma de interpretar este valor dependera del tipo de dato (ver #Type) asociado
440      Devuelve la referencia a memoria de esta variable.
441      \internal
442   */
443   void* getReference() const throw();
444
445   /**
446      Devuelve el area de memoria de la variable C++ a sociada a esta variable logica.
447      \return La area de memoria de la variable C++ a sociada a esta variable logica.
448      \warning La forma de interpretar este valor dependera del tipo de dato (ver #Type) asociado
449      a esta variable.
450   */
451   void* buffer() const throw();
452
453   /**
454      Devuelve la referencia a la variable que controla el indicador de nulo de esta variable.
455      \return La referencia a la variable que controla el indicador de nulo de esta variable.
456   */
457   bool* getNullIndicator() throw() { return &a_isNull; }
458
459 private:
460   std::string a_name;
461   union {
462     std::string* a_string;
463     int* a_integer;
464     S64* a_longInteger;
465     bool* a_boolean;
466     DataBlock* a_dataBlock;
467     float* a_float;
468     double* a_double;
469     void* a_custom;
470   } a_value;
471   struct {
472     int integer;
473     S64 longInteger;
474     bool boolean;
475     float theFloat;
476     double theDouble;
477   } a_aux;
478   const Type::_v a_type;
479   const bool a_isOwner;
480   bool a_isNull;
481
482   Variable(const Variable&);
483   Variable& operator = (const Variable&);
484   void verifyIsNotNull(const char* file, const int lineno) const throw(RuntimeException);
485   void verifyMatchSomeType(const Type::_v firstType, const Type::_v secondType, const char* file, const int lineno) const throw(RuntimeException);
486   void verifyMatchType(const Type::_v, const char* file, const int lineno) const throw(RuntimeException);
487
488 };
489
490 }
491
492 #endif