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