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