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