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 #ifndef anna_comm_CompatCodec_hpp
10 #define anna_comm_CompatCodec_hpp
14 #include <anna/core/DataBlock.hpp>
15 #include <anna/core/RuntimeException.hpp>
16 #include <anna/core/util/SortedVector.hpp>
18 #include <anna/comm/Message.hpp>
19 #include <anna/comm/Variable.hpp>
31 Codificador/Decodificador compatible con los mensajes
33 Esta clase ofrece una forma muy eficaz para codificar estructuras de datos complejas y pretende
34 sustituir los tipicos aplanadores y desaplanadores ya que permite que cualquier proceso
35 defina facilmente la forma de transferir cierta informacion sobre un bloque de memoria
38 Vamos a ver un ejemplo de uso. Primero vamos a definir la clase MensajeDemo:
42 * #include <anna.comm.CompatCodec.h>
44 * class MensajeDemo : public CompatCodec {
46 * static const CompatCodec::Type type = 10;
48 * MensajeDemo () : CompatCodec (type),
51 * attach ("Entero", 0, a_entero);
52 * attach ("Cadena", 1, a_cadena);
53 * attach ("Bloque datos", 2, a_dataBlock);
57 * const int obtenerEntero () const { return a_entero; }
58 * const std::string& obtenerCadena () const { return a_cadena; }
59 * const DataBlock& obtenerDataBlock () const { return a_dataBlock; }
62 * void establecerEntero (const int entero) { a_entero = entero; }
63 * void establecerCadena (const std::string& cadena) { a_cadena = cadena; }
64 * void establecerCadena (const char* cadena) { a_cadena = cadena; }
65 * void establecerDataBlock (const DataBlock& dataBlock) { a_dataBlock = dataBlock; }
69 * std::string a_cadena;
70 * DataBlock a_dataBlock;
75 La clase que use esta clase para enviar un mensaje debe establecer los valores de cada uno de
76 los datos mediante los modificadores definidos y luego invocar al metodo #code que
77 transferiria el contenido de las variables asociadas a este mensaje a un bloque de memoria,
78 que normalmente seriausado como mensaje.
80 Por otra parte la clase que recibe el mensaje invocar�al metodo #decode que transfiere
81 el contenido del bloque de memoria a cada una de las variables asociadas al mensaje.
82 Posteriormente, podremos acceder al contenido de cada una de las variables asociadas al
83 mensaje atraves de los accesores definidos para el caso.
85 Estos codificadores nos dan la posibilidad de definir variables opcionales, de forma que
86 una determinada variable puede no ser transferida al bloque de memoria, y por tanto puede
87 no ser recibida en el otro extremo. Ver el metodo #isNull y #setNull para mas informacion.
89 \warning Esta clase no establece proteccion ante accesos concurrentes
91 class CompatCodec : public Message {
93 static short int value(const comm::Variable* variable) throw() {
94 return variable->getId();
98 class VariableContainer {
100 typedef comm::Variable* type_pointer;
102 typedef type_pointer* iterator;
103 typedef const type_pointer* const_iterator;
107 void clear() throw();
108 void add(comm::Variable* variable) throw();
109 comm::Variable* find(const int id) throw();
110 const comm::Variable* find(const int id) const throw();
112 int size() const throw() { return a_size; }
114 iterator begin() throw() { return a_variables; }
115 iterator end() throw() { return a_variables + a_size; }
117 const_iterator begin() const throw() { return a_variables; }
118 const_iterator end() const throw() { return a_variables + a_size; }
120 static comm::Variable* data(iterator ii) throw() { return *ii; }
121 static const comm::Variable* data(const_iterator ii) throw() { return *ii; }
124 comm::Variable** a_variables;
130 // typedef SortedVector <comm::Variable, SortById, short int> container;
131 typedef VariableContainer container;
132 typedef container::iterator iterator;
133 typedef container::const_iterator const_iterator;
134 typedef unsigned char Type;
139 @param type Tipo por el que sera conocido este tipo de mensaje.
140 @param scramble Indica si el mensaje debe ser codificado de forma que no se pueda ver el contenido
141 del mismo con una simple herramienta de monitorizacion de mensajes de red. Por defecto esta
142 activo ya que la codificacion realizada es muy simple y rapida y el tiempo empleado es casi
145 explicit CompatCodec(const Type type, const bool scramble = true);
150 virtual ~CompatCodec();
154 Devuelve el identificador del mensaje indicado en el constructor.
155 @return El identificador de este mensaje.
157 Type getType() const throw() { return a_type; }
161 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
162 estapensada principalmente para comunicar entre si procesos remotos.
163 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
164 de ellos le da a un determinado `id'.
166 \param name Nombre logico de la variable
167 @param id Identificador asignado al dato.
168 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
169 al mensaje y viceversa.
170 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
172 const Variable* attach(const char* name, const short int id, std::string& value) throw(RuntimeException);
175 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
176 estapensada principalmente para comunicar entre si procesos remotos
177 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
178 de ellos le da a un determinado `id'.
180 \param name Nombre logico de la variable
181 @param id Identificador asignado al dato.
182 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
183 al mensaje y viceversa.
184 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
186 const Variable* attach(const char* name, const short int id, const char*& value) throw(RuntimeException);
189 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
190 estapensada principalmente para comunicar entre si procesos remotos
191 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
192 de ellos le da a un determinado `id'.
194 \param name Nombre logico de la variable
195 @param id Identificador asignado al dato.
196 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
197 al mensaje y viceversa.
198 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
200 const Variable* attach(const char* name, const short int id, int& value) throw(RuntimeException);
203 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
204 estapensada principalmente para comunicar entre si procesos remotos
205 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
206 de ellos le da a un determinado `id'.
208 \param name Nombre logico de la variable
209 @param id Identificador asignado al dato.
210 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
211 al mensaje y viceversa.
212 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
214 const Variable* attach(const char* name, const short int id, S64& value) throw(RuntimeException);
217 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
218 estapensada principalmente para comunicar entre si procesos remotos
219 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
220 de ellos le da a un determinado `id'.
222 \param name Nombre logico de la variable
223 @param id Identificador asignado al dato.
224 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
225 al mensaje y viceversa.
226 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
228 const Variable* attach(const char* name, const short int id, bool& value) throw(RuntimeException);
231 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
232 estapensada principalmente para comunicar entre si procesos remotos
233 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
234 de ellos le da a un determinado `id'.
236 \param name Nombre logico de la variable
237 @param id Identificador asignado al dato.
238 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
239 al mensaje y viceversa. Debe tener activado el sistema de copia profunda.
240 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
242 const Variable* attach(const char* name, const short int id, DataBlock& value) throw(RuntimeException);
245 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
246 estapensada principalmente para comunicar entre si procesos remotos
247 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
248 de ellos le da a un determinado `id'.
250 \param name Nombre logico de la variable
251 @param id Identificador asignado al dato.
252 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
253 al mensaje y viceversa. Debe tener activado el sistema de copia profunda.
254 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
256 const Variable* attach(const char* name, const short int id, float& value) throw(RuntimeException);
259 Asocia el valor recibido como parametro al dato interno identificado por `id'. Esta clase
260 estapensada principalmente para comunicar entre si procesos remotos
261 La unica restriccion que se les imponen a ambos que es compartan el significado que cada uno
262 de ellos le da a un determinado `id'.
264 \param name Nombre logico de la variable
265 @param id Identificador asignado al dato.
266 @param value Rerencia a una variable de nuestro entorno usada para transferir los datos de la memoria
267 al mensaje y viceversa. Debe tener activado el sistema de copia profunda.
268 @return Un puntero que hace referencia al nuevo dato interno que ha sido creado.
270 const Variable* attach(const char* name, const short int id, double& value) throw(RuntimeException);
272 const Variable* attach(const char* name, const short int id, Second& value) throw(RuntimeException);
273 const Variable* attach(const char* name, const short int id, Millisecond& value) throw(RuntimeException);
274 const Variable* attach(const char* name, const short int id, Microsecond& value) throw(RuntimeException);
277 * Asocia el mensaje recibido como un parámetro interno especificado por \em id.
278 * \param name Nombre lógico de la variable.
279 * \param id Identificador del dato asignado.
280 * \param value Instancia del mensaje que se codificará/decodificará de forma recursiva.
282 const Variable* attach(const char* name, const short int id, comm::CompatCodec& value) throw(RuntimeException);
285 Devuelve la referencia al dato interno identificado por el `id' recibido como parametro.
287 @param id Identificador asignado al dato que queremos obtener.
289 @return La referencia de la variable identificada por 'id'. Si no existe se lanzar�una excepcin.
291 const Variable& find(const short int id) const throw(RuntimeException);
294 Marca el dato asociado al identificador recibido como nulo, lo cual conlleva que el dato no seria
295 transferido al bloque de memoria del mensaje en caso de invocar al metodo de codificacion.
297 @param id Identificador asignado al dato.
298 @param isNull Indica la nueva marca de la variable.
300 void setNull(const short int id, const bool isNull = true) throw(RuntimeException);
303 Marca el dato recibido como nulo, lo cual conlleva que el dato no seria transferido al bloque
304 de memoria del mensaje en caso de invocar al metodo de codificacion.
306 @param variable Instancia de Varaible obtenida al invocar al método #attach
307 @param isNull Indica la nueva marca de la variable.
309 void setNull(const Variable* variable, const bool isNull = true) throw();
312 @param id Identificador asignado al dato.
314 @return Devuelve @em false si el dato identificado por `id' tiene algun valor o @em true en caso de que
315 el dato haya sido marcado como nulo. Por defecto se considera que todos los datos tienen valor.
316 Un dato puede tener un value nulo, bien por que se ha invocado a la funcin @ref setNull
317 o bien porque se recibio un mensaje en el que no venia contenido el identificador del dato.
319 bool isNull(const short int id) const throw(RuntimeException);
322 Devuelve un iterador al comienzo de la lista de variables asociados a este mensaje.
323 \return Un iterador al comienzo de la lista de variables asociados a este mensaje.
325 iterator begin() throw() { return a_variables.begin(); }
328 Devuelve un iterador al comienzo de la lista de variables asociados a este mensaje.
329 \return Un iterador al comienzo de la lista de variables asociados a este mensaje.
331 const_iterator begin() const throw() { return a_variables.begin(); }
334 Devuelve un iterador al comienzo de la lista de variables asociados a este mensaje.
335 \return Un iterador al final de la lista de variables asociados a este mensaje.
337 iterator end() throw() { return a_variables.end(); }
340 Devuelve un iterador al comienzo de la lista de variables asociados a este mensaje.
341 \return Un iterador al final de la lista de variables asociados a este mensaje.
343 const_iterator end() const throw() { return a_variables.end(); }
346 Devuelve el número de enginees asociados a.esta instancia.
347 \return el número de enginees asociados a.esta instancia.
349 int size() const throw() { return a_variables.size(); }
352 Devuelve la instancia de la variable sobre el que esta posicionado el iterador recibido
354 \param ii Iterador que debera estar comprendido entre begin y end.
355 \return La instancia de la variable sobre el que esta posicionado el iterador recibido
357 static Variable* variable(iterator ii) throw() { return container::data(ii); }
360 Devuelve la instancia de la variable sobre el que esta posicionado el iterador recibido
362 \param ii Iterador que debera estar comprendido entre begin y end.
363 \return La instancia de la variable sobre el que esta posicionado el iterador recibido
365 static const Variable* variable(const_iterator ii) throw() { return container::data(ii); }
368 Transfiene los datos establecidos en este mensaje interno a un bloque de memoria cuya instancia es devuelta por este metodo.
369 @return Bloque de memoria que contiene la informacion del mensaje.
371 virtual const DataBlock& code() throw(RuntimeException);
374 Transfiene la informacion contenida en el bloque de memoria recibido hacia las variables asociadas a este mensaje interno.
375 Las variables cuyo value no esta incluidas en el bloque de memoria seria marcadas como nulas.
377 @param dataBlock Bloque de memoria que contiene las variables codificadas.
379 virtual void decode(const DataBlock& dataBlock) throw(RuntimeException);
382 Permite conocer el identificador del mensaje que viene contenido en el bloque de memoria
383 antes de realizar la decodificacion.
385 @param dataBlock Bloque de memoria que contiene la informacion del mensaje.
387 @return El tipo del mensaje contenido en el bloque de memoria.
389 static Type getType(const DataBlock& dataBlock) throw(RuntimeException);
396 container a_variables;
399 static bool st_initScramble;
401 CompatCodec(const CompatCodec&);
402 CompatCodec& operator = (const CompatCodec&);
404 void normalDecode(const char* data, const int size, const int maxdata) throw(RuntimeException);
405 bool optimizedDecode(const char* data, const int size) throw(RuntimeException);