f8d06801b88cc2cc17bbc38140b17149234975a2
[anna.git] / include / anna / core / functions.hpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // http://redmine.teslayout.com/projects/anna-suite
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
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
16 // distribution.
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.
20 //
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.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_core_functions_hpp
38 #define anna_core_functions_hpp
39
40 #include <stdlib.h>
41
42 #include <anna/core/util/ComponentManager.hpp>
43 #include <anna/core/util/defines.hpp>
44 #include <anna/core/RuntimeException.hpp>
45
46 #include <anna/core/util/ExclusiveHash.hpp>
47 #include <anna/core/util/Second.hpp>
48 #include <anna/core/util/Millisecond.hpp>
49 #include <anna/core/util/Microsecond.hpp>
50
51 #include <anna/core/DataBlock.hpp>
52
53
54 #include <time.h>
55 #include <sys/time.h>
56 #include <string>
57 #include <vector>
58
59
60 //------------------------------------------------------------------------------
61 //---------------------------------------------------------------------- #define
62 //------------------------------------------------------------------------------
63 #define s_REGEXP_IPv4_ADDRESSES "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"
64 //#define s_REGEXP_IPv6_ADDRESSES "s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})))(%.+)?\\s*"
65 #define s_REGEXP_IPv6_ADDRESSES "s*((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}(:|((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})\
66 (\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\
67 \\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(\
68 25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}((:((25[0-5]|2[0-4]\\d|[01]?\
69 \\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}((:((25[0-5]|2\
70 [0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4}){0,4}((:\
71 ((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-\
72 5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(((25[0-5]|2[0-4]\\d|[01]?\\d{1,2})(\\.(25[\
73 0-5]|2[0-4]\\d|[01]?\\d{1,2})){3})))(%.+)?\\s*"
74
75 // Helpers for alarm parsing parameters:
76 #define STRING_WITH_QUOTATION_MARKS__C_STR(x)   ((anna::functions::addQuotationMarks(x)).c_str())
77 #define ANNA_AS_STRING__C_STR(x)             ((anna::functions::asString(x)).c_str())
78
79
80
81 namespace anna {
82
83 class DataBlock;
84
85 #ifdef __CYGWIN__
86 #define CLOCK_PROCESS_CPUTIME_ID CLOCK_PROCESS_CPUTIME
87 #endif
88
89
90 /**
91    functions - Métodos y variables
92 */
93 struct functions {
94   /**
95      Tamao de la memoria reservada que debe tener la variable usada para guardar
96      el resultado de convertir el 'time' en texto.
97
98      @see asString
99   */
100   static const int DateTimeSizeString = 21;
101
102   /**
103      @return La versin de functions con la que hemos linkado nuestra aplicacion.
104   */
105   static std::string getVersion() throw();
106
107   /**
108      @return Un literal con la arquitectura sobre la que hemos compilado nuestra aplicacion.
109   */
110   static std::string getArchitecture() throw();
111
112   /**
113      Indica el número de bits de un entero.
114   */
115   static const int intBitSize = sizeof(int) * 8;
116
117   /*
118    * Indica el número de bits de un entero largo.
119    */
120   static const int int64BitSize = sizeof(S64) * 8;
121
122   /**
123      \param number Numero a convertir.
124      @return Un literal con el numero convertido a cadena decimal.
125   */
126   static std::string asString(const int number) throw();
127
128   /**
129      \param number Numero a convertir.
130      @return Un literal con el numero convertido a cadena decimal.
131   */
132   static std::string asString(const unsigned long number) throw();
133
134   /**
135      \param number Numero a convertir.
136      @return Un literal con el numero sin signo convertido a cadena decimal.
137   */
138   static std::string asString(const unsigned int number) throw();
139
140   /**
141      Devuelve un literal con tel numero convertido a cadena decimal
142      @return Un literal con el numero signo convertido a cadena decimal.
143   */
144   static std::string asString(const S64 number) throw();
145
146   /**
147      Devuelve un literal con tel numero convertido a cadena decimal
148      @return Un literal con el numero signo convertido a cadena decimal.
149   */
150   static std::string asString(const U64 number) throw();
151
152   /**
153      \param _bool Booleano a convertir.
154      \return Un literal con el boolean convertido a cadena.
155   */
156   static const char* asString(const bool _bool) throw() { return (_bool == true) ? "true" : "false"; }
157
158   /**
159      Devuelve una cadena con el bloque de datos decodificado en grupos de 16 bytes.
160      @param dataBlock Bloque de datos a interpretar.
161      \param characterByLine Número de caracteres en cada línea.
162      @return Devuelve una cadena con el bloque de datos decodificado en grupos de 16 bytes.
163   */
164   static std::string asString(const DataBlock& dataBlock, const int characterByLine = 16) throw();
165
166   /**
167      Devuelve una cadena con el numero en coma flotante.
168      \param v Numero a tratar.
169      \param format Formato aplicado para convertir el numero a cadena. Ver \em man printf.
170      \return una cadena con el numero en coma flotante.
171   */
172   static std::string asString(const double v, const char* format = "%e") throw();
173
174   /**
175      Devuelve una cadena con el numero en coma flotante.
176      \param v Numero a tratar.
177      \param format Formato aplicado para convertir el numero a cadena. Ver \em man printf.
178      \return una cadena con el numero en coma flotante.
179   */
180   static std::string asString(const float v, const char* format = "%f") throw();
181
182   /**
183      \param comment Comentario que precede al valor.
184      \param number Numero a convertir.
185      @return Un literal con el numero convertido a cadena decimal.
186   */
187   static std::string asText(const char* comment, const int number)
188   throw() {
189     std::string result(comment);
190     return result += asString(number);
191   }
192
193   /**
194      \param comment Comentario que precede al valor.
195      \param number Numero a convertir.
196      @return Un literal con el numero convertido a cadena decimal.
197   */
198   static std::string asText(const char* comment, const S64 number)
199   throw() {
200     std::string result(comment);
201     return result += asString(number);
202   }
203
204   /**
205       \param comment Comentario que precede al valor.
206       \param _bool Booleano a convertir.
207       @return Un literal con el numero convertido a cadena decimal.
208    */
209   static std::string asText(const char* comment, const bool _bool)
210   throw() {
211     std::string result(comment);
212     return result += asString(_bool);
213   }
214
215   /**
216      \param comment Comentario que precede al valor.
217      \param dataBlock Bloque de datos a interpretar.
218      \param characterByLine Número de caracteres en cada línea.
219      @return Un literal con el numero convertido a cadena decimal.
220   */
221   static std::string asText(const char* comment, const DataBlock& dataBlock, const int characterByLine = 16)
222   throw() {
223     std::string result(comment);
224     return result += asString(dataBlock, characterByLine);
225   }
226
227   /**
228      \param comment Comentario que precede al valor.
229      \param value Numero a tratar.
230      \param format Formato aplicado para convertir el numero a cadena. Ver \em man printf.
231      \return Un literal con el numero convertido a cadena.
232   */
233   static std::string asText(const char* comment, const float value, const char* format = "%f")
234   throw() {
235     std::string result(comment);
236     return result += asString(value, format);
237   }
238
239   /**
240      \param comment Comentario que precede al valor.
241      \param value Numero a tratar.
242      \param format Formato aplicado para convertir el numero a cadena. Ver \em man printf.
243      \return Un literal con el numero convertido a cadena.
244   */
245   static std::string asText(const char* comment, const double value, const char* format = "%e")
246   throw() {
247     std::string result(comment);
248     return result += asString(value, format);
249   }
250
251   /**
252      \param number Numero a convertir.
253      @return Un literal con el numero convertido a cadena hexadecimal.
254   */
255   static std::string asHexString(const int number) throw();
256
257   /**
258      \param number Numero a convertir.
259      @return Un literal con el numero convertido a cadena hexadecimal.
260   */
261   static std::string asHexString(const S64 number) throw();
262
263   /**
264      \param number Numero a convertir.
265      @return Un literal con el numero convertido a cadena hexadecimal.
266   */
267   static std::string asHexString(const long number) throw();
268
269   /**
270      \param number Numero a convertir.
271      @return Un literal con el numero convertido a cadena hexadecimal.
272   */
273   static std::string asHexString(const U64 number) throw() { return asHexString((S64) number); }
274
275   /**
276      \param comment Comentario que precede al valor.
277      \param number Numero a convertir.
278      @return Un literal con el numero convertido a cadena decimal.
279   */
280   static std::string asHexText(const char* comment, const int number)
281   throw() {
282     std::string result(comment);
283     return result += asHexString(number);
284   }
285
286   /**
287      \param comment Comentario que precede al valor.
288      \param number Numero a convertir.
289      @return Un literal con el numero convertido a cadena decimal.
290   */
291   static std::string asHexText(const char* comment, const S64 number)
292   throw() {
293     std::string result(comment);
294     return result += asHexString(number);
295   }
296
297   /**
298     * Devuelve un cadena con el contenido del bloque de datos interpretado como BCD, pero pasa
299     * cada valor binario a su correspondiente carácter. Por ejemplo, el buffer aa210c quedará como una cadena "AA210C".
300     *
301     * \param dataBlock Bloque a codificar.
302     * \return La cadena que contiene el valor literal del buffer de datos.
303     */
304   static std::string asHexString(const DataBlock& dataBlock) throw();
305
306   /**
307    * Obtiene el valor original de una cadena obtenido con #asHexString (const DataBlock&).
308    * \param hexString Cadena que contiene el búfer.
309    * \param target Bloque de datos sobre el que decodificar la cadena.
310    * \return El bloque de datos original correspondiente a la cadena recibida.
311    */
312   static DataBlock& fromHexString(const std::string& hexString, DataBlock& target) throw(RuntimeException);
313
314   /**
315      Devuelve una cadena con la hora en formato 'dd/mm/yyyy hh:mm:ss'.
316
317      @param second Hora que deseamos traducir.
318
319      @return Un literal con la hora en el formato 'dd/mm/yyyy hh:mm:ss'.
320   */
321   static std::string asDateTime(const Second &second) throw();
322
323   /**
324       Devuelve una cadena con la hora en formato 'dd/mm/yyyy hh:mm:ss'.
325
326       @param second Hora que deseamos traducir.
327       @param result Puntero donde vamos a guardar el resultado de la conversin.
328       Debe tener espacio reservado para contener #TimeSizeAsString caracteres.
329
330       @return El puntero recibido como parametro conteniendo el literal con la hora
331       en el formato 'dd/mm/yyyy hh:mm:ss'.
332    */
333   static const char* asDateTime(const Second &second, char* result) throw();
334
335   /**
336      Calcula la funcion hash de la cadena recibida como parametro.
337      \param str Cadena a la que aplicar la funcion hash.
338   */
339   static S64 hash(const char* str) throw();
340
341   /**
342      Calcula la funcion hash de la cadena recibida como parametro.
343      \param str Cadena a la que aplicar la funcion hash.
344   */
345   static S64 hash(const std::string& str) throw() { return hash(str.c_str()); }
346
347   /**
348      Calcula la funcion hash exclusive de la cadena recibida como parametro.
349      \param str Cadena a la que aplicar la funcion hash exclusiva.
350   */
351   static unsigned long exclusiveHash(const std::string& str) throw() { return st_stringExclusiveHash.calcule(str); }
352
353   /**
354      Calcula la funcion hash exclusive de la cadena recibida como parametro.
355      \param str Cadena a la que aplicar la funcion hash exclusiva.
356   */
357   static unsigned long exclusiveHash(const char* str) throw() { return st_stringExclusiveHash.calcule(std::string(str)); }
358
359   /**
360      Devuelve la cadena que contiene el resultado de aplicar la especificacion \em format
361      sobre el resto de los parametros.
362
363      \param format especificacion de formato similiar al empleado en las funciones \em printf,
364      \em scanf, etc.
365
366      \return la cadena que contiene el resultado de aplicar la especificacion \em format
367      sobre el resto de los parametros.
368   */
369   static std::string asString(const char* format, ...) throw();
370
371   /**
372      Devuelve el resultado de invocar a metodo asString de la clase recibida como parametro.
373      Si t es NULL devolvera el texto indicando la sitacion.
374      \param t Instancia de la clase a usar. Puede ser NULL.
375      \return el resultado de invoca a T::asString () si t es distinto de NULL.
376      \warning La clase T debe tener un metodo estatico con la signatura:
377      \code
378         static const char* className () throw ();
379      \endcode
380   */
381   template <typename T> static std::string asString(const T* t)
382   throw() {
383     if(t == NULL) {
384       std::string result(T::className());
385       result += " { <null> }";
386       return result;
387     }
388
389     return t->asString();
390   }
391
392   /**
393      Metodo identididad. Facilita la implementacion de patrones donde no se conoce el tipo de dato recibido.
394
395      \param str Instancia de la cadena.
396      \return La misma instancia recibida como parametro.
397   */
398   static const std::string& asString(const std::string& str) throw() { return str; }
399
400   /**
401      Detiene la ejecucion del thread durante el numero de milisegundos indicados.
402
403      \param millisecond Numero de milisegundos que vamos a detener la ejecucion de este thread.
404   */
405   static void sleep(const Millisecond &millisecond) throw();
406
407   /**
408      Obtiene el numero de segundos transcurridos desde el 1 del 1 de 1970.
409      \return El numero de segundos transcurridos desde el 1 del 1 de 1970.
410   */
411   static Second second() throw() {
412     Second result(::time(NULL));
413     return result;
414   }
415
416   /**
417      Obtiene el numero de microsegundos transcurridos desde el 1 del 1 de 1970.
418      \return El numero de microsegundos transcurridos desde el 1 del 1 de 1970.
419   */
420   static Microsecond microsecond() throw() {
421     struct timeval tv;
422     gettimeofday(&tv, NULL);
423     Microsecond result((Microsecond::type_t)1000000 * tv.tv_sec + tv.tv_usec);
424     return result;
425   }
426
427   /**
428      Obtiene el numero de milisegundos transcurridos desde el 1 del 1 de 1970.
429      \return El numero de milisegundos transcurridos desde el 1 del 1 de 1970.
430   */
431   static Millisecond millisecond() throw() {
432     struct timeval tv;
433     gettimeofday(&tv, NULL);
434     Millisecond result((Millisecond::type_t)1000 * tv.tv_sec + tv.tv_usec / 1000);
435     return result;
436   }
437
438   /**
439      Devuelve la referencia interna de los microsegundos transcurrido en el procesador.
440      \return la referencia interna de los microsegundos transcurrido en el procesador.
441   */
442   static Microsecond hardwareClock() throw() {
443     timespec ts;
444     //clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); // DONT works (original)
445     //clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); // DONT works
446     //clock_gettime(CLOCK_MONOTONIC, &ts); // works
447       // Note that CLOCK_MONOTONIC is subject to discontinuities from system time
448       //  adjustment in Linux. CLOCK_MONOTONIC_RAW was defined to get around this
449       //  (gets hardware time not adjusted by NTP).
450     clock_gettime(CLOCK_MONOTONIC_RAW, &ts); // works
451
452     Microsecond result((Microsecond::type_t)1000000 * ts.tv_sec + ts.tv_nsec / 1000);
453     return result;
454   }
455
456   /**
457      Interpreta la cadena recibida como parametro como un dato de tipo boolean.
458
459      Si la cadena vale NULL, o contiene los literales "false" o "0" devolvera \em false,
460      si contiene los literales "true" o "1" devolvera \em true, en otro caso devolvera un excepcion.
461
462      \param str Cadena a interpretar.
463
464      \return El valor booleano correspondiente a la cadena recibida.
465   */
466   static bool asBool(const char* str) throw(RuntimeException);
467
468   /**
469      Interpreta la cadena recibida como parametro como un entero de 32 bits.
470      \return
471    */
472   static int asInteger(const char* str) throw() { return atoi(str); }
473
474   /**
475      Interpreta la cadena recibida como parametro como un entero de 32 bits.
476      \return
477    */
478   static S64 asInteger64(const char* str) throw();
479
480   /**
481      Devuelve el identificador de thread desde el que es invocado este metodo.
482      Si el programa no tuviera soporta para MT siempre devolvera 0.
483      \return el identificador de thread desde el que es invocado este metodo.
484   */
485   static pthread_t getCurrentThread() throw();
486
487   /**
488      Devuelve \em true si la version de nucleo que estamos ejecutado soporta multithread o \em false en otro
489      caso.
490      \return \em true si la version de nucleo que estamos ejecutado soporta multithread o \em false en otro
491   */
492   static bool supportMultithread() throw() {
493     WHEN_SINGLETHREAD(return false);
494     WHEN_MULTITHREAD(return true);
495   }
496
497   /**
498      Devuelve \em true si el valor recibido cumple el patron establecido o \em false en otro caso.
499      \param pattern Expresion regular que describe el patron a cumplir.
500      \param value Cadena a comparar con el patron.
501      \return \em true si el valor recibido cumple el patron establecido o \em false en otro caso.
502
503      \see regexec para mas informacion sobre las expresiones regulares.
504   */
505   static bool isLike(const char* pattern, const std::string& value) throw(RuntimeException);
506
507   /**
508    * Devuelve el número de bits necesarios para representar el valor recibido como parámetro.
509    * \param n Valor a estudiar.
510    * \return el número de bits necesarios para representar el valor recibido como parámetro.
511    */
512   static int bitsize(const int n) throw() {  return (n == 0) ? 1 : functions::log2(n) + 1; }
513
514   /**
515    * Devuelve el número de bits necesarios para representar el valor recibido como parámetro.
516    * \param n Valor a estudiar.
517    * \return el número de bits necesarios para representar el valor recibido como parámetro.
518    */
519   static int bitsize(const S64 n) throw() {
520     register int aux = n >> intBitSize;
521     return (aux != 0) ? (bitsize(aux) + intBitSize) : bitsize((int) n);
522   }
523
524   /**
525    * Calcula la operación (n1 << bitShit) | n2. Establece las comprobaciones necesarias para verificar
526    * que la operación se realiza correctamente, teniendo especial cuidado de que no se puedan solapar
527    * ninguno de los valores.
528    *
529    * \param whatis Literal que debería identificar el punto de invocación en caso de que haya algún error.
530    * \param n1 Número a desplazar el nº de bits indicado por \em bitShift.
531    * \param bitShift Número de bits a desplazar.
532    * \param n2 Número a combinar con el resultado de la operación (n1 << bitShift).
533    */
534   static S64 merge(const char* whatis, const int n1, const int n2, const int bitShift) throw(RuntimeException);
535
536   /**
537    * Calcula el logaritmo en base 2 del número recibo como parámetro.
538    * \param v Valor a calcular.
539    * \return El algoritmo en base 2 del número recibido como parámetro o -1 si el parámetro recibido es 0.
540    */
541   static int log2(const unsigned int v) throw();
542
543
544
545
546   //////////////////////////////////////////////////////////////////////////////////////////////////
547   // Text format resources /////////////////////////////////////////////////////////////////////////
548   //////////////////////////////////////////////////////////////////////////////////////////////////
549   struct TextHighlightMode {
550     enum _v {
551       None = -1, // Initialized
552       Overline,
553       Underline,
554       OverAndUnderline,
555       Leftline,
556       Rightline,
557       LeftAndRightline
558     };
559   };
560
561   struct TextJustifyMode {
562     enum _v {
563       None = -1, // Initialized
564       Left,
565       Center,
566       Right
567     };
568   };
569
570   /**
571      Solve singular/plural literal expression for any number.
572      <pre>
573      Provide (0): returns "no entries"
574      Provide (1): returns "1 entry"
575      Provide (2): returns "2 entries"
576
577      Provide (0, 'table'): returns "no tables"
578      Provide (1, 'table'): returns "1 table"
579      Provide (2, 'table'): returns "2 tables"
580
581      Provide (0, 'query', 'queries'): returns "no queries"
582      Provide (1, 'query', 'queries'): returns "1 query"
583      Provide (2, 'query', 'queries'): returns "2 queries"
584      </pre>
585
586      @param number Amount processed
587      @param wordForSingular Word used as singular, 'entry' by default.
588      @param wordForPlural Word used as plural, 'entries' by default.
589
590      @return Coherent literal as '%d <singular word/plural word>'
591   */
592   static std::string entriesAsString(int number, const char * wordForSingular = NULL, const char * wordForPlural = NULL) throw();
593
594   /**
595      Justify text (traces and output improvement)
596
597      @param title Title processed
598      @param mode Justify mode: Left (default), Center, Right
599      @param filler Filler character used (space by default)
600
601      @return Processed text
602   */
603   static std::string justify(const std::string & title, TextJustifyMode::_v mode = TextJustifyMode::Left, char filler = ' ') throw();
604
605   /**
606      Highligth text (traces and output improvement)
607
608      @param title Title processed
609      @param mode Highlight mode: Overline, Underline(default), OverAndUnderline, Leftline, Rightline, LeftAndRightline
610      @param filler Filler character used (dash by default)
611      @param appendCR Carriage return inclusion (true by default)
612
613      @return Processed text
614   */
615   static std::string highlight(const std::string & title, TextHighlightMode::_v mode = TextHighlightMode::Underline, char filler = '-', bool appendCR = true) throw();
616
617   /**
618      Highligth and justify text (traces and output improvement)
619
620      @param title Title processed
621      @param hMode Highlight mode: Overline, Underline(default), OverAndUnderline, Leftline, Rightline, LeftAndRightline
622      @param jMode Justify mode: Left (default), Center, Right
623      @param highlightFiller Filler character used (double dash ('=') by default)
624      @param justifyFiller Filler character used when justify (space by default)
625      @param appendCR Carriage return inclusion (true by default)
626
627      @return Processed text
628   */
629   static std::string highlightJustify(const std::string & title, TextHighlightMode::_v hMode = TextHighlightMode::OverAndUnderline, TextJustifyMode::_v jMode = TextJustifyMode::Center, char highlightFiller = '=', char justifyFiller = ' ', bool appendCR = true) throw() {
630     return(highlight(justify(title, jMode, justifyFiller), hMode, highlightFiller, appendCR));
631   }
632
633   /**
634      Tabulate text (traces and output improvement)
635
636      @param text Text processed
637      @param tabSpaces Tab spaces (three by default)
638   */
639   static std::string tab(const std::string & text, int tabSpaces = 3) throw();
640
641
642   //////////////////////////////////////////////////////////////////////////////////////////////////
643   // Conversions and helpers ///////////////////////////////////////////////////////////////////////
644   //////////////////////////////////////////////////////////////////////////////////////////////////
645
646   /**
647      Pattern to obtain a component instance easily.
648      Parameters are usually replaced by the macro C <b>FILE_LOCATION</b>.
649
650      \param fromFile File which called the method
651      \param fromLine Line number within the file from where the method is called.
652
653      \return Component instance for the class provided at the pattern
654      \warning The class T must define:
655      \code
656          static const char* getClassName () throw ();
657      \endcode
658      \see Component
659   */
660   template <typename T> static T* component(const char* fromFile, const int fromLine)
661   throw(RuntimeException) {
662     ComponentManager &cm = ComponentManager::instantiate();
663     const char *className = T::getClassName();
664     T* result = static_cast <T*>(cm.find(className));
665
666     if(result == NULL) {
667       std::string msg(className);
668       msg += " | Componente no registrado";
669       throw RuntimeException(msg, fromFile, fromLine);
670     }
671
672     return result;
673   }
674
675   /**
676    * Gets exclusive hash for string provided on integer range
677    *
678    * @param str String hashed
679    *
680    * @return Hash unique value
681    */
682   static int exclusiveHashInt(const std::string& str) throw() { return st_string2intExclusiveHash.calcule(str); }
683
684   /**
685    * Gets exclusive hash for string (char pointer) provided on integer range
686    *
687    * @param str String hashed
688    *
689    * @return Hash unique value
690    */
691   static int exclusiveHashInt(const char* str) throw() { return st_string2intExclusiveHash.calcule(std::string(str)); }
692
693   /**
694      Finds string at the end of another
695
696      @param pattern String where we find
697      @param suffix Searched string
698
699      @return Boolean about ocurrency
700   */
701   static bool endsWith(const std::string & pattern, const std::string & suffix) throw() {
702     std::string dummy;
703     return endsWith(pattern, suffix, dummy);
704   }
705
706   /**
707      Similar to #endsWith but returning additional preffix string by reference (pattern without suffix)
708   */
709   static bool endsWith(const std::string & pattern, const std::string & suffix, std::string & preffix) throw();
710
711   /**
712      Finds string at the begining of another
713
714      @param pattern String where we find
715      @param preffix Searched string
716
717      @return Boolean about ocurrency
718   */
719   static bool startsWith(const std::string & pattern, const std::string & preffix) throw() {
720     std::string dummy;
721     return startsWith(pattern, preffix, dummy);
722   }
723
724   /**
725      Similar to #startsWith but returning additional suffix string by reference (pattern without preffix)
726   */
727   static bool startsWith(const std::string & pattern, const std::string & preffix, std::string & suffix) throw();
728
729   /**
730      Finds 'item' and replaces it with 'target' within the string provided ('text').
731      The result is returned.
732
733      @param text Original string
734      @param item Searched string
735      @param target String which replaces the item
736      @param all Boolean about replace all items or only the first found. True by default.
737
738      @return Modified string
739   */
740   static std::string replace(const std::string & text, const char *item, const char *target, bool all = true) throw();
741
742   /**
743   * Coverts original string without quotation into quoted one: '\%s'
744   */
745   static std::string addQuotationMarks(const std::string & str) throw();
746   static std::string addQuotationMarks(const char * str) throw();
747   static std::string addQuotationMarks(const int & integer) throw();
748
749   /**
750   * Generates space-separated string lists based on integer elements
751   * Also, another separator could be used.
752   */
753   static std::string vectorToStringRepresentation(const std::vector<int> & v, const char separator = ' ') throw();
754
755   /**
756   * Generates space-separated string lists based on string elements.
757   * Also, another separator could be used.
758   */
759   static std::string vectorToStringRepresentation(const std::vector<std::string> & v, const char separator = ' ') throw();
760
761   /**
762      Returns socket notation 'Address:Port'
763   */
764   static std::string socketLiteralAsString(const std::string & address, int port) throw();
765
766   /**
767      Ascii string for buffer/size data block
768
769      @param buffer Octet string buffer
770      @param size Buffer size
771      @param isFullyPrintable Returned by reference
772
773      @return Ascii string representation, and dots for non-printable cheracters
774   */
775   static std::string asAsciiString(const char * buffer, int size, bool & isFullyPrintable) throw();
776
777   /**
778      Same as #asAsciiString but without interest about if is printable or not
779   */
780   static std::string asAsciiString(const char * buffer, int size) throw() {
781     bool isFullyPrintable;
782     return asAsciiString(buffer, size, isFullyPrintable);
783   }
784
785   /**
786      Same as #asAsciiString providing anna::DataBlock
787   */
788   static std::string asAsciiString(const DataBlock & db, bool & isFullyPrintable) throw() {
789     return asAsciiString(db.getData(), db.getSize(), isFullyPrintable);
790   }
791
792   /**
793      Same as #asAsciiString providing DataBlock and without interest about if is printable or not
794   */
795   static std::string asAsciiString(const DataBlock & db) throw() {
796     bool isFullyPrintable;
797     return asAsciiString(db.getData(), db.getSize(), isFullyPrintable);
798   }
799
800
801   /**
802    * IP Address enconding based on common database 'human-readable raw presentation':
803    * <pre>
804    *    Example for IPv4: 'AABBCCDD' will be DataBlock for '170.187.204.221'
805    *    Example for IPv6: '20010DB885A3000000008A2E03707334' will be DataBlock for '2001:0db8:85a3:0000:0000:8a2e:0370:7334'
806    *
807    *    '000000000000000000000000AABBCCDD' will be encoded as 16-sized Datablock, not IPv4 (4 bytes). Is not recommended to
808    *    put IPv4 on this way because of ambiguity regarding IPv4-compatible format. It is application responsability to trim
809    *    leading zeros in order to use this method for IPv4 source.
810    * </pre>
811    *
812    * @param rawPresentation Input IP address as raw presentation. Must be 8 or 32 sized for IPv4 and IPv6 respectively.
813    *
814    * @return Encoded DataBlock
815    */
816   static DataBlock rawIpPresentationAsRaw(const std::string & rawPresentation) throw(RuntimeException);
817
818
819   /**
820    * IP Address decoding from raw presentation:
821    * <pre>
822    *    Example for IPv4: 'AABBCCDD' will be '170.187.204.221'
823    *    Example for IPv6: '20010DB885A3000000008A2E03707334' will be '2001:0db8:85a3:0000:0000:8a2e:0370:7334'
824    *
825    *    '000000000000000000000000AABBCCDD' will be internally encoded as 16-sized Datablock, not IPv4 (4 bytes).
826    *    Is not recommended to put IPv4 on this way because of ambiguity regarding IPv4-compatible format. It is
827    *    application responsability to trim leading zeros in order to use this method for IPv4 source.
828    * </pre>
829    *
830    * @param rawPresentation Input IP address as raw presentation. Must be 8 or 32 sized for IPv4 and IPv6 respectively.
831    * @param normalize Normalize returned address representation, 'false' by default (to avoid IPv4 to IPv6 conversion)
832    *
833    * @return Decoded IP address
834    */
835   static std::string rawIpPresentationToIpAsString(const std::string & rawPresentation, bool normalize = false) throw(RuntimeException) {
836     return rawIpAsString(rawIpPresentationAsRaw(rawPresentation), normalize);
837   }
838
839
840   /**
841    * IP Address decoding to 'human-readable raw presentation':
842    * <pre>
843    *    Example for IPv4: DataBlock for '170.187.204.221' will be 'AABBCCDD' (a pure IPv4 will never contain leading zeros outside of its scope (i.e., 24 zeros on a 32-character presentation)
844    *    Example for IPv6: DataBlock for '2001:0db8:85a3:0000:0000:8a2e:0370:7334' will be '20010DB885A3000000008A2E03707334'
845    *
846    *    DataBlock for '::170.187.204.221' will be represented as IPv4 compatible: '000000000000000000000000AABBCCDD'
847    * </pre>
848    *
849    * @param db Encoded DataBlock with 4 or 16 bytes to represent Ipv4 or Ipv6.
850    *
851    * @return Human-readable raw IP presentation
852    */
853   static std::string rawIpAsRawIpPresentation(const DataBlock & db) throw(RuntimeException);
854
855
856   /**
857    * Gets the host name (system name)
858    *
859    * @return Hostname
860    */
861   static std::string getHostname() throw();
862
863   /**
864    * Gets the domain name
865    *
866    * @return Domainname
867    */
868   static std::string getDomainname() throw();
869
870   /**
871    * Gets the FQDN (Fully Qualified Domain Name)
872    *
873    * @param hostname Specific provided hostname. Automatically solved if missing. Empty string implies exclusion from FQDN.
874    * @param domainname Specific provided domainname. Automatically solved if missing. Empty string implies exclusion from FQDN.
875    *
876    * @return FQDN (<hostname>.<domainname>)
877    */
878   static std::string getFQDN(const char *hostname = NULL, const char  *domainname = NULL) throw();
879
880   /**
881    * Gets the IP based on hostname (#getHostname)
882    *
883    * @return Hostname-based IP
884    */
885   static std::string getHostnameIP() throw();
886
887
888
889   //////////////////////////////////////////////////////////////////////////////////////////////////
890   // IP Address resources //////////////////////////////////////////////////////////////////////////
891   //////////////////////////////////////////////////////////////////////////////////////////////////
892
893   /**
894   * IPv4 subtype (Estrict/Compatible)
895   */
896   struct IPv4Type {
897     enum _v {
898       Estrict = -1, // Initialized,
899       Compatible,
900       Mapped
901     };
902   };
903
904   /**
905   * IPv4 address family detection
906   *
907   * @param ip IP address
908   * @param ipv4Type Check for IPv4-compatible (i.e. '::192.168.0.1'), IPv4-mapped (i.e. '2001:0db8:85a3:0000:0000:8a2e:192.168.0.1') or estrict IPv4 format.
909   *
910   * @return Boolean for IPv4 nature
911   */
912   static bool isIPv4(const std::string & ip, IPv4Type::_v ipv4Type = IPv4Type::Estrict) throw();
913
914   /**
915   * IPv6 address family detection
916   *
917   * @param ip IP address
918   *
919   * @return Boolean for IPv6 nature
920   */
921   static bool isIPv6(const std::string & ip) throw();
922
923   /**
924    * Convert an IPv4 address to IPv6. Also removes dots from IPv4-mapped format.
925    *
926    * @param ipv4 IP Address in dot notation (192.168.1.100)
927    *
928    * @return string IPv6 formatted address or launch exception if invalid input
929    */
930   static std::string IPv4To6(const std::string & ipv4) throw(RuntimeException);
931
932   /**
933    * Normalizes an IP address to long notation. Specially used for IPv6, but valid for IPv4 (via IPv4To6 conversion).
934    *
935    * Examples:
936    *  ::1 ->                          0000:0000:0000:0000:0000:0000:0000:0001
937    *  2001:db8:85a3::8a2e:370:7334 -> 2001:0db8:85a3:0000:0000:8a2e:0370:7334
938    *
939    * @param ip Input IP address
940    *
941    * @return Normalized IP address
942    */
943   static std::string normalizeIP(const std::string & ip) throw(RuntimeException);
944
945   /**
946    * Compare two IP addresses by mean normalization
947    *
948    * @param ip1 First IP address compared
949    * @param ip2 Second IP address compared
950    *
951    * @return Boolean about IP's comparison
952    */
953   static bool sameIP(const std::string & ip1, const std::string & ip2) throw(RuntimeException);
954
955   /**
956    * Compare two IP addresses by mean internal comparison after ipv6 preffix restriction
957    *
958    * @param ipv6 IPv6 address matched
959    * @param preffixedIpv6 Preffixed IPv6 address (<ipv6>/<preffix length>: only values from 0 (always match) to 128 (maximum restriction) are allowed).
960    *
961    * @return Boolean about subnet matching
962    */
963   static bool matchIPv6(const std::string & ipv6, const std::string & preffixedIpv6) throw(RuntimeException);
964
965   /**
966    * IP Address serialization
967    *
968    * @param ip Input IP address
969    *
970    * @return Encoded DataBlock
971    */
972   static DataBlock ipAsRaw(const std::string & ip) throw(RuntimeException);
973
974   /**
975    * IP Address decoding
976    *
977    * @param db Encoded DataBlock with 4 or 16 bytes to represent Ipv4 or Ipv6.
978    * @param normalize Normalize returned address representation, 'false' by default (to avoid IPv4 to IPv6 conversion)
979    *
980    * @return Decoded IP address
981    */
982   static std::string rawIpAsString(const DataBlock & db, bool normalize = false) throw(RuntimeException) {
983     return (rawIpAsString(db.getData(), db.getSize(), normalize));
984   }
985
986   /**
987    * IP Address decoding
988    *
989    * @param buffer Encoded buffer with 4 or 16 bytes to represent Ipv4 or Ipv6.
990    * @param bufferLength Encoded buffer length with 4 or 16 bytes to represent Ipv4 or Ipv6.
991    * @param normalize Normalize returned address representation, 'false' by default (to avoid IPv4 to IPv6 conversion)
992    *
993    * @return Decoded IP address
994    */
995   static std::string rawIpAsString(const char *buffer, int bufferLength, bool normalize = false) throw(RuntimeException);
996
997   /**
998    * Abbreviates an IP address. Specially used for IPv6, but valid for IPv4.
999    *
1000    * Examples:
1001    *  0000:0000:0000:0000:0000:0000:0000:0001 -> ::1
1002    *  2001:0db8:85a3:0000:0000:8a2e:0370:7334 -> 2001:db8:85a3::8a2e:370:7334
1003    *
1004    * @param ip Input IP address
1005    *
1006    * @return Abbreviated IP address
1007    */
1008   static std::string abbreviateIP(const std::string & ip) throw(RuntimeException) {
1009     return (rawIpAsString(ipAsRaw(ip)));
1010   }
1011
1012
1013
1014
1015   // socket literal description typedef, vectors and conversion tools
1016
1017   /**
1018   * Extract ADDRESS (ip or hostname ro resolve) and PORT from socket literal description ('<ip|hostname>:<port>').
1019   *
1020   * @param literal Socket literal in format '<ip|hostname>:<port>'
1021   * @param address Address extracted by reference
1022   * @param port Port extracted by reference
1023   */
1024   static void getAddressAndPortFromSocketLiteral(const std::string &literal, std::string &address, int &port) throw();
1025
1026   /**
1027   * Translate pipe-separated socket literal list into Address/Port vector.
1028   *
1029   * @param list Comma-separated Address/Port list. I.e.: '10.95.10.25:4000,10.95.10.25:4001', or 'fed1:4000,fed2:4001'
1030   * @return Address/Port socket items vector
1031   */
1032   static socket_v getSocketVectorFromString(const std::string & list) throw();
1033
1034   /**
1035   * Translate Address/Port vector into comma-separated Address/Port list.
1036   *
1037   * @param socketVector Address/Port vector
1038   *
1039   * @return Comma-separated Address/Port list. I.e.: '10.95.10.25:4000,10.95.10.25:4001', or 'fed1:4000,fed2:4001'
1040   */
1041   static std::string socketVectorAsString(const socket_v & socketVector) throw();
1042
1043
1044   /**
1045     Endianess of the system
1046
1047     @result Returns true when the system is little endian, false if big endian
1048   */
1049   static bool littleEndian() throw();
1050
1051   /**
1052      Encodes an integer number with 32 bits over a buffer with at least 4 bytes of length.
1053      @param result Buffer where the number is encoded.
1054      @param n Number to encode.
1055      \return Buffer with the encoded number.
1056    */
1057   static const char* codeInteger(char* result, const int n) throw();
1058
1059   /**
1060      Encodes an integer number with 16 bits over a buffer with at least 2 bytes of length.
1061      @param result Buffer where the number is encoded.
1062      @param n Number to encode.
1063      \return Buffer with the encoded number.
1064   */
1065   static const char* codeShort(char* result, const short int n) throw();
1066
1067   /**
1068      Encodes an integer number with 64 bits over a buffer with at least 8 bytes of length.
1069      @param result Buffer where the number is encoded.
1070      @param n Number to encode.
1071      \return Buffer with the encoded number.
1072    */
1073   static const char* codeInteger64(char* result, const S64 n) throw();
1074
1075   /**
1076      Encodes a floating number with 32 bits (according to the standard IEEE-754) over a buffer with at least 4 bytes of length.
1077      @param result Buffer where the number is encoded.
1078      @param n Number to encode.
1079      \return Buffer with the encoded number.
1080    */
1081   static const char* codeFloat(char* result, const float n) throw();
1082
1083   /**
1084      Encodes a floating number with 64 bits (according to the standard IEEE-754) over a buffer with at least 8 bytes of length.
1085      @param result Buffer where the number is encoded.
1086      @param n Number to encode.
1087      \return Buffer with the encoded number.
1088    */
1089   static const char* codeDouble(char* result, const double n) throw();
1090
1091   /**
1092      Decodes an 32 bits integer number contained in a 4-bytes buffer.
1093      @param data Buffer with the encoded number.
1094      @return Value for the number contained in the buffer.
1095   */
1096   static int decodeInteger(const char* data)  throw();
1097
1098   /**
1099      Decodes an 16 bits integer number contained in a 2-bytes buffer.
1100      @param data Buffer with the encoded number.
1101      @return Value for the number contained in the buffer.
1102   */
1103   static short int decodeShort(const char* data)  throw();
1104
1105   /**
1106      Decodes an 64 bits integer number contained in a 8-bytes buffer.
1107      @param data Buffer with the encoded number.
1108      @return Value for the number contained in the buffer.
1109   */
1110   static S64 decodeInteger64(const char* data)  throw();
1111
1112   /**
1113      Decodes an 32 bits floating number (according to the standard IEEE-754) contained in a 4-bytes buffer.
1114      @param data Buffer with the encoded number.
1115      @return Value for the number contained in the buffer.
1116   */
1117   static float decodeFloat(const char* data)  throw();
1118
1119   /**
1120      Decodes an 64 bits floating number (according to the standard IEEE-754) contained in a 8-bytes buffer.
1121      @param data Buffer with the encoded number.
1122      @return Value for the number contained in the buffer.
1123   */
1124   static double decodeDouble(const char* data)  throw();
1125
1126
1127   /**
1128   * Decodes an ISUP Number (called or calling party number).
1129   *
1130   * @param buffer Isup number content buffer.
1131   * @param length Isup number content length.
1132   * @param isupNumber Isup number decoded by reference.
1133   * @param calledOrCalling True for called party number, false for calling
1134   */
1135   static void decodeIsupNumber(const char *buffer, int length, isup_number_t & isupNumber, bool calledOrCalling) throw(RuntimeException);
1136
1137   /**
1138   * Encodes an ISUP Number (called or calling party number).
1139   *
1140   * @param isupNumber Isup number.
1141   * @param calledOrCalling True for called party number, false for calling
1142   * @param buffer Isup number content encoded buffer.
1143   * @param length Isup number content encoded length.
1144   */
1145   static void codeIsupNumber(const isup_number_t & isupNumber, bool calledOrCalling, char * buffer, int & length) throw(RuntimeException);
1146
1147   /**
1148   * Encodes an ISUP Number (called or calling party number).
1149   *
1150   * @param isupNumber Isup number.
1151   * @param calledOrCalling True for called party number, false for calling
1152   * @param target Isup number octet string.
1153   */
1154   static void codeIsupNumber(const isup_number_t & isupNumber, bool calledOrCalling, std::string & target) throw(RuntimeException);
1155
1156 private:
1157   static ExclusiveHash <std::string> st_stringExclusiveHash;
1158   static ExclusiveHash <std::string, int> st_string2intExclusiveHash;
1159 };
1160
1161 }
1162
1163 #endif
1164