1 /**
2  * yateclass.h
3  * This file is part of the YATE Project http://YATE.null.ro
4  *
5  * Base classes and types, not related to the engine or telephony
6  *
7  * Yet Another Telephony Engine - a fully featured software PBX and IVR
8  * Copyright (C) 2004-2014 Null Team
9  *
10  * This software is distributed under multiple licenses;
11  * see the COPYING file in the main directory for licensing
12  * information for this specific distribution.
13  *
14  * This use of this software may be subject to additional restrictions.
15  * See the LEGAL file in the main directory for details.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 
22 #ifndef __YATECLASS_H
23 #define __YATECLASS_H
24 
25 #ifndef __cplusplus
26 #error C++ is required
27 #endif
28 
29 #include <limits.h>
30 #include <sys/types.h>
31 #include <stddef.h>
32 #include <unistd.h>
33 #include <errno.h>
34 #include <stdarg.h>
35 
36 #ifndef _WORDSIZE
37 #if defined(__arch64__) || defined(__x86_64__) \
38     || defined(__amd64__) || defined(__ia64__) \
39     || defined(__alpha__) || defined(__sparcv9) || defined(__mips64)
40 #define _WORDSIZE 64
41 #else
42 #define _WORDSIZE 32
43 #endif
44 #endif
45 
46 #ifndef _WINDOWS
47 #if defined(WIN32) || defined(_WIN32)
48 #define _WINDOWS
49 #endif
50 #endif
51 
52 #ifdef _WINDOWS
53 
54 #include <windows.h>
55 #include <io.h>
56 #include <direct.h>
57 
58 /**
59  * Windows definitions for commonly used types
60  */
61 typedef signed __int8 int8_t;
62 typedef unsigned __int8 u_int8_t;
63 typedef unsigned __int8 uint8_t;
64 typedef signed __int16 int16_t;
65 typedef unsigned __int16 u_int16_t;
66 typedef unsigned __int16 uint16_t;
67 typedef signed __int32 int32_t;
68 typedef unsigned __int32 u_int32_t;
69 typedef unsigned __int32 uint32_t;
70 typedef signed __int64 int64_t;
71 typedef unsigned __int64 u_int64_t;
72 typedef unsigned __int64 uint64_t;
73 
74 typedef int pid_t;
75 typedef int socklen_t;
76 typedef unsigned long in_addr_t;
77 
78 #ifndef strcasecmp
79 #define strcasecmp _stricmp
80 #endif
81 
82 #ifndef strncasecmp
83 #define strncasecmp _strnicmp
84 #endif
85 
86 #define vsnprintf _vsnprintf
87 #define snprintf _snprintf
88 #define strdup _strdup
89 #define strtoll _strtoi64
90 #define strtoull _strtoui64
91 #define open _open
92 #define dup2 _dup2
93 #define read _read
94 #define write _write
95 #define close _close
96 #define getpid _getpid
97 #define chdir _chdir
98 #define mkdir(p,m) _mkdir(p)
99 #define unlink _unlink
100 #define llabs _abs64
101 
102 #define O_RDWR   _O_RDWR
103 #define O_RDONLY _O_RDONLY
104 #define O_WRONLY _O_WRONLY
105 #define O_APPEND _O_APPEND
106 #define O_BINARY _O_BINARY
107 #define O_EXCL   _O_EXCL
108 #define O_CREAT  _O_CREAT
109 #define O_TRUNC  _O_TRUNC
110 #define O_NOCTTY 0
111 
112 #define S_IRUSR _S_IREAD
113 #define S_IWUSR _S_IWRITE
114 #define S_IXUSR 0
115 #define S_IRWXU (_S_IREAD|_S_IWRITE)
116 
117 #ifdef LIBYATE_EXPORTS
118 #define YATE_API __declspec(dllexport)
119 #else
120 #ifndef LIBYATE_STATIC
121 #define YATE_API __declspec(dllimport)
122 #endif
123 #endif
124 
125 #define FMT64 "%I64d"
126 #define FMT64U "%I64u"
127 
128 #else /* _WINDOWS */
129 
130 #include <sys/time.h>
131 #include <sys/socket.h>
132 
133 #if (defined(__FreeBSD__)||defined(__DragonFly__))
134 #include <netinet/in_systm.h>
135 #endif
136 
137 #include <netinet/in.h>
138 #include <netinet/ip.h>
139 #include <netinet/tcp.h>
140 #include <arpa/inet.h>
141 #include <netdb.h>
142 
143 /**
144  * Non-Windows definitions for commonly used types
145  */
146 #ifndef SOCKET
147 typedef int SOCKET;
148 #endif
149 #ifndef HANDLE
150 typedef int HANDLE;
151 #endif
152 
153 #ifndef O_BINARY
154 #define O_BINARY 0
155 #endif
156 
157 #if _WORDSIZE == 64 && !defined(__APPLE__)
158 #define FMT64 "%ld"
159 #define FMT64U "%lu"
160 #else
161 #define FMT64 "%lld"
162 #define FMT64U "%llu"
163 #endif
164 
165 #endif /* ! _WINDOWS */
166 
167 #ifndef LLONG_MAX
168 #ifdef _I64_MAX
169 #define LLONG_MAX _I64_MAX
170 #else
171 #define LLONG_MAX 9223372036854775807LL
172 #endif
173 #endif
174 
175 #ifndef LLONG_MIN
176 #ifdef _I64_MIN
177 #define LLONG_MIN _I64_MIN
178 #else
179 #define LLONG_MIN (-LLONG_MAX - 1LL)
180 #endif
181 #endif
182 
183 #ifndef ULLONG_MAX
184 #ifdef _UI64_MAX
185 #define ULLONG_MAX _UI64_MAX
186 #else
187 #define ULLONG_MAX 18446744073709551615ULL
188 #endif
189 #endif
190 
191 #ifndef O_LARGEFILE
192 #define O_LARGEFILE 0
193 #endif
194 
195 #ifndef IPTOS_LOWDELAY
196 #define IPTOS_LOWDELAY      0x10
197 #define IPTOS_THROUGHPUT    0x08
198 #define IPTOS_RELIABILITY   0x04
199 #endif
200 #ifndef IPTOS_MINCOST
201 #define IPTOS_MINCOST       0x02
202 #endif
203 #ifndef IPPROTO_SCTP
204 #define IPPROTO_SCTP        132
205 #endif
206 
207 #ifndef YATE_API
208 #define YATE_API
209 #endif
210 
211 #ifdef _WINDOWS
212 #undef RAND_MAX
213 #define RAND_MAX 2147483647
214 #endif
215 
216 /**
217  * Holds all Telephony Engine related classes.
218  */
219 namespace TelEngine {
220 
221 #ifdef HAVE_GCC_FORMAT_CHECK
222 #define FORMAT_CHECK(f) __attribute__((format(printf,(f),(f)+1)))
223 #else
224 #define FORMAT_CHECK(f)
225 #endif
226 
227 #define YIGNORE(v) while (v) { break; }
228 
229 #ifdef HAVE_BLOCK_RETURN
230 #define YSTRING(s) (*({static const String str("" s);&str;}))
231 #define YATOM(s) (*({static const String* str(0);str ? str : String::atom(str,"" s);}))
232 #else
233 #define YSTRING(s) ("" s)
234 #define YATOM(s) ("" s)
235 #endif
236 
237 #define YSTRING_INIT_HASH ((unsigned) -1)
238 
239 /**
240  * Abort execution (and coredump if allowed) if the abort flag is set.
241  * This function may not return.
242  */
243 YATE_API void abortOnBug();
244 
245 /**
246  * Set the abort on bug flag. The default flag state is false.
247  * @return The old state of the flag.
248  */
249 YATE_API bool abortOnBug(bool doAbort);
250 
251 /**
252  * Standard debugging levels.
253  * The DebugFail level is special - it is always displayed and may abort
254  *  the program if @ref abortOnBug() is set.
255  */
256 enum DebugLevel {
257     DebugFail = 0,
258     DebugTest = 1,
259     DebugCrit = 2,
260     DebugGoOn = DebugCrit,
261     DebugConf = 3,
262     DebugStub = 4,
263     DebugWarn = 5,
264     DebugMild = 6,
265     DebugNote = 7,
266     DebugCall = 8,
267     DebugInfo = 9,
268     DebugAll = 10
269 };
270 
271 /**
272  * Retrieve the current global debug level
273  * @return The current global debug level
274  */
275 YATE_API int debugLevel();
276 
277 /**
278  * Set the current global debug level.
279  * @param level The desired debug level
280  * @return The new global debug level (may be different)
281  */
282 YATE_API int debugLevel(int level);
283 
284 /**
285  * Check if debugging output should be generated
286  * @param level The global debug level we are testing
287  * @return True if messages should be output, false otherwise
288  */
289 YATE_API bool debugAt(int level);
290 
291 /**
292  * Get an ANSI string to colorize debugging output
293  * @param level The debug level who's color is requested.
294  *  Negative or out of range will reset to the default color
295  * @return ANSI string that sets color corresponding to level
296  */
297 YATE_API const char* debugColor(int level);
298 
299 /**
300  * Get the name of a debugging or alarm level
301  * @param level The debug level
302  * @return Short C string describing the level
303  */
304 YATE_API const char* debugLevelName(int level);
305 
306 /**
307  * Holds a local debugging level that can be modified separately from the
308  *  global debugging
309  * @short A holder for a debug level
310  */
311 class YATE_API DebugEnabler
312 {
313 public:
314     /**
315      * Constructor
316      * @param level The initial local debug level
317      * @param enabled Enable debugging on this object
318      */
319     inline DebugEnabler(int level = TelEngine::debugLevel(), bool enabled = true)
m_level(DebugFail)320 	: m_level(DebugFail), m_enabled(enabled), m_chain(0), m_name(0)
321 	{ debugLevel(level); }
322 
~DebugEnabler()323     inline ~DebugEnabler()
324 	{ m_name = 0; m_chain = 0; }
325 
326     /**
327      * Retrieve the current local debug level
328      * @return The current local debug level
329      */
debugLevel()330     inline int debugLevel() const
331 	{ return m_chain ? m_chain->debugLevel() : m_level; }
332 
333     /**
334      * Set the current local debug level.
335      * @param level The desired debug level
336      * @return The new debug level (may be different)
337      */
338     int debugLevel(int level);
339 
340     /**
341      * Retrieve the current debug activation status
342      * @return True if local debugging is enabled
343      */
debugEnabled()344     inline bool debugEnabled() const
345 	{ return m_chain ? m_chain->debugEnabled() : m_enabled; }
346 
347     /**
348      * Set the current debug activation status
349      * @param enable The new debug activation status, true to enable
350      */
debugEnabled(bool enable)351     inline void debugEnabled(bool enable)
352 	{ m_enabled = enable; m_chain = 0; }
353 
354     /**
355      * Get the current debug name
356      * @return Name of the debug activation if set or NULL
357      */
debugName()358     inline const char* debugName() const
359 	{ return m_name; }
360 
361     /**
362      * Check if debugging output should be generated
363      * @param level The debug level we are testing
364      * @return True if messages should be output, false otherwise
365      */
366     bool debugAt(int level) const;
367 
368     /**
369      * Check if this enabler is chained to another one
370      * @return True if local debugging is chained to other enabler
371      */
debugChained()372     inline bool debugChained() const
373 	{ return m_chain != 0; }
374 
375     /**
376      * Chain this debug holder to a parent or detach from existing one
377      * @param chain Pointer to parent debug level, NULL to detach
378      */
379     inline void debugChain(const DebugEnabler* chain = 0)
380 	{ m_chain = (chain != this) ? chain : 0; }
381 
382     /**
383      * Copy debug settings from another object or from engine globals
384      * @param original Pointer to a DebugEnabler to copy settings from
385      */
386     void debugCopy(const DebugEnabler* original = 0);
387 
388 protected:
389     /**
390      * Set the current debug name
391      * @param name Static debug name or NULL
392      */
debugName(const char * name)393     inline void debugName(const char* name)
394 	{ m_name = name; }
395 
396 private:
397     int m_level;
398     bool m_enabled;
399     const DebugEnabler* m_chain;
400     const char* m_name;
401 };
402 
403 #if 0 /* for documentation generator */
404 /**
405  * Convenience macro.
406  * Does the same as @ref Debug if DEBUG is \#defined (compiling for debugging)
407  *  else it does not get compiled at all.
408  */
409 void DDebug(int level, const char* format, ...);
410 
411 /**
412  * Convenience macro.
413  * Does the same as @ref Debug if DEBUG is \#defined (compiling for debugging)
414  *  else it does not get compiled at all.
415  */
416 void DDebug(const char* facility, int level, const char* format, ...);
417 
418 /**
419  * Convenience macro.
420  * Does the same as @ref Debug if DEBUG is \#defined (compiling for debugging)
421  *  else it does not get compiled at all.
422  */
423 void DDebug(const DebugEnabler* local, int level, const char* format, ...);
424 
425 /**
426  * Convenience macro.
427  * Does the same as @ref Debug if XDEBUG is \#defined (compiling for extra
428  * debugging) else it does not get compiled at all.
429  */
430 void XDebug(int level, const char* format, ...);
431 
432 /**
433  * Convenience macro.
434  * Does the same as @ref Debug if XDEBUG is \#defined (compiling for extra
435  * debugging) else it does not get compiled at all.
436  */
437 void XDebug(const char* facility, int level, const char* format, ...);
438 
439 /**
440  * Convenience macro.
441  * Does the same as @ref Debug if XDEBUG is \#defined (compiling for extra
442  * debugging) else it does not get compiled at all.
443  */
444 void XDebug(const DebugEnabler* local, int level, const char* format, ...);
445 
446 /**
447  * Convenience macro.
448  * Does the same as @ref Debug if NDEBUG is not \#defined
449  *  else it does not get compiled at all (compiling for mature release).
450  */
451 void NDebug(int level, const char* format, ...);
452 
453 /**
454  * Convenience macro.
455  * Does the same as @ref Debug if NDEBUG is not \#defined
456  *  else it does not get compiled at all (compiling for mature release).
457  */
458 void NDebug(const char* facility, int level, const char* format, ...);
459 
460 /**
461  * Convenience macro.
462  * Does the same as @ref Debug if NDEBUG is not \#defined
463  *  else it does not get compiled at all (compiling for mature release).
464  */
465 void NDebug(const DebugEnabler* local, int level, const char* format, ...);
466 #endif
467 
468 #if defined(_DEBUG) || defined(DEBUG) || defined(XDEBUG)
469 #undef DEBUG
470 #define DEBUG	1
471 #endif
472 
473 #ifdef DEBUG
474 #define DDebug Debug
475 #else
476 #ifdef _WINDOWS
477 #define DDebug do { break; } while
478 #else
479 #define DDebug(arg...)
480 #endif
481 #endif
482 
483 #ifdef XDEBUG
484 #define XDebug Debug
485 #else
486 #ifdef _WINDOWS
487 #define XDebug do { break; } while
488 #else
489 #define XDebug(arg...)
490 #endif
491 #endif
492 
493 #ifndef NDEBUG
494 #define NDebug Debug
495 #else
496 #ifdef _WINDOWS
497 #define NDebug do { break; } while
498 #else
499 #define NDebug(arg...)
500 #endif
501 #endif
502 
503 /**
504  * Outputs a debug string.
505  * @param level The level of the message
506  * @param format A printf() style format string
507  */
508 YATE_API void Debug(int level, const char* format, ...) FORMAT_CHECK(2);
509 
510 /**
511  * Outputs a debug string for a specific facility.
512  * @param facility Facility that outputs the message
513  * @param level The level of the message
514  * @param format A printf() style format string
515  */
516 YATE_API void Debug(const char* facility, int level, const char* format, ...) FORMAT_CHECK(3);
517 
518 /**
519  * Outputs a debug string for a specific facility.
520  * @param local Pointer to a DebugEnabler holding current debugging settings
521  * @param level The level of the message
522  * @param format A printf() style format string
523  */
524 YATE_API void Debug(const DebugEnabler* local, int level, const char* format, ...) FORMAT_CHECK(3);
525 
526 /**
527  * Outputs a debug string and emits an alarm if a callback is installed
528  * @param component Component that emits the alarm
529  * @param level The level of the alarm
530  * @param format A printf() style format string
531  */
532 YATE_API void Alarm(const char* component, int level, const char* format, ...) FORMAT_CHECK(3);
533 
534 /**
535  * Outputs a debug string and emits an alarm if a callback is installed
536  * @param component Pointer to a DebugEnabler holding component name and debugging settings
537  * @param level The level of the alarm
538  * @param format A printf() style format string
539  */
540 YATE_API void Alarm(const DebugEnabler* component, int level, const char* format, ...) FORMAT_CHECK(3);
541 
542 /**
543  * Outputs a debug string and emits an alarm if a callback is installed
544  * @param component Component that emits the alarm
545  * @param info Extra alarm information
546  * @param level The level of the alarm
547  * @param format A printf() style format string
548  */
549 YATE_API void Alarm(const char* component, const char* info, int level, const char* format, ...) FORMAT_CHECK(4);
550 
551 /**
552  * Outputs a debug string and emits an alarm if a callback is installed
553  * @param component Pointer to a DebugEnabler holding component name and debugging settings
554  * @param info Extra alarm information
555  * @param level The level of the alarm
556  * @param format A printf() style format string
557  */
558 YATE_API void Alarm(const DebugEnabler* component, const char* info, int level, const char* format, ...) FORMAT_CHECK(4);
559 
560 /**
561  * Outputs a string to the debug console with formatting
562  * @param format A printf() style format string
563  */
564 YATE_API void Output(const char* format, ...) FORMAT_CHECK(1);
565 
566 /**
567  * Outputs a debug string with a trace ID.
568  * @param traceId The trace ID associated with this message
569  * @param level The level of the message
570  * @param format A printf() style format string
571  */
572 YATE_API void TraceDebug(const char* traceId, int level, const char* format, ...) FORMAT_CHECK(3);
573 
574 /**
575  * Outputs a debug string with a trace ID.
576  * @param traceId The trace ID associated with this message
577  * @param facility Facility that outputs the message
578  * @param level The level of the message
579  * @param format A printf() style format string
580  */
581 YATE_API void TraceDebug(const char* traceId, const char* facility, int level,
582             const char* format, ...) FORMAT_CHECK(4);
583 
584 /**
585  * Outputs a debug string with a trace ID.
586  * @param traceId The trace ID associated with this message
587  * @param local Pointer to a DebugEnabler holding current debugging settings
588  * @param level The level of the message
589  * @param format A printf() style format string
590  */
591 YATE_API void TraceDebug(const char* traceId, const DebugEnabler* local, int level,
592             const char* format, ...) FORMAT_CHECK(4);
593 
594 
595 #if 0 /* for documentation generator */
596 /**
597  * Outputs a debug string with a trace ID.
598  * @param obj Object from where to get trace ID
599  * @param level The level of the message
600  * @param format A printf() style format string
601  */
602 void TraceDebugObj(GenObject* obj, int level, const char* format, ...);
603 
604 /**
605  * Outputs a debug string with a trace ID.
606  * @param obj Object from where to get trace ID
607  * @param facility Facility that outputs the message
608  * @param level The level of the message
609  * @param format A printf() style format string
610  */
611 void TraceDebugObj(GenObject* obj, const char* facility, int level, const char* format, ...);
612 
613 /**
614  * Outputs a debug string with a trace ID.
615  * @param obj Object from where to get trace ID
616  * @param local Pointer to a DebugEnabler holding current debugging settings
617  * @param level The level of the message
618  * @param format A printf() style format string
619  */
620 void TraceDebugObj(GenObject* obj, const DebugEnabler* local, int level, const char* format, ...);
621 
622 /**
623  * Outputs a debug string only if trace ID is valid.
624  * @param obj Object from where to get trace ID
625  * @param level The level of the message
626  * @param format A printf() style format string
627  */
628 void Trace(GenObject* obj, int level, const char* format, ...);
629 
630 /**
631  * Outputs a debug string only if trace ID is valid.
632  * @param obj Object from where to get trace ID
633  * @param facility Facility that outputs the message
634  * @param level The level of the message
635  * @param format A printf() style format string
636  */
637 void Trace(GenObject* obj, const char* facility, int level, const char* format, ...);
638 
639 /**
640  * Outputs a debug string only if trace ID is valid.
641  * @param obj Object from where to get trace ID
642  * @param local Pointer to a DebugEnabler holding current debugging settings
643  * @param level The level of the message
644  * @param format A printf() style format string
645  */
646 void Trace(GenObject* obj, const DebugEnabler* local, int level, const char* format, ...);
647 
648 /**
649  * Outputs a debug string only if trace ID is valid.
650  * @param obj Object from where to get trace ID
651  * @param level The level of the message
652  * @param format A printf() style format string
653  */
654 void TraceObj(GenObject* obj, int level, const char* format, ...);
655 
656 /**
657  * Outputs a debug string only if trace ID is valid.
658  * @param obj Object from where to get trace ID
659  * @param facility Facility that outputs the message
660  * @param level The level of the message
661  * @param format A printf() style format string
662  */
663 void TraceObj(GenObject* obj, const char* facility, int level, const char* format, ...);
664 
665 /**
666  * Outputs a debug string only if trace ID is valid.
667  * @param obj Object from where to get trace ID
668  * @param local Pointer to a DebugEnabler holding current debugging settings
669  * @param level The level of the message
670  * @param format A printf() style format string
671  */
672 void TraceObj(GenObject* obj, const DebugEnabler* local, int level, const char* format, ...);
673 
674 #endif
675 
676 #define TraceDebugObj(pGenObj,...) \
677 TraceDebug((!!(pGenObj)) ? (pGenObj)->traceId() : "",##__VA_ARGS__)
678 
679 #define Trace(traceId,...) \
680 do { if (!TelEngine::null(traceId)) TraceDebug(traceId,##__VA_ARGS__); } while(false)
681 
682 #define TraceObj(pGenObj,...) \
683 do { if (!!(pGenObj) && (pGenObj)->traceId()) TraceDebug((pGenObj)->traceId(),##__VA_ARGS__); } while (false)
684 
685 
686 /**
687  * Outputs a debug string with trace ID and emits an alarm if a callback is installed
688  * @param traceId The trace ID associated with this message
689  * @param component Component that emits the alarm
690  * @param info Extra alarm information
691  * @param level The level of the alarm
692  * @param format A printf() style format string
693  */
694 YATE_API void TraceAlarm(const char* traceId, const char* component, int level,
695             const char* format, ...) FORMAT_CHECK(4);
696 
697 /**
698  * Outputs a debug string with trace ID and emits an alarm if a callback is installed
699  * @param traceId The trace ID associated with this message
700  * @param component Pointer to a DebugEnabler holding component name and debugging settings
701  * @param level The level of the alarm
702  * @param format A printf() style format string
703  */
704 YATE_API void TraceAlarm(const char* traceId, const DebugEnabler* component,
705             int level, const char* format, ...) FORMAT_CHECK(4);
706 
707 /**
708  * Outputs a debug string with trace ID and emits an alarm if a callback is installed
709  * @param traceId The trace ID associated with this message
710  * @param component Component that emits the alarm
711  * @param info Extra alarm information
712  * @param level The level of the alarm
713  * @param format A printf() style format string
714  */
715 YATE_API void TraceAlarm(const char* traceId, const char* component, const char* info,
716             int level, const char* format, ...) FORMAT_CHECK(5);
717 
718 /**
719  * Outputs a debug string with trace ID and emits an alarm if a callback is installed
720  * @param traceId The trace ID associated with this message
721  * @param component Pointer to a DebugEnabler holding component name and debugging settings
722  * @param info Extra alarm information
723  * @param level The level of the alarm
724  * @param format A printf() style format string
725  */
726 YATE_API void TraceAlarm(const char* traceId, const DebugEnabler* component,
727             const char* info, int level, const char* format, ...) FORMAT_CHECK(5);
728 
729 /**
730  * This class is used as an automatic variable that logs messages on creation
731  *  and destruction (when the instruction block is left or function returns).
732  * IMPORTANT: the name is not copied so it should best be static.
733  * @short An object that logs messages on creation and destruction
734  */
735 class YATE_API Debugger
736 {
737 public:
738     /**
739      * Timestamp formatting
740      */
741     enum Formatting {
742 	None = 0,
743 	Relative,  // from program start
744 	Absolute,  // from EPOCH (1-1-1970)
745 	Textual,   // absolute GMT in YYYYMMDDhhmmss.uuuuuu format
746 	TextLocal, // local time in YYYYMMDDhhmmss.uuuuuu format
747 	TextSep,   // absolute GMT in YYYY-MM-DD_hh:mm:ss.uuuuuu format
748 	TextLSep,  // local time in YYYY-MM-DD_hh:mm:ss.uuuuuu format
749     };
750 
751     /**
752      * The constructor prints the method entry message and indents.
753      * @param name Name of the function or block entered, must be static
754      * @param format printf() style format string
755      */
756     explicit Debugger(const char* name, const char* format = 0, ...);
757 
758     /**
759      * The constructor prints the method entry message and indents.
760      * @param level The level of the message
761      * @param name Name of the function or block entered, must be static
762      * @param format printf() style format string
763      */
764     Debugger(int level, const char* name, const char* format = 0, ...);
765 
766     /**
767      * The destructor prints the method leave message and deindents.
768      */
769     ~Debugger();
770 
771     /**
772      * Set the output callback
773      * @param outFunc Pointer to the output function, NULL to use stderr
774      */
775     static void setOutput(void (*outFunc)(const char*,int) = 0);
776 
777     /**
778      * Set the interactive output callback
779      * @param outFunc Pointer to the output function, NULL to disable
780      */
781     static void setIntOut(void (*outFunc)(const char*,int) = 0);
782 
783     /**
784      * Set the alarm hook callback
785      * @param alarmFunc Pointer to the alarm callback function, NULL to disable
786      */
787     static void setAlarmHook(void (*alarmFunc)(const char*,int,const char*,const char*) = 0);
788 
789     /**
790      * Set the relay hook callback that will process all Output, Debug and Alarm
791      * @param relayFunc Pointer to the relay callback function, NULL to disable
792      */
793     static void setRelayHook(void (*relayFunc)(int,const char*,const char*,const char*) = 0);
794 
795     /**
796      * Enable or disable the debug output
797      * @param enable Set to true to globally enable output
798      * @param colorize Enable ANSI colorization of output
799      */
800     static void enableOutput(bool enable = true, bool colorize = false);
801 
802     /**
803      * Retrieve the start timestamp
804      * @return Start timestamp value in seconds
805      */
806     static uint32_t getStartTimeSec();
807 
808     /**
809      * Retrieve the format of timestamps
810      * @return The current formatting type for timestamps
811      */
812     static Formatting getFormatting();
813 
814     /**
815      * Set the format of timestamps on output messages and set the time start reference
816      * @param format Desired timestamp formatting
817      * @param startTimeSec Optional start timestamp (in seconds)
818      */
819     static void setFormatting(Formatting format, uint32_t startTimeSec = 0);
820 
821     /**
822      * Fill a buffer with a current timestamp prefix
823      * @param buf Buffer to fill, must be at least 28 characters long
824      * @param format Desired timestamp formatting
825      * @return Length of the prefix written in buffer excluding final NUL
826      */
827     static unsigned int formatTime(char* buf, Formatting format = getFormatting());
828 
829     /**
830      * Processes a preformatted string as Output, Debug or Alarm.
831      * This method is intended to relay messages from other processes, DO NOT USE!
832      * @param level The level of the debug or alarm, negative for an output
833      * @param buffer Preformatted text buffer, MUST HAVE SPACE for at least strlen + 2
834      * @param component Component that emits the alarm if applicable
835      * @param info Extra alarm information if applicable
836      */
837     static void relayOutput(int level, char* buffer, const char* component = 0, const char* info = 0);
838 
839 private:
840     const char* m_name;
841     int m_level;
842 };
843 
844 /**
845  * A structure to build (mainly static) Token-to-ID translation tables.
846  * A table of such structures must end with an entry with a null token
847  */
848 struct TokenDict {
849     /**
850      * Token to match
851      */
852     const char* token;
853 
854     /**
855      * Value the token translates to
856      */
857     int value;
858 };
859 
860 /**
861  * A structure to build (mainly static) Token-to-ID translation tables.
862  * Value is 64bit integer.
863  * A table of such structures must end with an entry with a null token
864  */
865 struct TokenDict64 {
866     /**
867      * Token to match
868      */
869     const char* token;
870 
871     /**
872      * Value the token translates to
873      */
874     int64_t value;
875 };
876 
877 class String;
878 class DataBlock;
879 class Mutex;
880 class ObjList;
881 class NamedCounter;
882 
883 #if 0 /* for documentation generator */
884 /**
885  * Macro to ignore the result of a function
886  * @param value Returned value to be ignored, must be interpretable as boolean
887  */
888 void YIGNORE(primitive value);
889 
890 /**
891  * Macro to create a local static String if supported by compiler, use with caution
892  * @param string Literal constant string
893  * @return A const String& if supported, literal string if not supported
894  */
895 constant YSTRING(const char* string);
896 
897 /**
898  * Macro to create a shared static String if supported by compiler, use with caution
899  * @param string Literal constant string
900  * @return A const String& if supported, literal string if not supported
901  */
902 constant YATOM(const char* string);
903 
904 /**
905  * Macro to create a GenObject class from a base class and implement @ref GenObject::getObject
906  * @param type Class that is declared
907  * @param base Base class that is inherited
908  */
909 void YCLASS(class type,class base);
910 
911 /**
912  * Macro to create a GenObject class from two base classes and implement @ref GenObject::getObject
913  * @param type Class that is declared
914  * @param base1 First base class that is inherited
915  * @param base2 Second base class that is inherited
916  */
917 void YCLASS2(class type,class base1,class base2);
918 
919 /**
920  * Macro to create a GenObject class from three base classes and implement @ref GenObject::getObject
921  * @param type Class that is declared
922  * @param base1 First base class that is inherited
923  * @param base2 Second base class that is inherited
924  * @param base3 Third base class that is inherited
925  */
926 void YCLASS3(class type,class base1,class base2,class base3);
927 
928 /**
929  * Macro to implement @ref GenObject::getObject in a derived class
930  * @param type Class that is declared
931  * @param base Base class that is inherited
932  */
933 void YCLASSIMP(class type,class base);
934 
935 /**
936  * Macro to implement @ref GenObject::getObject in a derived class
937  * @param type Class that is declared
938  * @param base1 First base class that is inherited
939  * @param base2 Second base class that is inherited
940  */
941 void YCLASSIMP2(class type,class base1,class base2);
942 
943 /**
944  * Macro to implement @ref GenObject::getObject in a derived class
945  * @param type Class that is declared
946  * @param base1 First base class that is inherited
947  * @param base2 Second base class that is inherited
948  * @param base3 Third base class that is inherited
949  */
950 void YCLASSIMP3(class type,class base1,class base2,class base3);
951 
952 /**
953  * Macro to retrieve a typed pointer to an interface from an object
954  * @param type Class we want to return
955  * @param pntr Pointer to the object we want to get the interface from
956  * @return Pointer to the class we want or NULL
957  */
958 class* YOBJECT(class type,GenObject* pntr);
959 
960 /**
961  * Macro to disable automatic copy and assignment operators
962  * @param type Class that is declared
963  */
964 void YNOCOPY(class type);
965 #endif
966 
967 #define YCLASS(type,base) \
968 public: virtual void* getObject(const String& name) const \
969 { return (name == YATOM(#type)) ? const_cast<type*>(this) : base::getObject(name); }
970 
971 #define YCLASS2(type,base1,base2) \
972 public: virtual void* getObject(const String& name) const \
973 { if (name == YATOM(#type)) return const_cast<type*>(this); \
974   void* tmp = base1::getObject(name); \
975   return tmp ? tmp : base2::getObject(name); }
976 
977 #define YCLASS3(type,base1,base2,base3) \
978 public: virtual void* getObject(const String& name) const \
979 { if (name == YATOM(#type)) return const_cast<type*>(this); \
980   void* tmp = base1::getObject(name); \
981   if (tmp) return tmp; \
982   tmp = base2::getObject(name); \
983   return tmp ? tmp : base3::getObject(name); }
984 
985 #define YCLASSIMP(type,base) \
986 void* type::getObject(const String& name) const \
987 { return (name == YATOM(#type)) ? const_cast<type*>(this) : base::getObject(name); }
988 
989 #define YCLASSIMP2(type,base1,base2) \
990 void* type::getObject(const String& name) const \
991 { if (name == YATOM(#type)) return const_cast<type*>(this); \
992   void* tmp = base1::getObject(name); \
993   return tmp ? tmp : base2::getObject(name); }
994 
995 #define YCLASSIMP3(type,base1,base2,base3) \
996 void* type::getObject(const String& name) const \
997 { if (name == YATOM(#type)) return const_cast<type*>(this); \
998   void* tmp = base1::getObject(name); \
999   if (tmp) return tmp; \
1000   tmp = base2::getObject(name); \
1001   return tmp ? tmp : base3::getObject(name); }
1002 
1003 #define YOBJECT(type,pntr) (static_cast<type*>(GenObject::getObject(YATOM(#type),pntr)))
1004 
1005 #define YNOCOPY(type) private: \
1006 type(const type&); \
1007 void operator=(const type&)
1008 
1009 
1010 /**
1011  * Compute a hash for a 64-bit unsigned integer
1012  * @param val Integer value to hash
1013  * @return Hash value
1014  */
hashInt64(uint64_t val)1015 YATE_API inline uint32_t hashInt64(uint64_t val)
1016 {
1017     return (uint32_t)(((val ^ (val >> 48)) ^ (val >> 32)) ^ (val >> 16));
1018 }
1019 
1020 /**
1021  * Compute a hash for a 32-bit unsigned integer
1022  * @param val Integer value to hash
1023  * @return Hash value
1024  */
hashInt32(uint32_t val)1025 YATE_API inline uint32_t hashInt32(uint32_t val)
1026 {
1027     return (uint32_t)((val ^ (val >> 16)) ^ (val << 16));
1028 }
1029 
1030 /**
1031  * Compute a hash for a pointer
1032  * @param val Pointer to hash
1033  * @return Hash value
1034  */
hashPtr(const void * ptr)1035 YATE_API inline uint32_t hashPtr(const void* ptr)
1036 {
1037 #if (_WORDSIZE == 64)
1038     return hashInt64((uintptr_t)ptr);
1039 #else
1040     return hashInt32((uintptr_t)ptr);
1041 #endif
1042 }
1043 
1044 
1045 /**
1046  * An object with just a public virtual destructor
1047  */
1048 class YATE_API GenObject
1049 {
1050     YNOCOPY(GenObject); // no automatic copies please
1051 public:
1052     /**
1053      * Default constructor
1054      */
1055     GenObject();
1056 
1057     /**
1058      * Destructor.
1059      */
~GenObject()1060     virtual ~GenObject() { setObjCounter(0); }
1061 
1062     /**
1063      * Check if the object is still valid and safe to access.
1064      * Note that you should not trust this result unless the object is locked
1065      *  by other means.
1066      * @return True if the object is still useable
1067      */
1068     virtual bool alive() const;
1069 
1070     /**
1071      * Destroys the object, disposes the memory.
1072      */
1073     virtual void destruct();
1074 
1075     /**
1076      * Get a string representation of this object
1077      * @return A reference to a String representing this object
1078      *  which is either null, the object itself (for objects derived from
1079      *  String) or some form of identification
1080      */
1081     virtual const String& toString() const;
1082 
1083     /**
1084      * Get the trace ID associated with this object
1085      * @return The trace ID or an empty string
1086      */
1087     virtual const String& traceId() const;
1088 
1089     /**
1090      * Get a pointer to a derived class given that class name
1091      * @param name Name of the class we are asking for
1092      * @return Pointer to the requested class or NULL if this object doesn't implement it
1093      */
1094     virtual void* getObject(const String& name) const;
1095 
1096     /**
1097      * Helper method to get the pointer to a derived class
1098      * @param name Name of the class we are asking for
1099      * @param obj Pointer to the object to get derived class from
1100      * @return Pointer to the requested class or NULL if this object doesn't implement it
1101      */
getObject(const String & name,const GenObject * obj)1102     static inline void* getObject(const String& name, const GenObject* obj)
1103 	{ return obj ? obj->getObject(name) : 0; }
1104 
1105     /**
1106      * Get the global state of object counting
1107      * @return True if object counting is enabled
1108      */
getObjCounting()1109     static inline bool getObjCounting()
1110 	{ return s_counting; }
1111 
1112     /**
1113      * Set the global state of object counting
1114      * @param enable True to enable object counting, false to disable
1115      */
setObjCounting(bool enable)1116     static inline void setObjCounting(bool enable)
1117 	{ s_counting = enable; }
1118 
1119     /**
1120      * Get the counter of this object
1121      * @return Pointer to current counter object
1122      */
getObjCounter()1123     inline NamedCounter* getObjCounter() const
1124 	{ return m_counter; }
1125 
1126     /**
1127      * Set the counter of this object
1128      * @param counter New counter object or NULL
1129      * @return Pointer to old counter object
1130      */
1131     NamedCounter* setObjCounter(NamedCounter* counter);
1132 
1133     /**
1134      * Retrieve or allocate an object counter
1135      * @param name Name of the counter
1136      * @param create True to create a new counter if needed
1137      * @return Pointer to existing or new counter object
1138      */
1139     static NamedCounter* getObjCounter(const String& name, bool create = true);
1140 
1141     /**
1142      * Access the object counters list
1143      * @return Reference to the global object counters list
1144      */
1145     static ObjList& getObjCounters();
1146 
1147 private:
1148     NamedCounter* m_counter;
1149     static bool s_counting;
1150 };
1151 
1152 /**
1153  * Helper function that destroys a GenObject only if the pointer is non-NULL.
1154  * Use it instead of the delete operator.
1155  * @param obj Pointer (rvalue) to the object to destroy
1156  */
destruct(GenObject * obj)1157 inline void destruct(GenObject* obj)
1158     { if (obj) obj->destruct(); }
1159 
1160 /**
1161  * Helper template function that destroys a GenObject descendant if the pointer
1162  *  is non-NULL and also zeros out the pointer.
1163  * Use it instead of the delete operator.
1164  * @param obj Reference to pointer (lvalue) to the object to destroy
1165  */
destruct(Obj * & obj)1166 template <class Obj> void destruct(Obj*& obj)
1167     { if (obj) { obj->destruct(); obj = 0; } }
1168 
1169 /**
1170  * A reference counted object.
1171  * Whenever using multiple inheritance you should inherit this class virtually.
1172  */
1173 class YATE_API RefObject : public GenObject
1174 {
1175     YNOCOPY(RefObject); // no automatic copies please
1176 public:
1177     /**
1178      * The constructor initializes the reference counter to 1!
1179      * Use deref() to destruct the object when safe
1180      */
1181     RefObject();
1182 
1183     /**
1184      * Destructor.
1185      */
1186     virtual ~RefObject();
1187 
1188     /**
1189      * Get a pointer to a derived class given that class name
1190      * @param name Name of the class we are asking for
1191      * @return Pointer to the requested class or NULL if this object doesn't implement it
1192      */
1193     virtual void* getObject(const String& name) const;
1194 
1195     /**
1196      * Check if the object is still referenced and safe to access.
1197      * Note that you should not trust this result unless the object is locked
1198      *  by other means.
1199      * @return True if the object is referenced and safe to access
1200      */
1201     virtual bool alive() const;
1202 
1203     /**
1204      * Increments the reference counter if not already zero
1205      * @return True if the object was successfully referenced and is safe to access
1206      */
1207     bool ref();
1208 
1209     /**
1210      * Decrements the reference counter, destroys the object if it reaches zero
1211      * <pre>
1212      * // Deref this object, return quickly if the object was deleted
1213      * if (deref()) return;
1214      * </pre>
1215      * @return True if the object may have been deleted, false if it still exists and is safe to access
1216      */
1217     bool deref();
1218 
1219     /**
1220      * Get the current value of the reference counter
1221      * @return The value of the reference counter
1222      */
refcount()1223     inline int refcount() const
1224 	{ return m_refcount; }
1225 
1226     /**
1227      * Refcounted objects should just have the counter decremented.
1228      * That will destroy them only when the refcount reaches zero.
1229      */
1230     virtual void destruct();
1231 
1232     /**
1233      * Check if a refcounted object is still alive
1234      * @param obj Pointer to the object to check
1235      * @return True if the pointer is not null and the object is referenced
1236      */
alive(const RefObject * obj)1237     inline static bool alive(const RefObject* obj)
1238 	{ return obj && (obj->refcount() > 0); }
1239 
1240     /**
1241      * Check if reference counter manipulations are efficient on this platform.
1242      * If platform does not support atomic operations a mutex pool is used.
1243      * @return True if refcount uses atomic integer operations
1244      */
1245     static bool efficientIncDec();
1246 
1247 protected:
1248     /**
1249      * This method is called when the reference count reaches zero after
1250      *  unlocking the mutex if the call to zeroRefsTest() returned true.
1251      * The default behaviour is to delete the object.
1252      */
1253     virtual void zeroRefs();
1254 
1255     /**
1256      * Bring the object back alive by setting the reference counter to one.
1257      * Note that it works only if the counter was zero previously
1258      * @return True if the object was resurrected - its name may be Lazarus ;-)
1259      */
1260     bool resurrect();
1261 
1262     /**
1263      * Pre-destruction notification, called just before the object is deleted.
1264      * Unlike in the destructor it is safe to call virtual methods here.
1265      * Reimplementing this method allows to perform any object cleanups.
1266      */
1267     virtual void destroyed();
1268 
1269 private:
1270     int m_refcount;
1271     Mutex* m_mutex;
1272 };
1273 
1274 /**
1275  * Internal helper class providing a non-inline method to RefPointer.
1276  * Please don't use this class directly, use @ref RefPointer instead.
1277  * @short Internal helper class
1278  */
1279 class YATE_API RefPointerBase
1280 {
1281 protected:
1282     /**
1283      * Default constructor, initialize to null pointer
1284      */
RefPointerBase()1285     inline RefPointerBase()
1286 	: m_pointer(0) { }
1287 
1288     /**
1289      * Set a new stored pointer
1290      * @param oldptr Pointer to the RefObject of the old stored object
1291      * @param newptr Pointer to the RefObject of the new stored object
1292      * @param pointer A void pointer to the derived class
1293      */
1294     void assign(RefObject* oldptr, RefObject* newptr, void* pointer);
1295 
1296     /**
1297      * The untyped stored pointer that should be casted to a @ref RefObject derived class
1298      */
1299     void* m_pointer;
1300 };
1301 
1302 /**
1303  * @short Templated smart pointer class
1304  */
1305 template <class Obj = RefObject> class RefPointer : public RefPointerBase
1306 {
1307 protected:
1308     /**
1309      * Retrieve the stored pointer
1310      * @return A typed pointer
1311      */
pointer()1312     inline Obj* pointer() const
1313 	{ return static_cast<Obj*>(m_pointer); }
1314 
1315     /**
1316      * Set a new stored pointer
1317      * @param object Pointer to the new stored object
1318      */
1319     inline void assign(Obj* object = 0)
1320 	{ RefPointerBase::assign(pointer(),object,object); }
1321 
1322 public:
1323     /**
1324      * Default constructor - creates a null smart pointer
1325      */
RefPointer()1326     inline RefPointer()
1327 	{ }
1328 
1329     /**
1330      * Copy constructor, references the object
1331      * @param value Original RefPointer
1332      */
RefPointer(const RefPointer<Obj> & value)1333     inline RefPointer(const RefPointer<Obj>& value)
1334 	: RefPointerBase()
1335 	{ assign(value); }
1336 
1337     /**
1338      * Constructs an initialized smart pointer, references the object
1339      * @param object Pointer to object
1340      */
RefPointer(Obj * object)1341     inline RefPointer(Obj* object)
1342 	{ assign(object); }
1343 
1344     /**
1345      * Destructs the pointer and dereferences the object
1346      */
~RefPointer()1347     inline ~RefPointer()
1348 	{ assign(); }
1349 
1350     /**
1351      * Assignment from smart pointer
1352      */
1353     inline RefPointer<Obj>& operator=(const RefPointer<Obj>& value)
1354 	{ assign(value.pointer()); return *this; }
1355 
1356     /**
1357      * Assignment from regular pointer
1358      */
1359     inline RefPointer<Obj>& operator=(Obj* object)
1360 	{ assign(object); return *this; }
1361 
1362     /**
1363      * Conversion to regular pointer operator
1364      * @return The stored pointer
1365      */
1366     inline operator Obj*() const
1367 	{ return pointer(); }
1368 
1369     /**
1370      * Member access operator
1371      */
1372     inline Obj* operator->() const
1373 	{ return pointer(); }
1374 
1375     /**
1376      * Dereferencing operator
1377      */
1378     inline Obj& operator*() const
1379 	{ return *pointer(); }
1380 };
1381 
1382 /**
1383  * @short Templated pointer that can be inserted in a list
1384  */
1385 template <class Obj = GenObject> class GenPointer : public GenObject
1386 {
1387 private:
1388     /**
1389      * The stored pointer
1390      */
1391     Obj* m_pointer;
1392 
1393 public:
1394     /**
1395      * Default constructor - creates a null pointer
1396      */
GenPointer()1397     inline GenPointer()
1398 	: m_pointer(0)
1399 	{ }
1400 
1401     /**
1402      * Copy constructor
1403      * @param value Original GenPointer
1404      */
GenPointer(const GenPointer<Obj> & value)1405     inline GenPointer(const GenPointer<Obj>& value)
1406 	: m_pointer(value)
1407 	{ }
1408 
1409     /**
1410      * Constructs an initialized pointer
1411      * @param object Pointer to object
1412      */
GenPointer(Obj * object)1413     inline GenPointer(Obj* object)
1414 	: m_pointer(object)
1415 	{ }
1416 
1417     /**
1418      * Assignment from another GenPointer
1419      */
1420     inline GenPointer<Obj>& operator=(const GenPointer<Obj>& value)
1421 	{ m_pointer = value; return *this; }
1422 
1423     /**
1424      * Assignment from regular pointer
1425      */
1426     inline GenPointer<Obj>& operator=(Obj* object)
1427 	{ m_pointer = object; return *this; }
1428 
1429     /**
1430      * Conversion to regular pointer operator
1431      * @return The stored pointer
1432      */
1433     inline operator Obj*() const
1434 	{ return m_pointer; }
1435 
1436     /**
1437      * Member access operator
1438      */
1439     inline Obj* operator->() const
1440 	{ return m_pointer; }
1441 
1442     /**
1443      * Dereferencing operator
1444      */
1445     inline Obj& operator*() const
1446 	{ return *m_pointer; }
1447 };
1448 
1449 /**
1450  * A simple single-linked object list handling class
1451  * @short An object list class
1452  */
1453 class YATE_API ObjList : public GenObject
1454 {
1455     YNOCOPY(ObjList); // no automatic copies please
1456 public:
1457     /**
1458      * Creates a new, empty list.
1459      */
1460     ObjList();
1461 
1462     /**
1463      * Destroys the list and everything in it.
1464      */
1465     virtual ~ObjList();
1466 
1467     /**
1468      * Get a pointer to a derived class given that class name
1469      * @param name Name of the class we are asking for
1470      * @return Pointer to the requested class or NULL if this object doesn't implement it
1471      */
1472     virtual void* getObject(const String& name) const;
1473 
1474     /**
1475      * Get the number of elements in the list
1476      * @return Count of items
1477      */
1478     unsigned int length() const;
1479 
1480     /**
1481      * Get the number of non-null objects in the list
1482      * @return Count of items
1483      */
1484     unsigned int count() const;
1485 
1486     /**
1487      * Get the object associated to this list item
1488      * @return Pointer to the object or NULL
1489      */
get()1490     inline GenObject* get() const
1491 	{ return m_obj; }
1492 
1493     /**
1494      * Set the object associated to this list item
1495      * @param obj Pointer to the new object to set
1496      * @param delold True to delete the old object (default)
1497      * @return Pointer to the old object if not destroyed
1498      */
1499     GenObject* set(const GenObject* obj, bool delold = true);
1500 
1501     /**
1502      * Get the next item in the list
1503      * @return Pointer to the next item in list or NULL
1504      */
next()1505     inline ObjList* next() const
1506 	{ return m_next; }
1507 
1508     /**
1509      * Get the last item in the list
1510      * @return Pointer to the last item in list
1511      */
1512     ObjList* last() const;
1513 
1514     /**
1515      * Skip over NULL holding items in the list
1516      * @return Pointer to the first non NULL holding item in list or NULL
1517      */
1518     ObjList* skipNull() const;
1519 
1520     /**
1521      * Advance in the list skipping over NULL holding items
1522      * @return Pointer to the next non NULL holding item in list or NULL
1523      */
1524     ObjList* skipNext() const;
1525 
1526     /**
1527      * Get the object at a specific index in list
1528      * @param index Index of the object to retrieve
1529      * @return Pointer to the object or NULL
1530      */
1531     GenObject* at(int index) const;
1532 
1533     /**
1534      * Pointer-like indexing operator
1535      * @param index Index of the list item to retrieve
1536      * @return Pointer to the list item or NULL
1537      */
1538     ObjList* operator+(int index) const;
1539 
1540     /**
1541      * Array-like indexing operator with signed parameter
1542      * @param index Index of the object to retrieve
1543      * @return Pointer to the object or NULL
1544      */
1545     inline GenObject* operator[](signed int index) const
1546 	{ return at(index); }
1547 
1548     /**
1549      * Array-like indexing operator with unsigned parameter
1550      * @param index Index of the object to retrieve
1551      * @return Pointer to the object or NULL
1552      */
1553     inline GenObject* operator[](unsigned int index) const
1554 	{ return at(index); }
1555 
1556     /**
1557      * Array-like indexing operator
1558      * @param str String value of the object to locate
1559      * @return Pointer to the object or NULL
1560      */
1561     GenObject* operator[](const String& str) const;
1562 
1563     /**
1564      * Get the item in the list that holds an object
1565      * @param obj Pointer to the object to search for
1566      * @return Pointer to the found item or NULL
1567      */
1568     ObjList* find(const GenObject* obj) const;
1569 
1570     /**
1571      * Get the item in the list that holds an object by String value
1572      * @param str String value (toString) of the object to search for
1573      * @return Pointer to the found item or NULL
1574      */
1575     ObjList* find(const String& str) const;
1576 
1577     /**
1578      * Get the position in list of a GenObject by a pointer to it
1579      * @param obj Pointer to the object to search for
1580      * @return Index of object in list, -1 if not found
1581      */
1582     int index(const GenObject* obj) const;
1583 
1584     /**
1585      * Get the position in list of the first GenObject with a given value
1586      * @param str String value (toString) of the object to search for
1587      * @return Index of object in list, -1 if not found
1588      */
1589     int index(const String& str) const;
1590 
1591     /**
1592      * Insert an object at this point
1593      * @param obj Pointer to the object to insert
1594      * @param compact True to replace NULL values in list if possible
1595      * @return A pointer to the inserted list item
1596      */
1597     ObjList* insert(const GenObject* obj, bool compact = true);
1598 
1599     /**
1600      * Append an object to the end of the list
1601      * @param obj Pointer to the object to append
1602      * @param compact True to replace NULL values in list if possible
1603      * @return A pointer to the inserted list item
1604      */
1605     ObjList* append(const GenObject* obj, bool compact = true);
1606 
1607     /**
1608      * Set unique entry in this list. If not found, append it to the list
1609      * @param obj Pointer to the object to uniquely set in the list
1610      * @param compact True to replace NULL values in list if possible
1611      * @return A pointer to the set list item
1612      */
1613     ObjList* setUnique(const GenObject* obj, bool compact = true);
1614 
1615     /**
1616      * Delete this list item
1617      * @param delobj True to delete the object (default)
1618      * @return Pointer to the object if not destroyed
1619      */
1620     GenObject* remove(bool delobj = true);
1621 
1622     /**
1623      * Delete the list item that holds a given object
1624      * @param obj Object to search in the list
1625      * @param delobj True to delete the object (default)
1626      * @return Pointer to the object if not destroyed
1627      */
1628     GenObject* remove(GenObject* obj, bool delobj = true);
1629 
1630     /**
1631      * Delete the first list item that holds an object with a iven value
1632      * @param str String value (toString) of the object to remove
1633      * @param delobj True to delete the object (default)
1634      * @return Pointer to the object if not destroyed
1635      */
1636     GenObject* remove(const String& str, bool delobj = true);
1637 
1638     /**
1639      * Clear the list and optionally delete all contained objects
1640      */
1641     void clear();
1642 
1643     /**
1644      * Remove all empty objects in the list
1645      */
1646     void compact();
1647 
1648     /**
1649      * Get the automatic delete flag
1650      * @return True if will delete on destruct, false otherwise
1651      */
autoDelete()1652     inline bool autoDelete()
1653 	{ return m_delete; }
1654 
1655     /**
1656      * Set the automatic delete flag
1657      * @param autodelete True to delete on destruct, false otherwise
1658      */
setDelete(bool autodelete)1659     inline void setDelete(bool autodelete)
1660 	{ m_delete = autodelete; }
1661 
1662     /**
1663      * A static empty object list
1664      * @return Reference to a static empty list
1665      */
1666     static const ObjList& empty();
1667 
1668     /**
1669      * Sort this list
1670      * @param callbackCompare pointer to a callback function that should compare two objects.
1671      * <pre>
1672      *     obj1 First object of the comparation
1673      *     obj2 Second object of the comparation
1674      *     context Data context
1675      *     return 0 if the objects are equal; positive value if obj2 > obj1; negative value if obj1 > obj2
1676      *     Note: the function should expect receiving null pointers
1677      * </pre>
1678      * @param context Context data.
1679      */
1680     void sort(int (*callbackCompare)(GenObject* obj1, GenObject* obj2, void* context), void* context = 0);
1681 private:
1682     ObjList* m_next;
1683     GenObject* m_obj;
1684     bool m_delete;
1685 };
1686 
1687 /**
1688  * Simple vector class that holds objects derived from GenObject
1689  * @short A vector holding GenObjects
1690  */
1691 class YATE_API ObjVector : public GenObject
1692 {
1693     YNOCOPY(ObjVector); // no automatic copies please
1694 public:
1695     /**
1696      * Constructor of a zero capacity vector
1697      * @param autodelete True to delete objects on destruct, false otherwise
1698      */
1699     inline explicit ObjVector(bool autodelete = true)
1700 	: m_length(0), m_objects(0), m_delete(autodelete)
1701 	{ }
1702 
1703     /**
1704      * Constructor of an empty vector
1705      * @param maxLen Maximum number of objects the vector can hold
1706      * @param autodelete True to delete objects on destruct, false otherwise
1707      */
1708     ObjVector(unsigned int maxLen, bool autodelete = true);
1709 
1710     /**
1711      * Constructor from an object list
1712      * @param list List of objects to store in vector
1713      * @param move True to move elements from list, false to just copy the pointer
1714      * @param maxLen Maximum number of objects to put in vector, zero to put all
1715      * @param autodelete True to delete objects on destruct, false otherwise
1716      */
1717     ObjVector(ObjList& list, bool move = true, unsigned int maxLen = 0, bool autodelete = true);
1718 
1719     /**
1720      * Destroys the vector and the objects if automatic delete is set
1721      */
1722     virtual ~ObjVector();
1723 
1724     /**
1725      * Get a pointer to a derived class given that class name
1726      * @param name Name of the class we are asking for
1727      * @return Pointer to the requested class or NULL if this object doesn't implement it
1728      */
1729     virtual void* getObject(const String& name) const;
1730 
1731     /**
1732      * Get the capacity of the vector
1733      * @return Number of items the vector can hold
1734      */
length()1735     inline unsigned int length() const
1736 	{ return m_length; }
1737 
1738     /**
1739      * Get the number of non-null objects in the vector
1740      * @return Count of items
1741      */
1742     unsigned int count() const;
1743 
1744     /**
1745      * Check if the vector is empty
1746      * @return True if the vector contains no objects
1747      */
1748     bool null() const;
1749 
1750     /**
1751      * Get the object at a specific index in vector
1752      * @param index Index of the object to retrieve
1753      * @return Pointer to the object or NULL
1754      */
at(int index)1755     inline GenObject* at(int index) const
1756 	{ return (index >= 0 && index < (int)m_length) ? m_objects[index] : 0; }
1757 
1758     /**
1759      * Indexing operator with signed parameter
1760      * @param index Index of the object to retrieve
1761      * @return Pointer to the object or NULL
1762      */
1763     inline GenObject* operator[](signed int index) const
1764 	{ return at(index); }
1765 
1766     /**
1767      * Indexing operator with unsigned parameter
1768      * @param index Index of the object to retrieve
1769      * @return Pointer to the object or NULL
1770      */
1771     inline GenObject* operator[](unsigned int index) const
1772 	{ return at(index); }
1773 
1774     /**
1775      * Clear the vector and assign objects from a list
1776      * @param list List of objects to store in vector
1777      * @param move True to move elements from list, false to just copy the pointer
1778      * @param maxLen Maximum number of objects to put in vector, zero to put all
1779      * @return Capacity of the vector
1780      */
1781     unsigned int assign(ObjList& list, bool move = true, unsigned int maxLen = 0);
1782 
1783     /**
1784      * Retrieve and remove an object from the vector
1785      * @param index Index of the object to retrieve
1786      * @return Pointer to the stored object, NULL for out of bound index
1787      */
1788     GenObject* take(unsigned int index);
1789 
1790     /**
1791      * Store an object in the vector
1792      * @param obj Object to store in vector
1793      * @param index Index of the object to store
1794      * @return True for success, false if index was out of bounds
1795      */
1796     bool set(GenObject* obj, unsigned int index);
1797 
1798     /**
1799      * Get the position in vector of a GenObject by a pointer to it
1800      * @param obj Pointer to the object to search for
1801      * @return Index of object in vector, -1 if not found
1802      */
1803     int index(const GenObject* obj) const;
1804 
1805     /**
1806      * Get the position in vector of the first GenObject with a given value
1807      * @param str String value (toString) of the object to search for
1808      * @return Index of object in vector, -1 if not found
1809      */
1810     int index(const String& str) const;
1811 
1812     /**
1813      * Clear the vector and optionally delete all contained objects
1814      */
1815     void clear();
1816 
1817     /**
1818      * Get the automatic delete flag
1819      * @return True if will delete objects on destruct, false otherwise
1820      */
autoDelete()1821     inline bool autoDelete()
1822 	{ return m_delete; }
1823 
1824     /**
1825      * Set the automatic delete flag
1826      * @param autodelete True to delete objects on destruct, false otherwise
1827      */
setDelete(bool autodelete)1828     inline void setDelete(bool autodelete)
1829 	{ m_delete = autodelete; }
1830 
1831 private:
1832     unsigned int m_length;
1833     GenObject** m_objects;
1834     bool m_delete;
1835 };
1836 
1837 /**
1838  * A simple Array class derivated from RefObject
1839  * It uses one ObjList to keep the pointers to other ObjList's.
1840  * Data is organized in columns - the main ObjList holds pointers to one
1841  *  ObjList for each column.
1842  * This class has been written by Diana
1843  * @short A list based Array
1844  */
1845 class YATE_API Array : public RefObject
1846 {
1847 public:
1848     /**
1849      * Creates a new empty array.
1850      * @param columns Initial number of columns
1851      * @param rows Initial number of rows
1852      */
1853     explicit Array(int columns = 0, int rows = 0);
1854 
1855     /**
1856      * Destructor. Destructs all objects in the array
1857      */
1858     virtual ~Array();
1859 
1860     /**
1861      * Get a pointer to a derived class given that class name
1862      * @param name Name of the class we are asking for
1863      * @return Pointer to the requested class or NULL if this object doesn't implement it
1864      */
1865     virtual void* getObject(const String& name) const;
1866 
1867     /**
1868      * Insert a row of objects
1869      * @param row List of objects to insert or NULL
1870      * @param index Number of the row to insert before, negative to append
1871      * @return True for success, false if index was larger than the array
1872      */
1873     bool addRow(ObjList* row = 0, int index = -1);
1874 
1875     /**
1876      * Insert a column of objects
1877      * @param column List of objects to insert or NULL
1878      * @param index Number of the column to insert before, negative to append
1879      * @return True for success, false if index was larger than the array
1880      */
1881     bool addColumn(ObjList* column = 0, int index = -1);
1882 
1883     /**
1884      * Delete an entire row of objects
1885      * @param index Number of the row to delete
1886      * @return True for success, false if index was out of bounds
1887      */
1888     bool delRow(int index);
1889 
1890     /**
1891      * Delete an entire column of objects
1892      * @param index Number of the column to delete
1893      * @return True for success, false if index was out of bounds
1894      */
1895     bool delColumn(int index);
1896 
1897     /**
1898      * Retrieve an object from the array
1899      * @param column Number of the column in the array
1900      * @param row Number of the row in the array
1901      * @return Pointer to the stored object, NULL for out of bound indexes
1902      */
1903     GenObject* get(int column, int row) const;
1904 
1905     /**
1906      * Retrieve and remove an object from the array
1907      * @param column Number of the column in the array
1908      * @param row Number of the row in the array
1909      * @return Pointer to the stored object, NULL for out of bound indexes
1910      */
1911     GenObject* take(int column, int row);
1912 
1913     /**
1914      * Store an object in the array
1915      * @param obj Object to store in the array
1916      * @param column Number of the column in the array
1917      * @param row Number of the row in the array
1918      * @return True for success, false if indexes were out of bounds
1919      */
1920     bool set(GenObject* obj, int column, int row);
1921 
1922     /**
1923      * Get the number of rows in the array
1924      * @return Total number of rows
1925      */
getRows()1926     inline int getRows() const
1927 	{ return m_rows; }
1928 
1929     /**
1930      * Get the number of columns in the array
1931      * @return Total number of columns
1932      */
getColumns()1933     inline int getColumns() const
1934 	{ return m_columns; }
1935 
1936     /**
1937      * Retrieve a column.
1938      * Note: Use the returned list only to get or set data.
1939      *  List items must not be removed or appended
1940      * @param column Column to retrieve
1941      * @return Pointer to column list, NULL for out of bound indexes
1942      */
getColumn(int column)1943     inline ObjList* getColumn(int column) const {
1944 	    if (column >= 0 || column < m_columns)
1945 		return static_cast<ObjList*>(m_obj[column]);
1946 	    return 0;
1947 	}
1948 
1949 private:
1950     int m_rows;
1951     int m_columns;
1952     ObjList m_obj;
1953 };
1954 
1955 class Regexp;
1956 class StringMatchPrivate;
1957 
1958 /**
1959  * A simple class to hold a single Unicode character and convert it to / from UTF-8
1960  * @short A single Unicode character
1961  */
1962 class YATE_API UChar
1963 {
1964 public:
1965     enum Endianness {
1966 	LE = 0,
1967 	BE = 1,
1968 	Native = 2,
1969     };
1970     /**
1971      * Constructor from unsigned numeric code
1972      * @param code Code of the Unicode character
1973      */
1974     inline explicit UChar(uint32_t code = 0)
m_chr(code)1975 	: m_chr(code)
1976 	{ encode(); }
1977 
1978     /**
1979      * Constructor from signed numeric code
1980      * @param code Code of the Unicode character
1981      */
UChar(int32_t code)1982     inline explicit UChar(int32_t code)
1983 	: m_chr((code < 0) ? 0 : code)
1984 	{ encode(); }
1985 
1986     /**
1987      * Constructor from signed character
1988      * @param code Character to construct from
1989      */
UChar(signed char code)1990     inline explicit UChar(signed char code)
1991 	: m_chr((unsigned char)code)
1992 	{ encode(); }
1993 
1994     /**
1995      * Constructor from unsigned character
1996      * @param code Character to construct from
1997      */
UChar(unsigned char code)1998     inline explicit UChar(unsigned char code)
1999 	: m_chr(code)
2000 	{ encode(); }
2001 
2002     /**
2003      * Assignment operator from a character code
2004      * @param code Character code to assign
2005      * @return Reference to this object
2006      */
2007     inline UChar& operator=(uint32_t code)
2008 	{ m_chr = code; encode(); return *this; }
2009 
2010     /**
2011      * Assignment operator from a character
2012      * @param code Character to assign
2013      * @return Reference to this object
2014      */
2015     inline UChar& operator=(char code)
2016 	{ m_chr = (unsigned char)code; encode(); return *this; }
2017 
2018     /**
2019      * Get the Unicode value of the character
2020      * @return Code of the character as defined by Unicode
2021      */
code()2022     inline uint32_t code() const
2023 	{ return m_chr; }
2024 
2025     /**
2026      * Get the value of the character as UTF-8 string.
2027      * @return The character as UTF-8 C string
2028      */
c_str()2029     inline const char* c_str() const
2030 	{ return m_str; }
2031 
2032     /**
2033      * Conversion to "const char *" operator.
2034      * @return Pointer to the internally stored UTF-8 string
2035      */
2036     inline operator const char*() const
2037 	{ return m_str; };
2038 
2039     /**
2040      * Decode the first Unicode character from an UTF-8 C string
2041      * @param str String to extract from, will be advanced past the character
2042      * @param maxChar Maximum accepted Unicode character code
2043      * @param overlong Accept overlong UTF-8 sequences (dangerous!)
2044      * @return True if an Unicode character was decoded from string
2045      */
2046     bool decode(const char*& str, uint32_t maxChar = 0x10ffff, bool overlong = false);
2047 
2048     /**
2049      * Decode the first Unicode character from an UTF-16 string
2050      * @param buff Input buffer, advanced if decoding succeeds
2051      * @param len Length of input buffer, updated if decoding succeeds
2052      * @param order Endianness to use for decoding the character
2053      * @param maxChar Maximum accepted Unicode character code
2054      * @return True if decoding succeeded, false otherwise
2055      */
2056     bool decode(uint16_t*& buff, unsigned int& len, Endianness order, uint32_t maxChar = 0x10ffff);
2057 
2058     /**
2059      * Decode the first Unicode character from an UTF-16 string
2060      * @param buff Input buffer from which to decode the character
2061      * @param order Endianness to use for decoding the character
2062      * @param maxChar Maximum accepted Unicode character code
2063      * @return True if decoding succeeded, false otherwise
2064      */
2065     bool decode(DataBlock& buff, Endianness order, uint32_t maxChar = 0x10ffff);
2066 
2067     /**
2068      * Encode the Unicode character to UTF-16 into a given buffer
2069      * @param buff Buffer where to put encoded character, advanced after encoding
2070      * @param len Available space in given buffer, updated after encoding
2071      * @param order Endianness to use for encoding the character
2072      * @return True if decoding succeeded, false otherwise
2073      */
2074     bool encode(uint16_t*& buff, unsigned int& len, Endianness order);
2075 
2076     /**
2077      * Encode the Unicode character to UTF-16 into a DataBlock
2078      * @param buff DataBlock to which the encoded character is to be appended
2079      * @param order Endianness to use for encoding the character
2080      * @return True if decoding succeeded, false otherwise
2081      */
2082     bool encode(DataBlock& buff, Endianness order);
2083 
2084     /**
2085      * Decode a UTF-16 encoded string
2086      * @param out String to append the decoded characters to
2087      * @param buff Input buffer to decode, advanced as decoding occurs
2088      * @param len Length of input buffer, decremented as decoding occurs
2089      * @param order Endianness to use for decoding
2090      * @param checkBOM Check for presence of BOM and interpret accordingly if present
2091      * @param maxChar Maximum accepted Unicode character code
2092      * @return True if decoding succeeded, false otherwise
2093      */
2094     static bool decode(String& out, uint16_t*& buff, unsigned int& len, Endianness order, bool checkBOM = false, uint32_t maxChar = 0x10ffff);
2095 
2096     /**
2097      * Encode a string to UTF-16
2098      * @param out DataBlock to which encoded data is to be appended
2099      * @param str String to be encoded
2100      * @param order Endianness to use for encoding the character
2101      * @param addBOM True to add BOM to the resulting encoding
2102      * @return True if encoding succeeded, false otherwise
2103      */
2104     static bool encode(DataBlock& out, const char*& str, Endianness order, bool addBOM = false);
2105 
2106     /**
2107      * Encode a string to UTF-16 into a given buffer
2108      * @param buff Buffer where to put encoded character, advanced after encoding
2109      * @param len Available space in given buffer, updated after encoding
2110      * @param str String to be encoded
2111      * @param order Endianness to use for encoding the character
2112      * @param addBOM True to add BOM to the resulting encoding
2113      * @return True if encoding succeeded, false otherwise
2114      */
2115     static bool encode(uint16_t*& buff, unsigned int& len, const char*& str, Endianness order, bool addBOM = false);
2116 
2117 private:
2118     void encode();
2119     uint32_t m_chr;
2120     char m_str[8];
2121 };
2122 
2123 /**
2124  * A simple string handling class for C style (one byte) strings.
2125  * For simplicity and read speed no copy-on-write is performed.
2126  * Strings have hash capabilities and comparations are using the hash
2127  * for fast inequality check.
2128  * @short A C-style string handling class
2129  */
2130 class YATE_API String : public GenObject
2131 {
2132 public:
2133     enum Align {
2134 	Left = 0,
2135 	Center,
2136 	Right
2137     };
2138 
2139     /**
2140      * Creates a new, empty string.
2141      */
2142     String();
2143 
2144     /**
2145      * Creates a new initialized string.
2146      * @param value Initial value of the string
2147      * @param len Length of the data to copy, -1 for full string
2148      */
2149     String(const char* value, int len = -1);
2150 
2151     /**
2152      * Creates a new initialized string.
2153      * @param value Character to fill the string
2154      * @param repeat How many copies of the character to use
2155      */
2156     explicit String(char value, unsigned int repeat = 1);
2157 
2158     /**
2159      * Creates a new initialized string from a 32 bit integer.
2160      * @param value Value to convert to string
2161      */
2162     explicit String(int32_t value);
2163 
2164     /**
2165      * Creates a new initialized string from a 32 bit unsigned int.
2166      * @param value Value to convert to string
2167      */
2168     explicit String(uint32_t value);
2169 
2170     /**
2171      * Creates a new initialized string from a 64 bit integer.
2172      * @param value Value to convert to string
2173      */
2174     explicit String(int64_t value);
2175 
2176     /**
2177      * Creates a new initialized string from a 64 bit unsigned int.
2178      * @param value Value to convert to string
2179      */
2180     explicit String(uint64_t value);
2181 
2182     /**
2183      * Creates a new initialized string from a boolean.
2184      * @param value Value to convert to string
2185      */
2186     explicit String(bool value);
2187 
2188     /**
2189      * Creates a new initialized string from a double value.
2190      * @param value Value to convert to string
2191      */
2192     explicit String(double value);
2193 
2194     /**
2195      * Copy constructor.
2196      * @param value Initial value of the string
2197      */
2198     String(const String& value);
2199 
2200     /**
2201      * Constructor from String pointer.
2202      * @param value Initial value of the string
2203      */
2204     String(const String* value);
2205 
2206     /**
2207      * Destroys the string, disposes the memory.
2208      */
2209     virtual ~String();
2210 
2211     /**
2212      * Get a pointer to a derived class given that class name
2213      * @param name Name of the class we are asking for
2214      * @return Pointer to the requested class or NULL if this object doesn't implement it
2215      */
2216     virtual void* getObject(const String& name) const;
2217 
2218     /**
2219      * A static null String
2220      * @return Reference to a static empty String
2221      */
2222     static const String& empty();
2223 
2224     /**
2225      * A standard text representation of boolean values
2226      * @param value Boolean value to convert
2227      * @return Pointer to a text representation of the value
2228      */
boolText(bool value)2229     inline static const char* boolText(bool value)
2230 	{ return value ? "true" : "false"; }
2231 
2232     /**
2233      * Get the value of the stored string.
2234      * @return The stored C string which may be NULL.
2235      */
c_str()2236     inline const char* c_str() const
2237 	{ return m_string; }
2238 
2239     /**
2240      * Get a valid non-NULL C string.
2241      * @return The stored C string or a static "".
2242      */
safe()2243     inline const char* safe() const
2244 	{ return m_string ? m_string : ""; }
2245 
2246     /**
2247      * Get a valid non-NULL C string with a provided default.
2248      * @param defStr Default C string to return if stored is NULL
2249      * @return The stored C string, the default or a static "".
2250      */
safe(const char * defStr)2251     inline const char* safe(const char* defStr) const
2252 	{ return m_string ? m_string : (defStr ? defStr : ""); }
2253 
2254     /**
2255      * Get the length of the stored string.
2256      * @return The length of the stored string, zero for NULL.
2257      */
length()2258     inline unsigned int length() const
2259 	{ return m_length; }
2260 
2261     /**
2262      * Checks if the string holds a NULL pointer.
2263      * @return True if the string holds NULL, false otherwise.
2264      */
null()2265     inline bool null() const
2266 	{ return !m_string; }
2267 
2268     /**
2269      * Get the number of characters in a string assuming UTF-8 encoding
2270      * @param value C string to compute Unicode length
2271      * @param maxChar Maximum accepted Unicode character code
2272      * @param overlong Accept overlong UTF-8 sequences (dangerous!)
2273      * @return Count of Unicode characters, -1 if not valid UTF-8
2274      */
2275     static int lenUtf8(const char* value, uint32_t maxChar = 0x10ffff, bool overlong = false);
2276 
2277     /**
2278      * Get the number of characters in the string assuming UTF-8 encoding
2279      * @param maxChar Maximum accepted Unicode character code
2280      * @param overlong Accept overlong UTF-8 sequences (dangerous!)
2281      * @return Count of Unicode characters, -1 if not valid UTF-8
2282      */
2283     inline int lenUtf8(uint32_t maxChar = 0x10ffff, bool overlong = false) const
2284 	{ return lenUtf8(m_string,maxChar,overlong); }
2285 
2286 
2287     /**
2288      * Fix an UTF-8 encoded string by replacing invalid sequences
2289      * @param replace String to replace invalid sequences, use U+FFFD if null
2290      * @param maxChar Maximum accepted Unicode character code
2291      * @param overlong Accept overlong UTF-8 sequences (dangerous!)
2292      * @return Count of invalid UTF-8 sequences that were replaced
2293      */
2294     int fixUtf8(const char* replace = 0, uint32_t maxChar = 0x10ffff, bool overlong = false);
2295 
2296      /**
2297      * Encode flags from dictionary values
2298      * @param tokens The dictionary containing the flags
2299      * @return Encoded flags
2300      */
2301     unsigned int encodeFlags(const TokenDict* tokens) const;
2302 
2303      /**
2304      * Encode flags from dictionary values
2305      * @param tokens The dictionary containing the flags
2306      * @return Encoded flags
2307      */
2308     uint64_t encodeFlags(const TokenDict64* tokens) const;
2309 
2310      /**
2311      * Decodoe flags from dictionary values
2312      * @param flags The flags
2313      * @param tokens The dictionary containing the flags
2314      * @param unknownflag True (default) to add unknown flags
2315      * @return Decoded flags
2316      */
2317     const String& decodeFlags(unsigned int flags, const TokenDict* tokens, bool unknownflag = true);
2318 
2319      /**
2320      * Decode flags from dictionary values
2321      * @param flags The flags
2322      * @param tokens The dictionary containing the flags
2323      * @param unknownflag True (default) to add unknown flags
2324      * @return Decoded flags
2325      */
2326      const String& decodeFlags(uint64_t flags, const TokenDict64* tokens, bool unknownflag = true);
2327     /**
2328      * Check if a string starts with UTF-8 Byte Order Mark
2329      * @param str String to check for BOM
2330      * @return True if the string starts with UTF-8 BOM
2331      */
checkBOM(const char * str)2332     inline static bool checkBOM(const char* str)
2333 	{ return str && (str[0] == '\357') && (str[1] == '\273') && (str[2] == '\277'); }
2334 
2335     /**
2336      * Check if this string starts with UTF-8 Byte Order Mark
2337      * @return True if the string starts with UTF-8 BOM
2338      */
checkBOM()2339     inline bool checkBOM() const
2340 	{ return checkBOM(c_str()); }
2341 
2342     /**
2343      * Advance a const string past an UTF-8 Byte Order Mark
2344      * @param str String to check for and strip BOM
2345      * @return True if the string started with UTF-8 BOM
2346      */
stripBOM(const char * & str)2347     inline static bool stripBOM(const char*& str)
2348 	{ return checkBOM(str) && (str += 3); }
2349 
2350     /**
2351      * Advance a string past an UTF-8 Byte Order Mark
2352      * @param str String to check for and strip BOM
2353      * @return True if the string started with UTF-8 BOM
2354      */
stripBOM(char * & str)2355     inline static bool stripBOM(char*& str)
2356 	{ return checkBOM(str) && (str += 3); }
2357 
2358     /**
2359      * Strip an UTF-8 Byte Order Mark from the start of this string
2360      * @return True if the string started with UTF-8 BOM
2361      */
stripBOM()2362     inline bool stripBOM()
2363 	{ return checkBOM(c_str()) && &(*this = c_str() + 3); }
2364 
2365     /**
2366      * Get the hash of the contained string.
2367      * @return The hash of the string.
2368      */
hash()2369     inline unsigned int hash() const
2370 	{
2371 	    if (m_hash == YSTRING_INIT_HASH)
2372 		m_hash = hash(m_string);
2373 	    return m_hash;
2374 	}
2375 
2376     /**
2377      * Get the hash of an arbitrary string.
2378      * @param value C string to hash
2379      * @param h Old hash value for incremental hashing
2380      * @return The hash of the string.
2381      */
2382     static unsigned int hash(const char* value, unsigned int h = 0);
2383 
2384     /**
2385      * Clear the string and free the memory
2386      */
2387     void clear();
2388 
2389     /**
2390      * Extract the caracter at a given index
2391      * @param index Index of character in string
2392      * @return Character at given index or 0 if out of range
2393      */
2394     char at(int index) const;
2395 
2396     /**
2397      * Substring extraction
2398      * @param offs Offset of the substring, negative to count from end
2399      * @param len Length of the substring, -1 for everything possible
2400      * @return A copy of the requested substring
2401      */
2402     String substr(int offs, int len = -1) const;
2403 
2404     /**
2405      * Strip off leading and trailing blank characters
2406      */
2407     String& trimBlanks();
2408 
2409     /**
2410      * Strip off leading and trailing whitespace characters
2411      *  (blank, tabs, form-feed, newlines)
2412      */
2413     String& trimSpaces();
2414 
2415     /**
2416      * Override GenObject's method to return this String
2417      * @return A reference to this String
2418      */
2419     virtual const String& toString() const;
2420 
2421     /**
2422      * Convert the string to an integer value.
2423      * @param defvalue Default to return if the string is not a number
2424      * @param base Numeration base, 0 to autodetect
2425      * @param minvalue Minimum value allowed
2426      * @param maxvalue Maximum value allowed
2427      * @param clamp Control the out of bound values: true to adjust to the nearest
2428      *  bound, false to return the default value
2429      * @return The integer interpretation or defvalue.
2430      */
2431     int toInteger(int defvalue = 0, int base = 0, int minvalue = INT_MIN,
2432 	int maxvalue = INT_MAX, bool clamp = true) const;
2433 
2434     /**
2435      * Convert the string to an integer value looking up first a token table.
2436      * @param tokens Pointer to an array of tokens to lookup first
2437      * @param defvalue Default to return if the string is not a token or number
2438      * @param base Numeration base, 0 to autodetect
2439      * @return The integer interpretation or defvalue.
2440      */
2441     int toInteger(const TokenDict* tokens, int defvalue = 0, int base = 0) const;
2442 
2443     /**
2444      * Convert the string to an long integer value.
2445      * @param defvalue Default to return if the string is not a number
2446      * @param base Numeration base, 0 to autodetect
2447      * @param minvalue Minimum value allowed
2448      * @param maxvalue Maximum value allowed
2449      * @param clamp Control the out of bound values: true to adjust to the nearest
2450      *  bound, false to return the default value
2451      * @return The long integer interpretation or defvalue.
2452      */
2453     long int toLong(long int defvalue = 0, int base = 0, long int minvalue = LONG_MIN,
2454 	long int maxvalue = LONG_MAX, bool clamp = true) const;
2455 
2456     /**
2457      * Convert the string to an 64 bit integer value.
2458      * @param defvalue Default to return if the string is not a number
2459      * @param base Numeration base, 0 to autodetect
2460      * @param minvalue Minimum value allowed
2461      * @param maxvalue Maximum value allowed
2462      * @param clamp Control the out of bound values: true to adjust to the nearest
2463      *  bound, false to return the default value
2464      * @return The 64 bit integer interpretation or defvalue.
2465      */
2466     int64_t toInt64(int64_t defvalue = 0, int base = 0, int64_t minvalue = LLONG_MIN,
2467 	int64_t maxvalue = LLONG_MAX, bool clamp = true) const;
2468 
2469     /**
2470      * Convert the string to an unsigned 64 bit integer value.
2471      * @param defvalue Default to return if the string is not a number
2472      * @param base Numeration base, 0 to autodetect
2473      * @param minvalue Minimum value allowed
2474      * @param maxvalue Maximum value allowed
2475      * @param clamp Control the out of bound values: true to adjust to the nearest
2476      *  bound, false to return the default value
2477      * @return The unsigned 64 bit integer interpretation or defvalue.
2478      */
2479     uint64_t toUInt64(uint64_t defvalue = 0, int base = 0, uint64_t minvalue = 0,
2480         uint64_t maxvalue = ULLONG_MAX, bool clamp = true) const;
2481 
2482     /**
2483      * Convert the string to a floating point value.
2484      * @param defvalue Default to return if the string is not a number
2485      * @return The floating-point interpretation or defvalue.
2486      */
2487     double toDouble(double defvalue = 0.0) const;
2488 
2489     /**
2490      * Convert the string to a boolean value.
2491      * @param defvalue Default to return if the string is not a bool
2492      * @return The boolean interpretation or defvalue.
2493      */
2494     bool toBoolean(bool defvalue = false) const;
2495 
2496     /**
2497      * Check if the string can be converted to a boolean value.
2498      * @return True if the string is a valid boolean.
2499      */
2500     bool isBoolean() const;
2501 
2502     /**
2503      * Turn the string to an all-uppercase string
2504      * @return A reference to this String
2505      */
2506     String& toUpper();
2507 
2508     /**
2509      * Turn the string to an all-lowercase string
2510      * @return A reference to this String
2511      */
2512     String& toLower();
2513 
2514     /**
2515      * Indexing operator with signed int
2516      * @param index Index of character in string
2517      * @return Character at given index or 0 if out of range
2518      */
2519     inline char operator[](signed int index) const
2520 	{ return at(index); }
2521 
2522     /**
2523      * Indexing operator with unsigned int
2524      * @param index Index of character in string
2525      * @return Character at given index or 0 if out of range
2526      */
2527     inline char operator[](unsigned int index) const
2528 	{ return at(index); }
2529 
2530     /**
2531      * Conversion to "const char *" operator.
2532      * @return Pointer to the internally stored string
2533      */
2534     inline operator const char*() const
2535 	{ return m_string; };
2536 
2537     /**
2538      * Assigns a new value to the string from a character block.
2539      * @param value New value of the string
2540      * @param len Length of the data to copy, -1 for full string
2541      * @return Reference to the String
2542      */
2543     String& assign(const char* value, int len = -1);
2544 
2545     /**
2546      * Assigns a new value by filling with a repeated character
2547      * @param value Character to fill the string
2548      * @param repeat How many copies of the character to use
2549      * @return Reference to the String
2550      */
2551     String& assign(char value, unsigned int repeat = 1);
2552 
2553     /**
2554      * Build a hexadecimal representation of a buffer of data
2555      * @param data Pointer to data to dump
2556      * @param len Length of the data buffer
2557      * @param sep Separator character to use between octets
2558      * @param upCase Set to true to use upper case characters in hexa
2559      * @return Reference to the String
2560      */
2561     String& hexify(void* data, unsigned int len, char sep = 0, bool upCase = false);
2562 
2563     /**
2564      * Assignment operator.
2565      * @param value Value to assign to the string
2566      */
2567     inline String& operator=(const String& value)
2568 	{ return operator=(value.c_str()); }
2569 
2570     /**
2571      * Assignment from String* operator.
2572      * @param value Value to assign to the string
2573      * @see TelEngine::strcpy
2574      */
2575     inline String& operator=(const String* value)
2576 	{ return operator=(value ? value->c_str() : ""); }
2577 
2578     /**
2579      * Assignment from char* operator.
2580      * @param value Value to assign to the string
2581      * @see TelEngine::strcpy
2582      */
2583     String& operator=(const char* value);
2584 
2585     /**
2586      * Assignment operator for single characters.
2587      * @param value Value to assign to the string
2588      */
2589     String& operator=(char value);
2590 
2591     /**
2592      * Assignment operator for 32 bit integers.
2593      * @param value Value to assign to the string
2594      */
2595     String& operator=(int32_t value);
2596 
2597     /**
2598      * Assignment operator for 32 bit unsigned integers.
2599      * @param value Value to assign to the string
2600      */
2601     String& operator=(uint32_t value);
2602 
2603     /**
2604      * Assignment operator for 64 bit integers.
2605      * @param value Value to assign to the string
2606      */
2607     String& operator=(int64_t value);
2608 
2609     /**
2610      * Assignment operator for 64 bit unsigned integers.
2611      * @param value Value to assign to the string
2612      */
2613     String& operator=(uint64_t value);
2614 
2615     /**
2616      * Assignment operator for booleans.
2617      * @param value Value to assign to the string
2618      */
2619     inline String& operator=(bool value)
2620 	{ return operator=(boolText(value)); }
2621 
2622     /**
2623      * Assignment operator for double.
2624      * @param value Value to assign to the string
2625      */
2626     String& operator=(double value);
2627 
2628     /**
2629      * Appending operator for strings.
2630      * @param value Value to assign to the string
2631      * @see TelEngine::strcat
2632      */
2633     inline String& operator+=(const char* value)
2634 	{ return append(value,-1); }
2635 
2636     /**
2637      * Appending operator for single characters.
2638      * @param value Value to append to the string
2639      */
2640     String& operator+=(char value);
2641 
2642     /**
2643      * Appending operator for 32 bit integers.
2644      * @param value Value to append to the string
2645      */
2646     String& operator+=(int32_t value);
2647 
2648     /**
2649      * Appending operator for 32 bit unsigned integers.
2650      * @param value Value to append to the string
2651      */
2652     String& operator+=(uint32_t value);
2653 
2654     /**
2655      * Appending operator for 64 bit integers.
2656      * @param value Value to append to the string
2657      */
2658     String& operator+=(int64_t value);
2659 
2660     /**
2661      * Appending operator for 64 bit unsigned integers.
2662      * @param value Value to append to the string
2663      */
2664     String& operator+=(uint64_t value);
2665 
2666     /**
2667      * Appending operator for booleans.
2668      * @param value Value to append to the string
2669      */
2670     inline String& operator+=(bool value)
2671 	{ return operator+=(boolText(value)); }
2672 
2673     /**
2674      * Appending operator for double.
2675      * @param value Value to append to the string
2676      */
2677     String& operator+=(double value);
2678 
2679     /**
2680      * Equality operator.
2681      */
2682     bool operator==(const char* value) const;
2683 
2684     /**
2685      * Inequality operator.
2686      */
2687     bool operator!=(const char* value) const;
2688 
2689     /**
2690      * Fast equality operator.
2691      */
2692     inline bool operator==(const String& value) const
2693 	{ return (this == &value) || ((hash() == value.hash()) && operator==(value.c_str())); }
2694 
2695     /**
2696      * Fast inequality operator.
2697      */
2698     inline bool operator!=(const String& value) const
2699 	{ return (this != &value) && ((hash() != value.hash()) || operator!=(value.c_str())); }
2700 
2701     /**
2702      * Case-insensitive equality operator.
2703      */
2704     bool operator&=(const char* value) const;
2705 
2706     /**
2707      * Case-insensitive inequality operator.
2708      */
2709     bool operator|=(const char* value) const;
2710 
2711     /**
2712      * Stream style appending operator for C strings
2713      */
2714     inline String& operator<<(const char* value)
2715 	{ return operator+=(value); }
2716 
2717     /**
2718      * Stream style appending operator for single characters
2719      */
2720     inline String& operator<<(char value)
2721 	{ return operator+=(value); }
2722 
2723     /**
2724      * Stream style appending operator for 32 bit integers
2725      */
2726     inline String& operator<<(int32_t value)
2727 	{ return operator+=(value); }
2728 
2729     /**
2730      * Stream style appending operator for 32 bit unsigned integers
2731      */
2732     inline String& operator<<(uint32_t value)
2733 	{ return operator+=(value); }
2734 
2735     /**
2736      * Stream style appending operator for 64 bit integers
2737      */
2738     inline String& operator<<(int64_t value)
2739 	{ return operator+=(value); }
2740 
2741     /**
2742      * Stream style appending operator for 64 bit unsigned integers
2743      */
2744     inline String& operator<<(uint64_t value)
2745 	{ return operator+=(value); }
2746 
2747     /**
2748      * Stream style appending operator for booleans
2749      */
2750     inline String& operator<<(bool value)
2751 	{ return operator+=(value); }
2752 
2753     /**
2754      * Stream style appending operator for double
2755      */
2756     inline String& operator<<(double value)
2757 	{ return operator+=(value); }
2758 
2759     /**
2760      * Stream style substring skipping operator.
2761      * It eats all characters up to and including the skip string
2762      */
2763     String& operator>>(const char* skip);
2764 
2765     /**
2766      * Stream style extraction operator for single characters
2767      */
2768     String& operator>>(char& store);
2769 
2770     /**
2771      * Stream style extraction operator for single Unicode characters
2772      */
2773     String& operator>>(UChar& store);
2774 
2775     /**
2776      * Stream style extraction operator for integers
2777      */
2778     String& operator>>(int& store);
2779 
2780     /**
2781      * Stream style extraction operator for unsigned integers
2782      */
2783     String& operator>>(unsigned int& store);
2784 
2785     /**
2786      * Stream style extraction operator for booleans
2787      */
2788     String& operator>>(bool& store);
2789 
2790     /**
2791      * Append a string to the current string
2792      * @param value String from which to append
2793      * @param len Length of the data to copy, -1 for full string
2794      * @return Reference to the String
2795      */
2796     String& append(const char* value, int len);
2797 
2798     /**
2799      * Conditional appending with a separator
2800      * @param value String to append
2801      * @param separator Separator to insert before the value
2802      * @param force True to allow appending empty strings
2803      */
2804     String& append(const char* value, const char* separator = 0, bool force = false);
2805 
2806     /**
2807      * List members appending with a separator
2808      * @param list Pointer to ObjList whose @ref GenObject::toString() of the items will be appended
2809      * @param separator Separator to insert before each item in list
2810      * @param force True to allow appending empty strings
2811      */
2812     String& append(const ObjList* list, const char* separator = 0, bool force = false);
2813 
2814     /**
2815      * List members appending with a separator
2816      * @param list Reference of ObjList whose @ref GenObject::toString() of the items will be appended
2817      * @param separator Separator to insert before each item in list
2818      * @param force True to allow appending empty strings
2819      */
2820     inline String& append(const ObjList& list, const char* separator = 0, bool force = false)
2821 	{ return append(&list,separator,force); }
2822 
2823     /**
2824      * Explicit double append
2825      * @param value Value to append
2826      * @param decimals Number of decimals
2827      */
2828     String& append(double value, unsigned int decimals = 3);
2829 
2830     /**
2831      * Build a String in a printf style.
2832      * @param format The output format.
2833      * NOTE: The length of the resulting string will be at most 128 + length of format
2834      */
2835     String& printf(const char* format, ...) FORMAT_CHECK(2);
2836 
2837     /**
2838      * Build a String in a printf style.
2839      * @param length maximum length of the resulting string
2840      * @param format The output format.
2841      */
2842     String& printf(unsigned int length, const char* format,  ...) FORMAT_CHECK(3);
2843 
2844     /**
2845      * Build a fixed aligned string from str and append it.
2846      * @param fixedLength The fixed length in which the 'str' will be aligned.
2847      * @param str The string to align
2848      * @param len The number of characters to use from str.
2849      * @param fill Character to fill the empty space.
2850      * @param align The alignment mode.
2851      */
2852     String& appendFixed(unsigned int fixedLength, const char* str, unsigned int len = -1, char fill = ' ', int align = Left);
2853 
2854     /**
2855      * Build a fixed aligned string from str and append it.
2856      * @param fixedLength The fixed length in which the 'str' will be aligned.
2857      * @param str The string to align
2858      * @param fill Character to fill the empty space.
2859      * @param align The alignment mode.
2860      */
2861     inline String& appendFixed(unsigned int fixedLength, const String& str, char fill = ' ', int align = Left)
2862 	{ return appendFixed(fixedLength,str.c_str(),str.length(),fill,align); }
2863 
2864     /**
2865      * Locate the first instance of a character in the string
2866      * @param what Character to search for
2867      * @param offs Offset in string to start searching from
2868      * @return Offset of character or -1 if not found
2869      */
2870     int find(char what, unsigned int offs = 0) const;
2871 
2872     /**
2873      * Locate the first instance of a substring in the string
2874      * @param what Substring to search for
2875      * @param offs Offset in string to start searching from
2876      * @return Offset of substring or -1 if not found
2877      */
2878     int find(const char* what, unsigned int offs = 0) const;
2879 
2880     /**
2881      * Locate the last instance of a character in the string
2882      * @param what Character to search for
2883      * @return Offset of character or -1 if not found
2884      */
2885     int rfind(char what) const;
2886 
2887     /**
2888      * Locate the last instance of a substring in the string
2889      * @param what Substring to search for
2890      * @return Offset of substring or -1 if not found
2891      */
2892     int rfind(const char* what) const;
2893 
2894     /**
2895      * Checks if the string starts with a substring
2896      * @param what Substring to search for
2897      * @param wordBreak Check if a word boundary follows the substring
2898      * @param caseInsensitive Compare case-insensitive if set
2899      * @return True if the substring occurs at the beginning of the string
2900      */
2901     bool startsWith(const char* what, bool wordBreak = false, bool caseInsensitive = false) const;
2902 
2903     /**
2904      * Checks if the string ends with a substring
2905      * @param what Substring to search for
2906      * @param wordBreak Check if a word boundary precedes the substring
2907      * @param caseInsensitive Compare case-insensitive if set
2908      * @return True if the substring occurs at the end of the string
2909      */
2910     bool endsWith(const char* what, bool wordBreak = false, bool caseInsensitive = false) const;
2911 
2912     /**
2913      * Checks if the string starts with a substring and removes it
2914      * @param what Substring to search for
2915      * @param wordBreak Check if a word boundary follows the substring;
2916      *  this parameter defaults to True because the intended use of this
2917      *  method is to separate commands from their parameters
2918      * @param caseInsensitive Compare case-insensitive if set
2919      * @return True if the substring occurs at the beginning of the string
2920      *  and also removes the substring; if wordBreak is True any word
2921      *  breaking characters are also removed
2922      */
2923     bool startSkip(const char* what, bool wordBreak = true, bool caseInsensitive = false);
2924 
2925     /**
2926      * Extract a substring up to a separator
2927      * @param sep Separator string to match after extracted fragment
2928      * @param store Reference to String variable to store extracted fragment
2929      * @return Reference to this string
2930      */
2931     String& extractTo(const char* sep, String& store);
2932 
2933     /**
2934      * Extract a boolean substring up to a separator
2935      * @param sep Separator string to match after extracted fragment
2936      * @param store Reference to boolean variable to store extracted fragment
2937      * @return Reference to this string
2938      */
2939     String& extractTo(const char* sep, bool& store);
2940 
2941     /**
2942      * Extract an integer value substring up to a separator
2943      * @param sep Separator string to match after extracted fragment
2944      * @param store Reference to integer variable to store extracted fragment
2945      * @param base Numeration base, 0 to autodetect
2946      * @return Reference to this string
2947      */
2948     String& extractTo(const char* sep, int& store, int base = 0);
2949 
2950     /**
2951      * Extract an integer or token value substring up to a separator
2952      * @param sep Separator string to match after extracted fragment
2953      * @param store Reference to integer variable to store extracted fragment
2954      * @param tokens Pointer to an array of tokens to lookup first
2955      * @param base Numeration base, 0 to autodetect
2956      * @return Reference to this string
2957      */
2958     String& extractTo(const char* sep, int& store, const TokenDict* tokens, int base = 0);
2959 
2960     /**
2961      * Extract a double value substring up to a separator
2962      * @param sep Separator string to match after extracted fragment
2963      * @param store Reference to double variable to store extracted fragment
2964      * @return Reference to this string
2965      */
2966     String& extractTo(const char* sep, double& store);
2967 
2968     /**
2969      * Checks if matches another string
2970      * @param value String to check for match
2971      * @return True if matches, false otherwise
2972      */
matches(const String & value)2973     virtual bool matches(const String& value) const
2974 	{ return operator==(value); }
2975 
2976     /**
2977      * Checks if matches a regular expression and fill the match substrings
2978      * @param rexp Regular expression to check for match
2979      * @return True if matches, false otherwise
2980      */
2981     bool matches(const Regexp& rexp);
2982 
2983     /**
2984      * Get the offset of the last match
2985      * @param index Index of the submatch to return, 0 for full match
2986      * @return Offset of the last match, -1 if no match or not in range
2987      */
2988     int matchOffset(int index = 0) const;
2989 
2990     /**
2991      * Get the length of the last match
2992      * @param index Index of the submatch to return, 0 for full match
2993      * @return Length of the last match, 0 if no match or out of range
2994      */
2995     int matchLength(int index = 0) const;
2996 
2997     /**
2998      * Get a copy of a matched (sub)string
2999      * @param index Index of the submatch to return, 0 for full match
3000      * @return Copy of the matched substring
3001      */
3002     inline String matchString(int index = 0) const
3003 	{ return substr(matchOffset(index),matchLength(index)); }
3004 
3005     /**
3006      * Create a string by replacing matched strings in a template
3007      * @param templ Template of the string to generate
3008      * @return Copy of template with "\0" - "\9" replaced with submatches
3009      */
3010     String replaceMatches(const String& templ) const;
3011 
3012     /**
3013      * Get the total number of submatches from the last match, 0 if no match
3014      * @return Number of matching subexpressions
3015      */
3016     int matchCount() const;
3017 
3018     /**
3019      * Splits the string at a delimiter character
3020      * @param separator Character where to split the string
3021      * @param emptyOK True if empty strings should be inserted in list
3022      * @return A newly allocated list of strings, must be deleted after use
3023      */
3024     ObjList* split(char separator, bool emptyOK = true) const;
3025 
3026     /**
3027      * Splits the string at Regexp delimiter
3028      * @param reg Regexp describing the delimiter
3029      * @param emptyOK True if empty strings should be inserted in list
3030      * @return A newly allocated list of strings, must be deleted after use
3031      */
3032     ObjList* split(const Regexp& reg, bool emptyOK = true) const;
3033 
3034     /**
3035      * Create an escaped string suitable for use in messages
3036      * @param str String to convert to escaped format
3037      * @param extraEsc Character to escape other than the default ones
3038      * @return The string with special characters escaped
3039      */
3040     static String msgEscape(const char* str, char extraEsc = 0);
3041 
3042     /**
3043      * Create an escaped string suitable for use in messages
3044      * @param extraEsc Character to escape other than the default ones
3045      * @return The string with special characters escaped
3046      */
3047     inline String msgEscape(char extraEsc = 0) const
3048 	{ return msgEscape(c_str(),extraEsc); }
3049 
3050     /**
3051      * Decode an escaped string back to its raw form
3052      * @param str String to convert to unescaped format
3053      * @param errptr Pointer to an integer to receive the place of 1st error
3054      * @param extraEsc Character to unescape other than the default ones
3055      * @return The string with special characters unescaped
3056      */
3057     static String msgUnescape(const char* str, int* errptr = 0, char extraEsc = 0);
3058 
3059     /**
3060      * Decode an escaped string back to its raw form
3061      * @param errptr Pointer to an integer to receive the place of 1st error
3062      * @param extraEsc Character to unescape other than the default ones
3063      * @return The string with special characters unescaped
3064      */
3065     inline String msgUnescape(int* errptr = 0, char extraEsc = 0) const
3066 	{ return msgUnescape(c_str(),errptr,extraEsc); }
3067 
3068     /**
3069      * Create an escaped string suitable for use in SQL queries
3070      * @param str String to convert to escaped format
3071      * @param extraEsc Character to escape other than the default ones
3072      * @return The string with special characters escaped
3073      */
3074     static String sqlEscape(const char* str, char extraEsc = 0);
3075 
3076     /**
3077      * Create an escaped string suitable for use in SQL queries
3078      * @param extraEsc Character to escape other than the default ones
3079      * @return The string with special characters escaped
3080      */
3081     inline String sqlEscape(char extraEsc = 0) const
3082 	{ return sqlEscape(c_str(),extraEsc); }
3083 
3084     /**
3085      * Create an escaped string suitable for use in URIs
3086      * @param str String to convert to escaped format
3087      * @param extraEsc Character to escape other than the default ones
3088      * @param noEsc Optional pointer to string of characters that shouldn't be escaped
3089      * @return The string with special characters escaped
3090      */
3091     static String uriEscape(const char* str, char extraEsc = 0, const char* noEsc = 0);
3092 
3093     /**
3094      * Create an escaped string suitable for use in URIs
3095      * @param str String to convert to escaped format
3096      * @param extraEsc Pointer to string of characters to escape other than the defaults
3097      * @param noEsc Optional pointer to string of characters that shouldn't be escaped
3098      * @return The string with special characters escaped
3099      */
3100     static String uriEscape(const char* str, const char* extraEsc, const char* noEsc = 0);
3101 
3102     /**
3103      * Create an escaped string suitable for use in URI
3104      * @param extraEsc Character to escape other than the default ones
3105      * @param noEsc Optional pointer to string of characters that shouldn't be escaped
3106      * @return The string with special characters escaped
3107      */
3108     inline String uriEscape(char extraEsc = 0, const char* noEsc = 0) const
3109 	{ return uriEscape(c_str(),extraEsc,noEsc); }
3110 
3111     /**
3112      * Decode an URI escaped string back to its raw form
3113      * @param str String to convert to unescaped format
3114      * @param errptr Pointer to an integer to receive the place of 1st error
3115      * @return The string with special characters unescaped
3116      */
3117     static String uriUnescape(const char* str, int* errptr = 0);
3118 
3119     /**
3120      * Decode an URI escaped string back to its raw form
3121      * @param errptr Pointer to an integer to receive the place of 1st error
3122      * @return The string with special characters unescaped
3123      */
3124     inline String uriUnescape(int* errptr = 0) const
3125 	{ return uriUnescape(c_str(),errptr); }
3126 
3127     /**
3128      * Atom string support helper
3129      * @param str Reference to variable to hold the atom string
3130      * @param val String value to allocate to the atom
3131      * @return Pointer to shared atom string
3132      */
3133     static const String* atom(const String*& str, const char* val);
3134 
3135 protected:
3136     /**
3137      * Called whenever the value changed (except in constructors).
3138      */
3139      virtual void changed();
3140 
3141 private:
3142     void clearMatches();
3143     char* m_string;
3144     unsigned int m_length;
3145     // I hope every C++ compiler now knows about mutable...
3146     mutable unsigned int m_hash;
3147     StringMatchPrivate* m_matches;
3148 };
3149 
3150 /**
3151  * Utility function to retrieve a C string from a possibly NULL String pointer
3152  * @param str Pointer to a String that may be NULL
3153  * @return String data pointer or NULL
3154  */
c_str(const String * str)3155 inline const char* c_str(const String* str)
3156     { return str ? str->c_str() : (const char*)0; }
3157 
3158 /**
3159  * Utility function to replace NULL C string pointers with an empty C string
3160  * @param str Pointer to a C string that may be NULL
3161  * @return Original pointer or pointer to an empty C string
3162  */
c_safe(const char * str)3163 inline const char* c_safe(const char* str)
3164     { return str ? str : ""; }
3165 
3166 /**
3167  * Utility function to replace NULL String pointers with an empty C string
3168  * @param str Pointer to a String that may be NULL
3169  * @return String data pointer or pointer to an empty C string
3170  */
c_safe(const String * str)3171 inline const char* c_safe(const String* str)
3172     { return str ? str->safe() : ""; }
3173 
3174 /**
3175  * Utility function to check if a C string is null or empty
3176  * @param str Pointer to a C string
3177  * @return True if str is NULL or starts with a NUL character
3178  */
null(const char * str)3179 inline bool null(const char* str)
3180     { return !(str && *str); }
3181 
3182 /**
3183  * Utility function to check if a String is null or empty
3184  * @param str Pointer to a String
3185  * @return True if str is NULL or is empty
3186  */
null(const String * str)3187 inline bool null(const String* str)
3188     { return !str || str->null(); }
3189 
3190 /**
3191  * Concatenation operator for strings.
3192  */
3193 YATE_API String operator+(const String& s1, const String& s2);
3194 
3195 /**
3196  * Concatenation operator for strings.
3197  */
3198 YATE_API String operator+(const String& s1, const char* s2);
3199 
3200 /**
3201  * Concatenation operator for strings.
3202  */
3203 YATE_API String operator+(const char* s1, const String& s2);
3204 
3205 /**
3206  * Prevent careless programmers from overwriting the string
3207  * @see TelEngine::String::operator=
3208  */
strcpy(String & dest,const char * src)3209 inline const char *strcpy(String& dest, const char* src)
3210     { dest = src; return dest.c_str(); }
3211 
3212 /**
3213  * Prevent careless programmers from overwriting the string
3214  * @see TelEngine::String::operator+=
3215  */
strcat(String & dest,const char * src)3216 inline const char *strcat(String& dest, const char* src)
3217     { dest += src; return dest.c_str(); }
3218 
3219 /**
3220  * Utility function to look up a string in a token table,
3221  * interpret as number if it fails
3222  * @param str String to look up
3223  * @param tokens Pointer to the token table
3224  * @param defvalue Value to return if lookup and conversion fail
3225  * @param base Default base to use to convert to number
3226  */
3227 YATE_API int lookup(const char* str, const TokenDict* tokens, int defvalue = 0, int base = 0);
3228 
3229 /**
3230  * Utility function to look up a number in a token table
3231  * @param value Value to search for
3232  * @param tokens Pointer to the token table
3233  * @param defvalue Value to return if lookup fails
3234  */
3235 YATE_API const char* lookup(int value, const TokenDict* tokens, const char* defvalue = 0);
3236 
3237 /**
3238  * Utility function to look up a string in a 64bit token table,
3239  * interpret as number if it fails
3240  * @param str String to look up
3241  * @param tokens Pointer to the token table
3242  * @param defvalue Value to return if lookup and conversion fail
3243  * @param base Default base to use to convert to number
3244  */
3245 YATE_API int64_t lookup(const char* str, const TokenDict64* tokens, int64_t defvalue = 0, int base = 0);
3246 
3247 /**
3248  * Utility function to look up a 64bit number in a token table
3249  * @param value Value to search for
3250  * @param tokens Pointer to the token table
3251  * @param defvalue Value to return if lookup fails
3252  */
3253 YATE_API const char* lookup(int64_t value, const TokenDict64* tokens, const char* defvalue = 0);
3254 
3255 class NamedList;
3256 
3257 /**
3258  * Utility method to return from a chan.control handler
3259  * @param params The parameters list
3260  * @param ret The return value
3261  * @param retVal The error message
3262  * @return ret if the message was not generated from rmanager.
3263  */
3264 YATE_API bool controlReturn(NamedList* params, bool ret, const char* retVal = 0);
3265 
3266 /**
3267  * A regular expression matching class.
3268  * @short A regexp matching class
3269  */
3270 class YATE_API Regexp : public String
3271 {
3272     YCLASS(Regexp,String)
3273     friend class String;
3274 public:
3275     /**
3276      * Creates a new, empty regexp.
3277      */
3278     Regexp();
3279 
3280     /**
3281      * Creates a new initialized regexp.
3282      * @param value Initial value of the regexp.
3283      * @param extended True to use POSIX Extended Regular Expression syntax
3284      * @param insensitive True to not differentiate case
3285      */
3286     explicit Regexp(const char* value, bool extended = false, bool insensitive = false);
3287 
3288     /**
3289      * Copy constructor.
3290      * @param value Initial value of the regexp.
3291      */
3292     Regexp(const Regexp& value);
3293 
3294     /**
3295      * Destroys the regexp, disposes the memory.
3296      */
3297     virtual ~Regexp();
3298 
3299     /**
3300      * Assignment from char* operator.
3301      */
3302     inline Regexp& operator=(const char* value)
3303 	{ String::operator=(value); return *this; }
3304 
3305     /**
3306      * Makes sure the regular expression is compiled
3307      * @return True if successfully compiled, false on error
3308      */
compile()3309     inline bool compile() const
3310 	{ return m_regexp || (m_compile && doCompile()); }
3311 
3312     /**
3313      * Checks if the pattern matches a given value
3314      * @param value String to check for match
3315      * @return True if matches, false otherwise
3316      */
3317     bool matches(const char* value) const;
3318 
3319     /**
3320      * Checks if the pattern matches a string
3321      * @param value String to check for match
3322      * @return True if matches, false otherwise
3323      */
matches(const String & value)3324     virtual bool matches(const String& value) const
3325 	{ return Regexp::matches(value.safe()); }
3326 
3327     /**
3328      * Change the expression matching flags
3329      * @param extended True to use POSIX Extended Regular Expression syntax
3330      * @param insensitive True to not differentiate case
3331      */
3332     void setFlags(bool extended, bool insensitive);
3333 
3334     /**
3335      * Return the POSIX Extended syntax flag
3336      * @return True if using POSIX Extended Regular Expression syntax
3337      */
3338     bool isExtended() const;
3339 
3340     /**
3341      * Return the Case Insensitive flag
3342      * @return True if not differentiating case
3343      */
3344     bool isCaseInsensitive() const;
3345 
3346 protected:
3347     /**
3348      * Called whenever the value changed (except in constructors) to recompile.
3349      */
3350     virtual void changed();
3351 
3352     /**
3353      * Compile the regular expression
3354      * @return True if successfully compiled, false on error
3355      */
3356     bool doCompile() const;
3357 
3358 private:
3359     void cleanup();
3360     bool matches(const char* value, StringMatchPrivate* matchlist) const;
3361     mutable void* m_regexp;
3362     mutable bool m_compile;
3363     int m_flags;
3364 };
3365 
3366 /**
3367  * Indirected shared string offering access to atom strings
3368  * @short Atom string holder
3369  */
3370 class Atom
3371 {
3372 public:
3373     /**
3374      * Constructor
3375      * @param value Atom's string value
3376      */
Atom(const char * value)3377     inline explicit Atom(const char* value)
3378 	: m_atom(0)
3379 	{ String::atom(m_atom,value); }
3380 
3381     /**
3382      * Conversion to "const String &" operator
3383      * @return Pointer to the atom String
3384      */
3385     inline operator const String&() const
3386 	{ return *m_atom; }
3387 
3388     /**
3389      * String method call operator
3390      * @return Pointer to the atom String
3391      */
3392     inline const String* operator->() const
3393 	{ return m_atom; }
3394 
3395 private:
3396     const String* m_atom;
3397 };
3398 
3399 /**
3400  * Holder for an event (output, debug or alarm) message
3401  * @short A captured event string with a debug level
3402  */
3403 class YATE_API CapturedEvent : public String
3404 {
3405     friend class Engine;
YCLASS(CapturedEvent,String)3406     YCLASS(CapturedEvent,String)
3407 public:
3408     /**
3409      * Constructor
3410      * @param level Debugging level associated with the event
3411      * @param text Text description of the event
3412      */
3413     inline CapturedEvent(int level, const char* text)
3414 	: String(text), m_level(level)
3415 	{ }
3416 
3417     /**
3418      * Copy constructor
3419      * @param original Captured event to copy
3420      */
CapturedEvent(const CapturedEvent & original)3421     inline CapturedEvent(const CapturedEvent& original)
3422 	: String(original), m_level(original.level())
3423 	{ }
3424 
3425     /**
3426      * Get the debugging level of the event
3427      * @return Debugging level associated with the event
3428      */
level()3429     inline int level() const
3430 	{ return m_level; }
3431 
3432 
3433     /**
3434      * Get the capturing state of the output and debug messages
3435      * @return True if output and debug messages are being captured
3436      */
capturing()3437     inline static bool capturing()
3438 	{ return s_capturing; }
3439 
3440     /**
3441      * Get the list of captured events
3442      * @return List of events captured from output and debugging
3443      */
events()3444     inline static const ObjList& events()
3445 	{ return s_events; }
3446 
3447     /**
3448      * Add an event to the captured events list
3449      * @param level Debugging level associated with the event
3450      * @param text Text description of the event, must not be empty
3451      */
append(int level,const char * text)3452     inline static void append(int level, const char* text)
3453 	{ if (text && *text) s_events.append(new CapturedEvent(level,text)); }
3454 
3455 protected:
3456     /**
3457      * Get a writable list of captured events
3458      * @return List of events captured from output and debugging
3459      */
eventsRw()3460     inline static ObjList& eventsRw()
3461 	{ return s_events; }
3462 
3463     /**
3464      * Enable or disable capturing of output and debug messages
3465      * @param capture True to capture internally the debugging messages
3466      */
capturing(bool capture)3467     inline static void capturing(bool capture)
3468 	{ s_capturing = capture; }
3469 
3470 private:
3471     int m_level;
3472     static ObjList s_events;
3473     static bool s_capturing;
3474 };
3475 
3476 /**
3477  * A string class with a hashed string name
3478  * @short A named string class.
3479  */
3480 class YATE_API NamedString : public String
3481 {
3482     YNOCOPY(NamedString); // no automatic copies please
3483 public:
3484     /**
3485      * Creates a new named string.
3486      * @param name Name of this string
3487      * @param value Initial value of the string
3488      */
3489     explicit NamedString(const char* name, const char* value = 0);
3490 
3491     /**
3492      * Retrieve the name of this string.
3493      * @return A hashed string with the name of the string
3494      */
name()3495     inline const String& name() const
3496 	{ return m_name; }
3497 
3498     /**
3499      * Get a string representation of this object
3500      * @return A reference to the name of this object
3501      */
3502     virtual const String& toString() const;
3503 
3504     /**
3505      * Get a pointer to a derived class given that class name
3506      * @param name Name of the class we are asking for
3507      * @return Pointer to the requested class or NULL if this object doesn't implement it
3508      */
3509     virtual void* getObject(const String& name) const;
3510 
3511     /**
3512      * Value assignment operator
3513      */
3514     inline NamedString& operator=(const char* value)
3515 	{ String::operator=(value); return *this; }
3516 
3517 private:
3518     NamedString(); // no default constructor please
3519     String m_name;
3520 };
3521 
3522 /**
3523  * A named string holding a pointer to arbitrary data.
3524  * The pointer is owned by the object: it will be released when the object is
3525  *  destroyed or the string value changed
3526  * @short A named pointer class.
3527  */
3528 class YATE_API NamedPointer : public NamedString
3529 {
3530 public:
3531     /**
3532      * Creates a new named pointer
3533      * @param name Name of this pointer
3534      * @param data Initial pointer value. The pointer will be owned by this object
3535      * @param value Initial string value
3536      */
3537     explicit NamedPointer(const char* name, GenObject* data = 0, const char* value = 0);
3538 
3539     /**
3540      * Destructor. Release the pointer
3541      */
3542     virtual ~NamedPointer();
3543 
3544     /**
3545      * Retrieve the pointer carried by this object
3546      * @return Pointer to arbitrary user GenObject
3547      */
userData()3548     inline GenObject* userData() const
3549 	{ return m_data; }
3550 
3551     /**
3552      * Retrieve the pointer carried by this object and release ownership.
3553      * The caller will own the returned pointer
3554      * @return Pointer to arbitrary user GenObject
3555      */
3556     GenObject* takeData();
3557 
3558     /**
3559      * Set obscure data carried by this object.
3560      * Note that a RefObject's reference counter should be increased before adding it to this named pointer
3561      * @param data Pointer to arbitrary user data
3562      */
3563     void userData(GenObject* data);
3564 
3565     /**
3566      * Get a pointer to a derived class of user data given that class name
3567      * @param name Name of the class we are asking for
3568      * @return Pointer to the requested class or NULL if user object id NULL or doesn't implement it
3569      */
userObject(const String & name)3570     inline void* userObject(const String& name) const
3571 	{ return m_data ? m_data->getObject(name) : 0; }
3572 
3573     /**
3574      * String value assignment operator
3575      */
3576     inline NamedPointer& operator=(const char* value)
3577 	{ NamedString::operator=(value); return *this; }
3578 
3579     /**
3580      * Get a pointer to a derived class given that class name
3581      * @param name Name of the class we are asking for
3582      * @return Pointer to the requested class or NULL if this object doesn't implement it
3583      */
3584     virtual void* getObject(const String& name) const;
3585 
3586 protected:
3587     /**
3588      * Called whenever the string value changed. Release the pointer
3589      */
3590     virtual void changed();
3591 
3592 private:
3593     NamedPointer(); // no default constructor please
3594     GenObject* m_data;
3595 };
3596 
3597 /**
3598  * An atomic counter with an associated name
3599  * @short Atomic counter with name
3600  */
3601 class YATE_API NamedCounter : public String
3602 {
3603     YNOCOPY(NamedCounter); // no automatic copies please
3604 public:
3605     /**
3606      * Constructor
3607      * @param name Name of the counter
3608      */
3609     explicit NamedCounter(const String& name);
3610 
3611     /**
3612      * Check if the counter is enabled
3613      * @return True if the counter is enabled
3614      */
enabled()3615     inline bool enabled() const
3616 	{ return m_enabled; }
3617 
3618     /**
3619      * Enable or disable the counter
3620      * @param val True to enable counter, false to disable
3621      */
enable(bool val)3622     inline void enable(bool val)
3623 	{ m_enabled = val; }
3624 
3625     /**
3626      * Increment the counter
3627      * @return Post-increment value of the counter
3628      */
3629     int inc();
3630 
3631     /**
3632      * Decrement the counter
3633      * @return Post-decrement value of the counter
3634      */
3635     int dec();
3636 
3637     /**
3638      * Get the current value of the counter
3639      * @return Value of the counter
3640      */
count()3641     inline int count() const
3642 	{ return m_count; }
3643 
3644 private:
3645     int m_count;
3646     bool m_enabled;
3647     Mutex* m_mutex;
3648 };
3649 
3650 /**
3651  * A hashed object list handling class. Objects placed in the list are
3652  *  distributed according to their String hash resulting in faster searches.
3653  * On the other hand an object placed in a hashed list must never change
3654  *  its String value or it becomes unfindable.
3655  * @short A hashed object list class
3656  */
3657 class YATE_API HashList : public GenObject
3658 {
3659     YNOCOPY(HashList); // no automatic copies please
3660 public:
3661     /**
3662      * Creates a new, empty list.
3663      * @param size Number of classes to divide the objects
3664      */
3665     explicit HashList(unsigned int size = 17);
3666 
3667     /**
3668      * Destroys the list and everything in it.
3669      */
3670     virtual ~HashList();
3671 
3672     /**
3673      * Get a pointer to a derived class given that class name
3674      * @param name Name of the class we are asking for
3675      * @return Pointer to the requested class or NULL if this object doesn't implement it
3676      */
3677     virtual void* getObject(const String& name) const;
3678 
3679     /**
3680      * Get the number of hash entries
3681      * @return Count of hash entries
3682      */
length()3683     inline unsigned int length() const
3684 	{ return m_size; }
3685 
3686     /**
3687      * Get the number of non-null objects in the list
3688      * @return Count of items
3689      */
3690     unsigned int count() const;
3691 
3692     /**
3693      * Retrieve one of the internal object lists. This method should be used
3694      *  only to iterate all objects in the list.
3695      * @param index Index of the internal list to retrieve
3696      * @return Pointer to the list or NULL
3697      */
getList(unsigned int index)3698     inline ObjList* getList(unsigned int index) const
3699 	{ return (index < m_size) ? m_lists[index] : 0; }
3700 
3701     /**
3702      * Retrieve one of the internal object lists knowing the hash value.
3703      * @param hash Hash of the internal list to retrieve
3704      * @return Pointer to the list or NULL if never filled
3705      */
getHashList(unsigned int hash)3706     inline ObjList* getHashList(unsigned int hash) const
3707 	{ return getList(hash % m_size); }
3708 
3709     /**
3710      * Retrieve one of the internal object lists knowing the String value.
3711      * @param str String whose hash internal list is to retrieve
3712      * @return Pointer to the list or NULL if never filled
3713      */
getHashList(const String & str)3714     inline ObjList* getHashList(const String& str) const
3715 	{ return getHashList(str.hash()); }
3716 
3717     /**
3718      * Array-like indexing operator
3719      * @param str String value of the object to locate
3720      * @return Pointer to the first object or NULL
3721      */
3722     GenObject* operator[](const String& str) const;
3723 
3724     /**
3725      * Get the item in the list that holds an object.
3726      * The item is searched sequentially in the lists, not using it's String hash
3727      * @param obj Pointer to the object to search for
3728      * @return Pointer to the found item or NULL
3729      */
3730     ObjList* find(const GenObject* obj) const;
3731 
3732     /**
3733      * Get the item in the list that holds an object
3734      * @param obj Pointer to the object to search for
3735      * @param hash Object hash used to identify the list it belongs to
3736      * @return Pointer to the found item or NULL
3737      */
3738     ObjList* find(const GenObject* obj, unsigned int hash) const;
3739 
3740     /**
3741      * Get the item in the list that holds an object by String value
3742      * @param str String value (toString) of the object to search for
3743      * @return Pointer to the first found item or NULL
3744      */
3745     ObjList* find(const String& str) const;
3746 
3747     /**
3748      * Appends an object to the hashed list
3749      * @param obj Pointer to the object to append
3750      * @return A pointer to the inserted list item
3751      */
3752     ObjList* append(const GenObject* obj);
3753 
3754     /**
3755      * Appends an object to the hashed list
3756      * @param obj Pointer to the object to append
3757      * @param hash Object hash used to identify the list into which this object should be inserted
3758      * @return A pointer to the inserted list item
3759      */
3760     ObjList* append(const GenObject* obj, unsigned int hash);
3761 
3762     /**
3763      * Delete the list item that holds a given object
3764      * @param obj Object to search in the list
3765      * @param delobj True to delete the object (default)
3766      * @param useHash True to use object hash to identify the list it belongs to
3767      * @return Pointer to the object if not destroyed
3768      */
3769     GenObject* remove(GenObject* obj, bool delobj = true, bool useHash = false);
3770 
3771     /**
3772      * Delete the item in the list that holds an object by String value
3773      * @param str String value (toString) of the object to remove
3774      * @param delobj True to delete the object (default)
3775      * @return Pointer to the object if not destroyed
3776      */
3777     inline GenObject* remove(const String& str, bool delobj = true)
3778     {
3779 	ObjList* n = find(str);
3780 	return n ? n->remove(delobj) : 0;
3781     }
3782 
3783     /**
3784      * Delete the item in the list that has the associated hash
3785      * @param obj Object to search in the list
3786      * @param hash Object hash used to identify the list from which to remove the object
3787      * @param delobj True to delete the object (default)
3788      * @return Pointer to the object if not destroyed
3789      */
3790     inline GenObject* remove(GenObject* obj, unsigned int hash, bool delobj = true)
3791     {
3792 	ObjList* n = find(obj,hash);
3793 	return n ? n->remove(delobj) : 0;
3794     }
3795 
3796     /**
3797      * Clear the list and optionally delete all contained objects
3798      */
3799     void clear();
3800 
3801     /**
3802      * Resync the list by checking if a stored object belongs to the list
3803      *  according to its hash
3804      * @param obj Object to resync in the list
3805      * @return True if object was in the wrong list and had to be moved
3806      */
3807     bool resync(GenObject* obj);
3808 
3809     /**
3810      * Resync the list by checking if all stored objects belong to the list
3811      *  according to their hash
3812      * @return True if at least one object had to be moved
3813      */
3814     bool resync();
3815 
3816 private:
3817     unsigned int m_size;
3818     ObjList** m_lists;
3819 };
3820 
3821 /**
3822  * An ObjList or HashList iterator that can be used even when list elements
3823  * are changed while iterating. Note that it will not detect that an item was
3824  * removed and another with the same address was inserted back in list.
3825  * @short Class used to iterate the items of a list
3826  */
3827 class YATE_API ListIterator
3828 {
3829     YNOCOPY(ListIterator); // no automatic copies please
3830 public:
3831     /**
3832      * Constructor used to iterate through an ObjList.
3833      * The image of the list is frozen at the time the constructor executes
3834      * @param list List to get the objects from
3835      * @param offset First list element to iterate, will wrap around
3836      */
3837     ListIterator(ObjList& list, int offset = 0);
3838 
3839     /**
3840      * Constructor used to iterate through a HashList.
3841      * The image of the list is frozen at the time the constructor executes
3842      * @param list List to get the objects from
3843      * @param offset First list element to iterate, will wrap around
3844      */
3845     ListIterator(HashList& list, int offset = 0);
3846 
3847     /**
3848      * Destructor - frees the allocated memory
3849      */
3850     ~ListIterator();
3851 
3852     /**
3853      * Get the number of elements in the list
3854      * @return Count of items in the internal list
3855      */
length()3856     inline unsigned int length() const
3857 	{ return m_length; }
3858 
3859     /**
3860      * Clear the iterator, disconnect from any list
3861      */
3862     void clear();
3863 
3864     /**
3865      * Assign an ObjList to the iterator, build a frozen image of the list
3866      * @param list List to get the objects from
3867      * @param offset First list element to iterate, will wrap around
3868      */
3869     void assign(ObjList& list, int offset = 0);
3870 
3871     /**
3872      * Assign a HashList to the iterator, build a frozen image of the list
3873      * @param list List to get the objects from
3874      * @param offset First list element to iterate, will wrap around
3875      */
3876     void assign(HashList& list, int offset = 0);
3877 
3878     /**
3879      * Get an arbitrary element in the iterator's list image.
3880      * Items that were removed from list or are not alive are not returned.
3881      * @param index Position to get the item from
3882      * @return Pointer to the list item or NULL if out of range or item removed
3883      */
3884     GenObject* get(unsigned int index) const;
3885 
3886     /**
3887      * Get the current element and advance the current index.
3888      * Items that were removed from list or are not alive are skipped over.
3889      * An example of typical usage:
3890      * <pre>
3891      * ListIterator iter(list);
3892      * while (GenObject* obj = iter.get()) {
3893      *     do_something_with(obj);
3894      * }
3895      * </pre>
3896      * @return Pointer to a list item or NULL if advanced past end (eof)
3897      */
3898     GenObject* get();
3899 
3900     /**
3901      * Check if the current pointer is past the end of the list
3902      * @return True if there are no more entries left
3903      */
eof()3904     inline bool eof() const
3905 	{ return m_current >= m_length; }
3906 
3907     /**
3908      * Reset the iterator index to the first position in the list
3909      */
reset()3910     inline void reset()
3911 	{ m_current = 0; }
3912 
3913 private:
3914     ObjList* m_objList;
3915     HashList* m_hashList;
3916     GenObject** m_objects;
3917     unsigned int* m_hashes;
3918     unsigned int m_length;
3919     unsigned int m_current;
3920 };
3921 
3922 /**
3923  * The Time class holds a time moment with microsecond accuracy
3924  * @short A time holding class
3925  */
3926 class YATE_API Time
3927 {
3928 public:
3929     /**
3930      * Constructs a Time object from the current time
3931      */
Time()3932     inline Time()
3933 	: m_time(now())
3934 	{ }
3935 
3936     /**
3937      * Constructs a Time object from a given time
3938      * @param usec Time in microseconds
3939      */
Time(u_int64_t usec)3940     inline Time(u_int64_t usec)
3941 	: m_time(usec)
3942 	{ }
3943 
3944     /**
3945      * Constructs a Time object from a timeval structure pointer
3946      * @param tv Pointer to the timeval structure
3947      */
Time(const struct timeval * tv)3948     inline explicit Time(const struct timeval* tv)
3949 	: m_time(fromTimeval(tv))
3950 	{ }
3951 
3952     /**
3953      * Constructs a Time object from a timeval structure
3954      * @param tv Reference of the timeval structure
3955      */
Time(const struct timeval & tv)3956     inline explicit Time(const struct timeval& tv)
3957 	: m_time(fromTimeval(tv))
3958 	{ }
3959 
3960     /**
3961      * Do-nothing destructor that keeps the compiler from complaining
3962      *  about inlining derivates or members of Time type
3963      */
~Time()3964     inline ~Time()
3965 	{ }
3966 
3967     /**
3968      * Get time in seconds
3969      * @return Time in seconds since the Epoch
3970      */
sec()3971     inline u_int32_t sec() const
3972 	{ return (u_int32_t)((m_time+500000) / 1000000); }
3973 
3974     /**
3975      * Get time in milliseconds
3976      * @return Time in milliseconds since the Epoch
3977      */
msec()3978     inline u_int64_t msec() const
3979 	{ return (m_time+500) / 1000; }
3980 
3981     /**
3982      * Get time in microseconds
3983      * @return Time in microseconds since the Epoch
3984      */
usec()3985     inline u_int64_t usec() const
3986 	{ return m_time; }
3987 
3988     /**
3989      * Conversion to microseconds operator
3990      */
u_int64_t()3991     inline operator u_int64_t() const
3992 	{ return m_time; }
3993 
3994     /**
3995      * Assignment operator.
3996      */
3997     inline Time& operator=(u_int64_t usec)
3998 	{ m_time = usec; return *this; }
3999 
4000     /**
4001      * Offsetting operator.
4002      */
4003     inline Time& operator+=(int64_t delta)
4004 	{ m_time += delta; return *this; }
4005 
4006     /**
4007      * Offsetting operator.
4008      */
4009     inline Time& operator-=(int64_t delta)
4010 	{ m_time -= delta; return *this; }
4011 
4012     /**
4013      * Fill in a timeval struct from a value in microseconds
4014      * @param tv Pointer to the timeval structure
4015      */
toTimeval(struct timeval * tv)4016     inline void toTimeval(struct timeval* tv) const
4017 	{ toTimeval(tv, m_time); }
4018 
4019     /**
4020      * Fill in a timeval struct from a value in microseconds
4021      * @param tv Pointer to the timeval structure
4022      * @param usec Time to convert to timeval
4023      */
4024     static void toTimeval(struct timeval* tv, u_int64_t usec);
4025 
4026     /**
4027      * Convert time in a timeval struct to microseconds
4028      * @param tv Pointer to the timeval structure
4029      * @return Corresponding time in microseconds or zero if tv is NULL
4030      */
4031     static u_int64_t fromTimeval(const struct timeval* tv);
4032 
4033     /**
4034      * Convert time in a timeval struct to microseconds
4035      * @param tv Reference of the timeval structure
4036      * @return Corresponding time in microseconds
4037      */
fromTimeval(const struct timeval & tv)4038     inline static u_int64_t fromTimeval(const struct timeval& tv)
4039 	{ return fromTimeval(&tv); }
4040 
4041     /**
4042      * Get the current system time in microseconds
4043      * @return Time in microseconds since the Epoch
4044      */
4045     static u_int64_t now();
4046 
4047     /**
4048      * Get the current system time in milliseconds
4049      * @return Time in milliseconds since the Epoch
4050      */
4051     static u_int64_t msecNow();
4052 
4053     /**
4054      * Get the current system time in seconds
4055      * @return Time in seconds since the Epoch
4056      */
4057     static u_int32_t secNow();
4058 
4059     /**
4060      * Build EPOCH time from date/time components
4061      * @param year The year component of the date. Must be greater then 1969
4062      * @param month The month component of the date (1 to 12)
4063      * @param day The day component of the date (1 to 31)
4064      * @param hour The hour component of the time (0 to 23). The hour can be 24
4065      *  if minute and sec are 0
4066      * @param minute The minute component of the time (0 to 59)
4067      * @param sec The seconds component of the time (0 to 59)
4068      * @param offset Optional number of seconds to be added/substracted
4069      *  to/from result. It can't exceed the number of seconds in a day
4070      * @return EPOCH time in seconds, -1 on failure
4071      */
4072     static unsigned int toEpoch(int year, unsigned int month, unsigned int day,
4073 	unsigned int hour, unsigned int minute, unsigned int sec, int offset = 0);
4074 
4075     /**
4076      * Split a given EPOCH time into its date/time components
4077      * @param epochTimeSec EPOCH time in seconds
4078      * @param year The year component of the date
4079      * @param month The month component of the date (1 to 12)
4080      * @param day The day component of the date (1 to 31)
4081      * @param hour The hour component of the time (0 to 23)
4082      * @param minute The minute component of the time (0 to 59)
4083      * @param sec The seconds component of the time (0 to 59)
4084      * @param wDay The day of the week (optional)
4085      * @return True on succes, false if conversion failed
4086      */
4087     static bool toDateTime(unsigned int epochTimeSec, int& year, unsigned int& month,
4088 	unsigned int& day, unsigned int& hour, unsigned int& minute, unsigned int& sec,
4089 	unsigned int* wDay = 0);
4090 
4091     /**
4092      * Convert system time to 32bit NTP (seconds since 1900)
4093      * @param sec Time in seconds
4094      * @param over Optional destination for overflow value. Must be reset before calling this method
4095      * @param rfc2030 Use time extension as specified in RFC 2030 Section 3
4096      * @return NTP time value in seconds
4097      */
4098     static uint32_t toNtp(uint32_t sec, uint32_t* over = 0, bool rfc2030 = true);
4099 
4100     /**
4101      * Convert this time to 32bit NTP (seconds since 1900)
4102      * @param over Optional destination for overflow value. Must be reset before calling this method
4103      * @param rfc2030 Use time extension as specified in RFC 2030 Section 3
4104      * @return NTP time value in seconds
4105      */
4106     inline uint32_t toNtp(uint32_t* over = 0, bool rfc2030 = true)
4107 	{ return toNtp(sec(),over,rfc2030); }
4108 
4109     /**
4110      * Convert 32bit NTP (seconds since 1900) to system time
4111      * @param val NTP time in seconds
4112      * @param under Optional destination for underflow value (given time is before EPOCH).
4113      *   Must be reset before calling this method
4114      * @param rfc2030 Handle time extension as specified in RFC 2030 Section 3
4115      * @return System time value in seconds. 0 if underflow
4116      */
4117     static uint32_t fromNtp(uint32_t val, uint32_t* under = 0, bool rfc2030 = true);
4118 
4119     /**
4120      * Convert EPOCH time to a string representation. Does not add a NUL char at end
4121      * Minimal representation is yyyy-mm-ddThh:mm:ssZ
4122      * Destination buffer length must be at least 20 if no fractions are going to be filled
4123      * For milliseconds fractions extra 4 bytes must be available in buffer
4124      * For microseconds fractions extra 7 bytes must be available in buffer
4125      * @param buf Buffer to be filled
4126      * @param time System time in microseconds to convert
4127      * @param frac Add second fractions. 0: none, negative: microseconds, positive: milliseconds
4128      * @return The number of chars written in buffer. 0 on failure
4129      */
4130     static unsigned int toString(char* buf, uint64_t time, int frac = 0);
4131 
4132     /**
4133      * Convert system time to a string representation
4134      * Minimal representation is yyyy-mm-ddThh:mm:ssZ
4135      * Destination buffer length must be at least 20 if no fractions are going to be filled
4136      * For milliseconds fractions extra 4 bytes must be available in buffer
4137      * For microseconds fractions extra 7 bytes must be available in buffer
4138      * @param buf Buffer to append to
4139      * @param time System time in microseconds to convert
4140      * @param frac Add second fractions. 0: none, negative: microseconds, positive: milliseconds
4141      * @return The number of chars added to buffer. 0 on failure
4142      */
4143     static inline unsigned int appendTo(String& buf, uint64_t time, int frac = 0) {
4144 	    char tmp[30];
4145 	    unsigned int n = toString(tmp,time,frac);
4146 	    if (n)
4147 		buf.append(tmp,n);
4148 	    return n;
4149 	}
4150 
4151     /**
4152      * Decode string to EPOCH time
4153      * Decode yyyy-mm-dd{T|t}hh:mm:ss[.SEC-FRAC]{{Z|z}|{+/-hh:mm}}
4154      * Date seconds may contain leap seconds (value 60). These are ignored (second will be used as 59)
4155      * @param buf Buffer to parse
4156      * @param len Buffer length. 0 to detect
4157      * @param frac Handle second fractions. 0: none, negative: microseconds, positive: milliseconds
4158      * @return EPOCH time in (milli|micro)seconds, -1 on failure
4159      */
4160     static uint64_t toEpoch(const char* buf, unsigned int len, int frac = 0);
4161 
4162     /**
4163      * Check if an year is a leap one
4164      * @param year The year to check
4165      * @return True if the given year is a leap one
4166      */
isLeap(unsigned int year)4167     static inline bool isLeap(unsigned int year)
4168 	{ return (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)); }
4169 
4170     /**
4171      * Retrieve the difference between local time and UTC in seconds east of UTC
4172      * @param when UNIX time for which to compute timezone, affects daylight saving
4173      * @return Difference between local time and UTC in seconds
4174      */
4175     static int timeZone(u_int32_t when = secNow());
4176 
4177 private:
4178     u_int64_t m_time;
4179 };
4180 
4181 /**
4182  * Implementation of a system independent pseudo random number generator
4183  * @short Pseudo random number generator
4184  */
4185 class YATE_API Random
4186 {
4187 public:
4188     /**
4189      * Constructor
4190      * @param seed Number to use as initial sequence seed
4191      */
4192     inline Random(u_int32_t seed = Time::now() & 0xffffffff)
m_random(seed)4193 	: m_random(seed)
4194 	{ }
4195 
4196     /**
4197      * Get the latest random number generated
4198      * @return Last random number generated
4199      */
get()4200     inline u_int32_t get() const
4201 	{ return m_random; }
4202 
4203     /**
4204      * Set the pseudo random generator to a known state
4205      * @param seed Number to set as current state
4206      */
set(u_int32_t seed)4207     inline void set(u_int32_t seed)
4208 	{ m_random = seed; }
4209 
4210     /**
4211      * Advance the pseudo random sequence and return new value
4212      * @return Next random number in sequence
4213      */
4214     u_int32_t next();
4215 
4216     /**
4217      * Thread safe (and shared) replacement for library ::random()
4218      * @return Next random number in the global sequence
4219      */
4220     static long int random();
4221 
4222     /**
4223      * Thread safe (and shared) replacement for library ::srandom()
4224      * @param seed Number to set as seed in the global sequence
4225      */
4226     static void srandom(unsigned int seed);
4227 
4228 private:
4229     u_int32_t m_random;
4230 };
4231 
4232 /**
4233  * The DataBlock holds a data buffer with no specific formatting.
4234  * @short A class that holds just a block of raw data
4235  */
4236 class YATE_API DataBlock : public GenObject
4237 {
4238 public:
4239 
4240     /**
4241      * Constructs an empty data block
4242      * @param overAlloc How many bytes of memory to overallocate
4243      */
4244     DataBlock(unsigned int overAlloc = 0);
4245 
4246     /**
4247      * Copy constructor
4248      * @param value Data block to copy from
4249      */
4250     DataBlock(const DataBlock& value);
4251 
4252     /**
4253      * Copy constructor with overallocation
4254      * @param value Data block to copy from
4255      * @param overAlloc How many bytes of memory to overallocate
4256      */
4257     DataBlock(const DataBlock& value, unsigned int overAlloc);
4258 
4259     /**
4260      * Constructs an initialized data block
4261      * @param value Data to assign, may be NULL to fill with zeros
4262      * @param len Length of data, may be zero (then value is ignored)
4263      * @param copyData True to make a copy of the data, false to just insert the pointer
4264      * @param overAlloc How many bytes of memory to overallocate
4265      */
4266     DataBlock(void* value, unsigned int len, bool copyData = true, unsigned int overAlloc = 0);
4267 
4268     /**
4269      * Destroys the data, disposes the memory.
4270      */
4271     virtual ~DataBlock();
4272 
4273     /**
4274      * Get a pointer to a derived class given that class name
4275      * @param name Name of the class we are asking for
4276      * @return Pointer to the requested class or NULL if this object doesn't implement it
4277      */
4278     virtual void* getObject(const String& name) const;
4279 
4280     /**
4281      * A static empty data block
4282      */
4283     static const DataBlock& empty();
4284 
4285     /**
4286      * Get a pointer to the stored data.
4287      * @return A pointer to the data or NULL.
4288      */
data()4289     inline void* data() const
4290 	{ return m_data; }
4291 
4292     /**
4293      * Get a pointer to a byte range inside the stored data.
4294      * @param offs Byte offset inside the stored data
4295      * @param len Number of bytes that must be valid starting at offset
4296      * @return A pointer to the data or NULL if the range is not available.
4297      */
4298     inline unsigned char* data(unsigned int offs, unsigned int len = 1) const
4299 	{ return (offs + len <= m_length) ? (static_cast<unsigned char*>(m_data) + offs) : 0; }
4300 
4301     /**
4302      * Get the value of a single byte inside the stored data
4303      * @param offs Byte offset inside the stored data
4304      * @param defvalue Default value to return if offset is outside data
4305      * @return Byte value at offset (0-255) or defvalue if offset outside data
4306      */
4307     inline int at(unsigned int offs, int defvalue = -1) const
4308 	{ return (offs < m_length) ? static_cast<unsigned char*>(m_data)[offs] : defvalue; }
4309 
4310     /**
4311      * Checks if the block holds a NULL pointer.
4312      * @return True if the block holds NULL, false otherwise.
4313      */
null()4314     inline bool null() const
4315 	{ return !m_data; }
4316 
4317     /**
4318      * Get the length of the stored data.
4319      * @return The length of the stored data, zero for NULL.
4320      */
length()4321     inline unsigned int length() const
4322 	{ return m_length; }
4323 
4324     /**
4325      * Get the memory overallocation setting.
4326      * @return Amount of memory that will be overallocated.
4327      */
overAlloc()4328     inline unsigned int overAlloc() const
4329 	{ return m_overAlloc; }
4330 
4331     /**
4332      * Set the memory overallocation.
4333      * @param bytes How many bytes of memory to overallocate
4334      */
overAlloc(unsigned int bytes)4335     inline void overAlloc(unsigned int bytes)
4336 	{ m_overAlloc = bytes; }
4337 
4338     /**
4339      * Clear the data and optionally free the memory
4340      * @param deleteData True to free the deta block, false to just forget it
4341      */
4342     void clear(bool deleteData = true);
4343 
4344     /**
4345      * Assign data to the object
4346      * @param value Data to assign, may be NULL to fill with zeros
4347      * @param len Length of data, may be zero (then value is ignored)
4348      * @param copyData True to make a copy of the data, false to just insert the pointer
4349      * @param allocated Real allocated data length in case it should not be copied
4350      */
4351     DataBlock& assign(void* value, unsigned int len, bool copyData = true, unsigned int allocated = 0);
4352 
4353     /**
4354      * Append data to the current block
4355      * @param value Data to append
4356      * @param len Length of data
4357      */
append(void * value,unsigned int len)4358     inline void append(void* value, unsigned int len) {
4359 	    DataBlock tmp(value,len,false);
4360 	    append(tmp);
4361 	    tmp.clear(false);
4362 	}
4363 
4364     /**
4365      * Append data to the current block
4366      * @param value Data to append
4367      */
4368     void append(const DataBlock& value);
4369 
4370     /**
4371      * Append a String to the current block
4372      * @param value String to append
4373      */
4374     void append(const String& value);
4375 
4376     /**
4377      * Insert data before the current block
4378      * @param value Data to insert
4379      */
4380     void insert(const DataBlock& value);
4381 
4382     /**
4383      * Resize (re-alloc or free) this block if required size is not the same as the current one
4384      * @param len Required block size
4385      */
resize(unsigned int len)4386     inline void resize(unsigned int len) {
4387 	    if (len != length())
4388 		assign(0,len);
4389 	}
4390 
4391     /**
4392      * Truncate the data block
4393      * @param len The maximum length to keep
4394      */
4395     void truncate(unsigned int len);
4396 
4397     /**
4398      * Cut off a number of bytes from the data block
4399      * @param len Amount to cut, positive to cut from end, negative to cut from start of block
4400      */
4401     void cut(int len);
4402 
4403     /**
4404      * Byte indexing operator with signed parameter
4405      * @param index Index of the byte to retrieve
4406      * @return Byte value at offset (0-255) or -1 if index outside data
4407      */
4408     inline int operator[](signed int index) const
4409 	{ return at(index); }
4410 
4411     /**
4412      * Byte indexing operator with unsigned parameter
4413      * @param index Index of the byte to retrieve
4414      * @return Byte value at offset (0-255) or -1 if index outside data
4415      */
4416     inline int operator[](unsigned int index) const
4417 	{ return at(index); }
4418 
4419     /**
4420      * Assignment operator.
4421      */
4422     DataBlock& operator=(const DataBlock& value);
4423 
4424     /**
4425      * Appending operator.
4426      */
4427     inline DataBlock& operator+=(const DataBlock& value)
4428 	{ append(value); return *this; }
4429 
4430     /**
4431      * Appending operator for Strings.
4432      */
4433     inline DataBlock& operator+=(const String& value)
4434 	{ append(value); return *this; }
4435 
4436     /**
4437      * Convert data from a different format
4438      * @param src Source data block
4439      * @param sFormat Name of the source format
4440      * @param dFormat Name of the destination format
4441      * @param maxlen Maximum amount to convert, 0 to use source
4442      * @return True if converted successfully, false on failure
4443      */
4444     bool convert(const DataBlock& src, const String& sFormat,
4445 	const String& dFormat, unsigned maxlen = 0);
4446 
4447     /**
4448      * Build this data block from a hexadecimal string representation.
4449      * Each octet must be represented in the input string with 2 hexadecimal characters.
4450      * If a separator is specified, the octets in input string must be separated using
4451      *  exactly 1 separator. Only 1 leading or 1 trailing separators are allowed.
4452      * @param data Input character string
4453      * @param len Length of the input string
4454      * @param sep Separator character used between octets. 0 if no separator is expected
4455      * @return True if the input string was succesfully parsed, false otherwise
4456      */
4457     bool unHexify(const char* data, unsigned int len, char sep);
4458 
4459     /**
4460      * Build this data block from a hexadecimal string representation.
4461      * Each octet must be represented in the input string with 2 hexadecimal characters.
4462      * This method guesses if separators are used. If so the octets in input string must be
4463      *  separated using exactly 1 separator. Only 1 leading or 1 trailing separators are allowed.
4464      * @param data Input character string
4465      * @param len Length of the input string
4466      * @return True if the input string was succesfully parsed, false otherwise
4467      */
4468     bool unHexify(const char* data, unsigned int len);
4469 
4470     /**
4471      * Build this data block from a hexadecimal string representation.
4472      * This version parses a String and guesses separators presence.
4473      * @param data Input character string
4474      * @return True if the input string was succesfully parsed, false otherwise
4475      */
unHexify(const String & data)4476     inline bool unHexify(const String& data)
4477 	{ return unHexify(data.c_str(),data.length()); }
4478 
4479     /**
4480      * Create an escaped string suitable for use in SQL queries
4481      * @param extraEsc Character to escape other than the default ones
4482      * @return A string with binary zeros and other special characters escaped
4483      */
4484     String sqlEscape(char extraEsc) const;
4485 
4486 private:
4487     unsigned int allocLen(unsigned int len) const;
4488     void* m_data;
4489     unsigned int m_length;
4490     unsigned int m_allocated;
4491     unsigned int m_overAlloc;
4492 };
4493 
4494 /**
4495  * Abstract base class representing a hash calculator
4496  * @short An abstract hashing class
4497  */
4498 class YATE_API Hasher
4499 {
4500 public:
4501     /**
4502      * Destroy the instance, free allocated memory
4503      */
4504     virtual ~Hasher();
4505 
4506     /**
4507      * Clear the digest and prepare for reuse
4508      */
4509     virtual void clear() = 0;
4510 
4511     /**
4512      * Finalize the digest computation, make result ready.
4513      * Subsequent calls to @ref update() will fail
4514      */
4515     virtual void finalize() = 0;
4516 
4517     /**
4518      * Returns a pointer to the raw 16-byte binary value of the message digest.
4519      * The digest is finalized if if wasn't already
4520      * @return Pointer to the raw digest data or NULL if some error occured
4521      */
4522     virtual const unsigned char* rawDigest() = 0;
4523 
4524     /**
4525      * Returns the standard hexadecimal representation of the message digest.
4526      * The digest is finalized if if wasn't already
4527      * @return A String which holds the hex digest or a null one if some error occured
4528      */
hexDigest()4529     inline const String& hexDigest()
4530 	{ finalize(); return m_hex; }
4531 
4532     /**
4533      * Update the digest from a buffer of data
4534      * @param buf Pointer to the data to be included in digest
4535      * @param len Length of data in the buffer
4536      * @return True if success, false if @ref finalize() was already called
4537      */
update(const void * buf,unsigned int len)4538     inline bool update(const void* buf, unsigned int len)
4539 	{ return updateInternal(buf,len); }
4540 
4541     /**
4542      * Update the digest from the content of a DataBlock
4543      * @param data Data to be included in digest
4544      * @return True if success, false if @ref finalize() was already called
4545      */
update(const DataBlock & data)4546     inline bool update(const DataBlock& data)
4547 	{ return updateInternal(data.data(), data.length()); }
4548 
4549     /**
4550      * Update the digest from the content of a String
4551      * @param str String to be included in digest
4552      * @return True if success, false if @ref finalize() was already called
4553      */
update(const String & str)4554     inline bool update(const String& str)
4555 	{ return updateInternal(str.c_str(), str.length()); }
4556 
4557     /**
4558      * Digest updating operator for Strings
4559      * @param value String to be included in digest
4560      */
4561     inline Hasher& operator<<(const String& value)
4562 	{ update(value); return *this; }
4563 
4564     /**
4565      * Digest updating operator for DataBlocks
4566      * @param data Data to be included in digest
4567      */
4568     inline Hasher& operator<<(const DataBlock& data)
4569 	{ update(data); return *this; }
4570 
4571     /**
4572      * Digest updating operator for C strings
4573      * @param value String to be included in digest
4574      */
4575     Hasher& operator<<(const char* value);
4576 
4577     /**
4578      * Start a HMAC calculation, initialize the hash and the outer pad
4579      * @param opad Outer pad to be filled from key
4580      * @param key Secret key
4581      * @param keyLen Secret key length
4582      * @return True if hash and outer pad were successfully initialized
4583      */
4584     bool hmacStart(DataBlock& opad, const void* key, unsigned int keyLen);
4585 
4586     /**
4587      * Start a HMAC calculation, initialize the hash and the outer pad
4588      * @param opad Outer pad to be filled from key
4589      * @param key Secret key
4590      * @return True if hash and outer pad were successfully initialized
4591      */
hmacStart(DataBlock & opad,const DataBlock & key)4592     inline bool hmacStart(DataBlock& opad, const DataBlock& key)
4593 	{ return hmacStart(opad,key.data(),key.length()); }
4594 
4595     /**
4596      * Start a HMAC calculation, initialize the hash and the outer pad
4597      * @param opad Outer pad to be filled from key
4598      * @param key Secret key string
4599      * @return True if hash and outer pad were successfully initialized
4600      */
hmacStart(DataBlock & opad,const String & key)4601     inline bool hmacStart(DataBlock& opad, const String& key)
4602 	{ return hmacStart(opad,key.c_str(),key.length()); }
4603 
4604     /**
4605      * Finalize a HMAC calculation with this hash
4606      * @param opad Outer pad as filled by hmacStart
4607      * @return True on success, HMAC result is left in hasher
4608      */
4609     bool hmacFinal(const DataBlock& opad);
4610 
4611     /**
4612      * Compute a Message Authentication Code with this hash
4613      * @param key Secret key
4614      * @param keyLen Secret key length
4615      * @param msg Message to authenticate
4616      * @param msgLen Message length
4617      * @return True if HMAC was computed correctly, result is left in hasher
4618      */
4619     bool hmac(const void* key, unsigned int keyLen, const void* msg, unsigned int msgLen);
4620 
4621     /**
4622      * Compute a Message Authentication Code with this hash
4623      * @param key Secret key
4624      * @param msg Message to authenticate
4625      * @return True if HMAC was computed correctly, result is left in hasher
4626      */
hmac(const DataBlock & key,const DataBlock & msg)4627     inline bool hmac(const DataBlock& key, const DataBlock& msg)
4628 	{ return hmac(key.data(),key.length(),msg.data(),msg.length()); }
4629 
4630     /**
4631      * Compute a Message Authentication Code with this hash
4632      * @param key Secret key string
4633      * @param msg Message string to authenticate
4634      * @return True if HMAC was computed correctly, result is left in hasher
4635      */
hmac(const String & key,const String & msg)4636     inline bool hmac(const String& key, const String& msg)
4637 	{ return hmac(key.c_str(),key.length(),msg.c_str(),msg.length()); }
4638 
4639     /**
4640      * Return the length of the raw binary digest
4641      * @return Length of the digest in octets
4642      */
4643     virtual unsigned int hashLength() const = 0;
4644 
4645     /**
4646      * Return the size of the block used in HMAC calculations
4647      * @return HMAC block size in octets, usually 64
4648      */
4649     virtual unsigned int hmacBlockSize() const;
4650 
4651 protected:
4652     /**
4653      * Default constructor
4654      */
Hasher()4655     inline Hasher()
4656 	: m_private(0)
4657 	{ }
4658 
4659     /**
4660      * Update the digest from a buffer of data
4661      * @param buf Pointer to the data to be included in digest
4662      * @param len Length of data in the buffer
4663      * @return True if success, false if @ref finalize() was already called
4664      */
4665     virtual bool updateInternal(const void* buf, unsigned int len) = 0;
4666 
4667     void* m_private;
4668     String m_hex;
4669 };
4670 
4671 /**
4672  * A class to compute and check MD5 digests
4673  * @short A standard MD5 digest calculator
4674  */
4675 class YATE_API MD5 : public Hasher
4676 {
4677 public:
4678     /**
4679      * Construct a fresh initialized instance
4680      */
4681     MD5();
4682 
4683     /**
4684      * Copy constructor
4685      * @param original MD5 instance to copy
4686      */
4687     MD5(const MD5& original);
4688 
4689     /**
4690      * Construct a digest from a buffer of data
4691      * @param buf Pointer to the data to be included in digest
4692      * @param len Length of data in the buffer
4693      */
4694     MD5(const void* buf, unsigned int len);
4695 
4696     /**
4697      * Construct a digest from a binary DataBlock
4698      * @param data Binary data to be included in digest
4699      */
4700     MD5(const DataBlock& data);
4701 
4702     /**
4703      * Construct a digest from a String
4704      * @param str String to be included in digest
4705      */
4706     MD5(const String& str);
4707 
4708     /**
4709      * Assignment operator.
4710      */
4711     MD5& operator=(const MD5& original);
4712 
4713     /**
4714      * Destroy the instance, free allocated memory
4715      */
4716     virtual ~MD5();
4717 
4718     /**
4719      * Clear the digest and prepare for reuse
4720      */
4721     virtual void clear();
4722 
4723     /**
4724      * Finalize the digest computation, make result ready.
4725      * Subsequent calls to @ref update() will fail
4726      */
4727     virtual void finalize();
4728 
4729     /**
4730      * Returns a pointer to the raw 16-byte binary value of the message digest.
4731      * The digest is finalized if if wasn't already
4732      * @return Pointer to the raw digest data or NULL if some error occured
4733      */
4734     virtual const unsigned char* rawDigest();
4735 
4736     /**
4737      * Return the length of the raw binary digest
4738      * @return Constant value of 16
4739      */
rawLength()4740     inline static unsigned int rawLength()
4741 	{ return 16; }
4742 
4743     /**
4744      * Return the length of the raw binary digest
4745      * @return Length of the digest in octets
4746      */
hashLength()4747     virtual unsigned int hashLength() const
4748 	{ return 16; }
4749 
4750 protected:
4751     bool updateInternal(const void* buf, unsigned int len);
4752 
4753 private:
4754     void init();
4755     unsigned char m_bin[16];
4756 };
4757 
4758 /**
4759  * A class to compute and check SHA1 digests
4760  * @short A standard SHA1 digest calculator
4761  */
4762 class YATE_API SHA1 : public Hasher
4763 {
4764 public:
4765     /**
4766      * Construct a fresh initialized instance
4767      */
4768     SHA1();
4769 
4770     /**
4771      * Copy constructor
4772      * @param original SHA1 instance to copy
4773      */
4774     SHA1(const SHA1& original);
4775 
4776     /**
4777      * Construct a digest from a buffer of data
4778      * @param buf Pointer to the data to be included in digest
4779      * @param len Length of data in the buffer
4780      */
4781     SHA1(const void* buf, unsigned int len);
4782 
4783     /**
4784      * Construct a digest from a binary DataBlock
4785      * @param data Binary data to be included in digest
4786      */
4787     SHA1(const DataBlock& data);
4788 
4789     /**
4790      * Construct a digest from a String
4791      * @param str String to be included in digest
4792      */
4793     SHA1(const String& str);
4794 
4795     /**
4796      * Assignment operator.
4797      */
4798     SHA1& operator=(const SHA1& original);
4799 
4800     /**
4801      * Destroy the instance, free allocated memory
4802      */
4803     virtual ~SHA1();
4804 
4805     /**
4806      * Clear the digest and prepare for reuse
4807      */
4808     virtual void clear();
4809 
4810     /**
4811      * Finalize the digest computation, make result ready.
4812      * Subsequent calls to @ref update() will fail
4813      */
4814     virtual void finalize();
4815 
4816     /**
4817      * Returns a pointer to the raw 20-byte binary value of the message digest.
4818      * The digest is finalized if if wasn't already
4819      * @return Pointer to the raw digest data or NULL if some error occured
4820      */
4821     virtual const unsigned char* rawDigest();
4822 
4823     /**
4824      * Return the length of the raw binary digest
4825      * @return Constant value of 20
4826      */
rawLength()4827     inline static unsigned int rawLength()
4828 	{ return 20; }
4829 
4830     /**
4831      * Return the length of the raw binary digest
4832      * @return Length of the digest in octets
4833      */
hashLength()4834     virtual unsigned int hashLength() const
4835 	{ return 20; }
4836 
4837     /**
4838      * NIST FIPS 186-2 change notice 1 Pseudo Random Function.
4839      * Uses a b=160 bits SHA1 based G(t,c) function with no XSEEDj
4840      * @param out Block to fill with pseudo-random data
4841      * @param seed Data to use as RNG seed, must be 1 to 64 octets long
4842      * @param len Desired output length in octets, must be 1 to 512
4843      * @return True on success, false on invalid lengths
4844      */
4845     static bool fips186prf(DataBlock& out, const DataBlock& seed, unsigned int len);
4846 
4847 protected:
4848     bool updateInternal(const void* buf, unsigned int len);
4849 
4850 private:
4851     void init();
4852     unsigned char m_bin[20];
4853 };
4854 
4855 /**
4856  * A class to compute and check SHA256 digests
4857  * @short A standard SHA256 digest calculator
4858  */
4859 class YATE_API SHA256 : public Hasher
4860 {
4861 public:
4862     /**
4863      * Construct a fresh initialized instance
4864      */
4865     SHA256();
4866 
4867     /**
4868      * Copy constructor
4869      * @param original SHA256 instance to copy
4870      */
4871     SHA256(const SHA256& original);
4872 
4873     /**
4874      * Construct a digest from a buffer of data
4875      * @param buf Pointer to the data to be included in digest
4876      * @param len Length of data in the buffer
4877      */
4878     SHA256(const void* buf, unsigned int len);
4879 
4880     /**
4881      * Construct a digest from a binary DataBlock
4882      * @param data Binary data to be included in digest
4883      */
4884     SHA256(const DataBlock& data);
4885 
4886     /**
4887      * Construct a digest from a String
4888      * @param str String to be included in digest
4889      */
4890     SHA256(const String& str);
4891 
4892     /**
4893      * Assignment operator.
4894      */
4895     SHA256& operator=(const SHA256& original);
4896 
4897     /**
4898      * Destroy the instance, free allocated memory
4899      */
4900     virtual ~SHA256();
4901 
4902     /**
4903      * Clear the digest and prepare for reuse
4904      */
4905     virtual void clear();
4906 
4907     /**
4908      * Finalize the digest computation, make result ready.
4909      * Subsequent calls to @ref update() will fail
4910      */
4911     virtual void finalize();
4912 
4913     /**
4914      * Returns a pointer to the raw 32-byte binary value of the message digest.
4915      * The digest is finalized if if wasn't already
4916      * @return Pointer to the raw digest data or NULL if some error occured
4917      */
4918     virtual const unsigned char* rawDigest();
4919 
4920     /**
4921      * Return the length of the raw binary digest
4922      * @return Constant value of 32
4923      */
rawLength()4924     inline static unsigned int rawLength()
4925 	{ return 32; }
4926 
4927     /**
4928      * Return the length of the raw binary digest
4929      * @return Length of the digest in octets
4930      */
hashLength()4931     virtual unsigned int hashLength() const
4932 	{ return 32; }
4933 
4934 protected:
4935     bool updateInternal(const void* buf, unsigned int len);
4936 
4937 private:
4938     void init();
4939     unsigned char m_bin[32];
4940 };
4941 
4942 /**
4943  * Base64 encoder/decoder class
4944  * @short Base64 encoder/decoder class
4945  */
4946 class YATE_API Base64 : public DataBlock
4947 {
4948     YNOCOPY(Base64); // no automatic copies please
4949 public:
4950     /**
4951      * Constructor
4952      */
Base64()4953     inline Base64()
4954 	{ }
4955 
4956     /**
4957      * Constructor. Set the buffer
4958      * @param src Initial data buffer
4959      * @param len Initial data buffer length
4960      * @param copyData True to make a copy of the received data
4961      */
4962     inline Base64(void* src, unsigned int len, bool copyData = true)
DataBlock(src,len,copyData)4963 	: DataBlock(src,len,copyData)
4964 	{ }
4965 
4966     /**
4967      * Encode this buffer to a destination string
4968      * @param dest Destination string
4969      * @param lineLen The length of a line. If non 0, a line break (CR/LF) will
4970      *  be inserted in the encoded data after each lineLine characters.
4971      *  No line break will be added after the last line. Use the lineAtEnd
4972      *  parameter to do that
4973      * @param lineAtEnd True to add a line break at the end of encoded data
4974      */
4975     void encode(String& dest, unsigned int lineLen = 0, bool lineAtEnd = false);
4976 
4977     /**
4978      * Decode this buffer to a destination one
4979      * @param dest Destination data buffer
4980      * @param liberal True to use 'liberal' rules when decoding. Some non alphabet
4981      *  characters (such as CR, LF, TAB, SPACE or the Base64 padding char '=')
4982      *  will be accepted and ignored. The resulting number of Base64 chars to
4983      *  decode must be a valid one
4984      * @return True on succes, false if an invalid (non Base64) character was
4985      *  found or the number of Base64 characters is invalid (must be a multiple
4986      *  of 4 plus 0, 2 or 3 characters) or the padding is incorrect
4987      */
4988     bool decode(DataBlock& dest, bool liberal = true);
4989 
4990     /**
4991      * Base64 append operator for Strings
4992      */
4993     inline Base64& operator<<(const String& value)
4994 	{ append(value); return *this; }
4995 
4996     /**
4997      * Base64 append operator for DataBlocks
4998      */
4999     inline Base64& operator<<(const DataBlock& data)
5000 	{ append(data); return *this; }
5001 
5002     /**
5003      * Base64 append operator for C strings
5004      */
5005     inline Base64& operator<<(const char* value)
5006 	{ return operator<<(String(value)); }
5007 };
5008 
5009 class NamedIterator;
5010 
5011 /**
5012  * This class holds a named list of named strings
5013  * @short A named string container class
5014  */
5015 class YATE_API NamedList : public String
5016 {
5017     friend class NamedIterator;
5018 public:
5019     /**
5020      * Creates a new named list.
5021      * @param name Name of the list - must not be NULL or empty
5022      */
5023     explicit NamedList(const char* name);
5024 
5025     /**
5026      * Copy constructor
5027      * @param original Named list we are copying
5028      */
5029     NamedList(const NamedList& original);
5030 
5031     /**
5032      * Creates a named list with subparameters of another list.
5033      * @param name Name of the list - must not be NULL or empty
5034      * @param original Named list to copy parameters from
5035      * @param prefix Prefix to match and remove from parameter names
5036      */
5037     NamedList(const char* name, const NamedList& original, const String& prefix);
5038 
5039     /**
5040      * Assignment operator
5041      * @param value New name and parameters to assign
5042      * @return Reference to this NamedList
5043      */
5044     NamedList& operator=(const NamedList& value);
5045 
5046     /**
5047      * Get a pointer to a derived class given that class name
5048      * @param name Name of the class we are asking for
5049      * @return Pointer to the requested class or NULL if this object doesn't implement it
5050      */
5051     virtual void* getObject(const String& name) const;
5052 
5053     /**
5054      * Get the number of parameters
5055      * @return Count of named strings
5056      */
length()5057     inline unsigned int length() const
5058 	{ return m_params.length(); }
5059 
5060     /**
5061      * Get the number of non-null parameters
5062      * @return Count of existing named strings
5063      */
count()5064     inline unsigned int count() const
5065 	{ return m_params.count(); }
5066 
5067     /**
5068      * Clear all parameters
5069      */
clearParams()5070     inline void clearParams()
5071 	{ m_params.clear(); }
5072 
5073     /**
5074      * Add a named string to the parameter list.
5075      * @param param Parameter to add
5076      * @return Reference to this NamedList
5077      */
5078     NamedList& addParam(NamedString* param);
5079 
5080     /**
5081      * Add a named string to the parameter list.
5082      * @param name Name of the new string
5083      * @param value Value of the new string
5084      * @param emptyOK True to always add parameter, false to skip empty values
5085      * @return Reference to this NamedList
5086      */
5087     NamedList& addParam(const char* name, const char* value, bool emptyOK = true);
5088 
5089     /**
5090      * Set a named string in the parameter list.
5091      * @param param Parameter to set or add
5092      * @return Reference to this NamedList
5093      */
setParam(NamedString * param)5094     inline NamedList& setParam(NamedString* param)
5095     {
5096 	if (param)
5097 	    m_params.setUnique(param);
5098 	return *this;
5099     }
5100 
5101     /**
5102      * Set a named string in the parameter list.
5103      * @param name Name of the string
5104      * @param value Value of the string
5105      * @return Reference to this NamedList
5106      */
5107     NamedList& setParam(const String& name, const char* value);
5108 
5109     /**
5110      * Clears all instances of a named string in the parameter list.
5111      * @param name Name of the string to remove
5112      * @param childSep If set clears all child parameters in format name+childSep+anything
5113      * @return Reference to this NamedList
5114      */
5115     NamedList& clearParam(const String& name, char childSep = 0);
5116 
5117     /**
5118      * Remove a specific parameter
5119      * @param param Pointer to parameter to remove
5120      * @param delParam True to destroy the parameter
5121      * @return Reference to this NamedList
5122      */
5123     NamedList& clearParam(NamedString* param, bool delParam = true);
5124 
5125     /**
5126      * Copy a parameter from another NamedList, clears it if not present there
5127      * @param original NamedList to copy the parameter from
5128      * @param name Name of the string to copy or clear
5129      * @param childSep If set copies all child parameters in format name+childSep+anything
5130      * @return Reference to this NamedList
5131      */
5132     NamedList& copyParam(const NamedList& original, const String& name, char childSep = 0);
5133 
5134     /**
5135      * Copy all parameters from another NamedList, does not clear list first
5136      * @param original NamedList to copy the parameters from
5137      * @return Reference to this NamedList
5138      */
5139     NamedList& copyParams(const NamedList& original);
5140 
5141     /**
5142      * Copy multiple parameters from another NamedList, clears them if not present there
5143      * @param original NamedList to copy the parameters from
5144      * @param list List of objects (usually String) whose name (blanks stripped) is used as parameters names
5145      * @param childSep If set copies all child parameters in format name+childSep+anything
5146      * @return Reference to this NamedList
5147      */
5148     NamedList& copyParams(const NamedList& original, ObjList* list, char childSep = 0);
5149 
5150     /**
5151      * Copy multiple parameters from another NamedList, clears it if not present there
5152      * @param original NamedList to copy the parameter from
5153      * @param list Comma separated list of parameters to copy or clear
5154      * @param childSep If set copies all child parameters in format name+childSep+anything
5155      * @return Reference to this NamedList
5156      */
5157     NamedList& copyParams(const NamedList& original, const String& list, char childSep = 0);
5158 
5159     /**
5160      * Copy subparameters from another list
5161      * @param original Named list to copy parameters from
5162      * @param prefix Prefix to match in parameter names, must not be NULL
5163      * @param skipPrefix Skip over the prefix when building new parameter name
5164      * @param replace Set to true to replace list parameter instead of adding a new one
5165      * @return Reference to this NamedList
5166      */
5167     NamedList& copySubParams(const NamedList& original, const String& prefix,
5168 	bool skipPrefix = true, bool replace = false);
5169 
5170     /**
5171      * Check if we have a parameter that starts with prefix
5172      * @param prefix Prefix to match in parameter name, must not be NULL
5173      * @return True if a parameter starts with prefix
5174      */
5175     bool hasSubParams(const char* prefix) const;
5176 
5177     /**
5178      * Get the index of a named string in the parameter list.
5179      * @param param Pointer to the parameter to locate
5180      * @return Index of the named string or -1 if not found
5181      */
5182     int getIndex(const NamedString* param) const;
5183 
5184     /**
5185      * Get the index of first matching named string in the parameter list.
5186      * @param name Name of parameter to locate
5187      * @return Index of the first matching named string or -1 if not found
5188      */
5189     int getIndex(const String& name) const;
5190 
5191     /**
5192      * Locate a named string in the parameter list.
5193      * @param name Name of parameter to locate
5194      * @return A pointer to the named string or NULL.
5195      */
5196     NamedString* getParam(const String& name) const;
5197 
5198     /**
5199      * Locate a named string in the parameter list.
5200      * @param index Index of the parameter to locate
5201      * @return A pointer to the named string or NULL.
5202      */
5203     NamedString* getParam(unsigned int index) const;
5204 
5205     /**
5206      * Parameter access operator
5207      * @param name Name of the parameter to return
5208      * @return String value of the parameter, @ref String::empty() if missing
5209      */
5210     const String& operator[](const String& name) const;
5211 
5212     /**
5213      * Retrieve the value of a named parameter.
5214      * @param name Name of parameter to locate
5215      * @param defvalue Default value to return if not found
5216      * @return The string contained in the named parameter or the default
5217      */
5218     const char* getValue(const String& name, const char* defvalue = 0) const;
5219 
5220     /**
5221      * Retrieve the numeric value of a parameter.
5222      * @param name Name of parameter to locate
5223      * @param defvalue Default value to return if not found
5224      * @param minvalue Minimum value allowed for the parameter
5225      * @param maxvalue Maximum value allowed for the parameter
5226      * @param clamp Control the out of bound values: true to adjust to the nearest
5227      *  bound, false to return the default value
5228      * @return The number contained in the named parameter or the default
5229      */
5230     int getIntValue(const String& name, int defvalue = 0, int minvalue = INT_MIN,
5231 	int maxvalue = INT_MAX, bool clamp = true) const;
5232 
5233     /**
5234      * Retrieve the numeric value of a parameter trying first a table lookup.
5235      * @param name Name of parameter to locate
5236      * @param tokens A pointer to an array of tokens to try to lookup
5237      * @param defvalue Default value to return if not found
5238      * @return The number contained in the named parameter or the default
5239      */
5240     int getIntValue(const String& name, const TokenDict* tokens, int defvalue = 0) const;
5241 
5242     /**
5243      * Retrieve the 64-bit numeric value of a parameter.
5244      * @param name Name of parameter to locate
5245      * @param defvalue Default value to return if not found
5246      * @param minvalue Minimum value allowed for the parameter
5247      * @param maxvalue Maximum value allowed for the parameter
5248      * @param clamp Control the out of bound values: true to adjust to the nearest
5249      *  bound, false to return the default value
5250      * @return The number contained in the named parameter or the default
5251      */
5252     int64_t getInt64Value(const String& name, int64_t defvalue = 0, int64_t minvalue = LLONG_MIN,
5253 	int64_t maxvalue = LLONG_MAX, bool clamp = true) const;
5254 
5255     /**
5256      * Retrieve the unsigned 64-bit numeric value of a parameter.
5257      * @param name Name of parameter to locate
5258      * @param defvalue Default value to return if not found
5259      * @param minvalue Minimum value allowed for the parameter
5260      * @param maxvalue Maximum value allowed for the parameter
5261      * @param clamp Control the out of bound values: true to adjust to the nearest
5262      *  bound, false to return the default value
5263      * @return The number contained in the named parameter or the default
5264      */
5265     uint64_t getUInt64Value(const String& name, uint64_t defvalue = 0, uint64_t minvalue = 0,
5266         uint64_t maxvalue = ULLONG_MAX, bool clamp = true) const;
5267 
5268     /**
5269      * Retrieve the floating point value of a parameter.
5270      * @param name Name of parameter to locate
5271      * @param defvalue Default value to return if not found
5272      * @return The number contained in the named parameter or the default
5273      */
5274     double getDoubleValue(const String& name, double defvalue = 0.0) const;
5275 
5276     /**
5277      * Retrieve the boolean value of a parameter.
5278      * @param name Name of parameter to locate
5279      * @param defvalue Default value to return if not found
5280      * @return The boolean value contained in the named parameter or the default
5281      */
5282     bool getBoolValue(const String& name, bool defvalue = false) const;
5283 
5284     /**
5285      * Replaces all ${paramname} in a String with the corresponding parameters
5286      * @param str String in which the replacements will be made
5287      * @param sqlEsc True to apply SQL escaping to parameter values
5288      * @param extraEsc Character to escape other than the SQL default ones
5289      * @return Number of replacements made, -1 if an error occured
5290      */
5291     int replaceParams(String& str, bool sqlEsc = false, char extraEsc = 0) const;
5292 
5293     /**
5294      * Dumps the name and all parameters to a string in a human readable format.
5295      * No escaping takes place so this method should be used for debugging only
5296      * @param str String to which the name and parameters are appended
5297      * @param separator Separator string to use before each parameter
5298      * @param quote String quoting character, usually single or double quote
5299      * @param force True to insert the separator even in an empty string
5300      */
5301     void dump(String& str, const char* separator, char quote = 0, bool force = false) const;
5302 
5303     /**
5304      * A static empty named list
5305      * @return Reference to a static empty named list
5306      */
5307     static const NamedList& empty();
5308 
5309     /**
5310      * Get the parameters list
5311      * @return Pointer to the parameters list
5312      */
paramList()5313     inline ObjList* paramList()
5314 	{ return &m_params; }
5315 
5316     /**
5317      * Get the parameters list
5318      * @return Pointer to the parameters list
5319      */
paramList()5320     inline const ObjList* paramList() const
5321 	{ return &m_params; }
5322 
5323 private:
5324     NamedList(); // no default constructor please
5325     ObjList m_params;
5326 };
5327 
5328 /**
5329  * An iterator for NamedString parameters of a NamedList.
5330  * Fast but unsafe, the list must not be modified during iteration.
5331  * @short NamedList parameters iterator
5332  */
5333 class YATE_API NamedIterator
5334 {
5335 public:
5336     /**
5337      * Constructor
5338      * @param list NamedList whose parameters are iterated
5339      */
NamedIterator(const NamedList & list)5340     inline NamedIterator(const NamedList& list)
5341 	: m_list(&list), m_item(list.m_params.skipNull())
5342 	{ }
5343 
5344     /**
5345      * Copy constructor, points to same list and position as the original
5346      * @param original Iterator to copy from
5347      */
NamedIterator(const NamedIterator & original)5348     inline NamedIterator(const NamedIterator& original)
5349 	: m_list(original.m_list), m_item(original.m_item)
5350 	{ }
5351 
5352     /**
5353      * Assignment from list operator
5354      * @param list NamedList whose parameters are iterated
5355      */
5356     inline NamedIterator& operator=(const NamedList& list)
5357 	{ m_list = &list; m_item = list.m_params.skipNull(); return *this; }
5358 
5359     /**
5360      * Assignment operator, points to same list and position as the original
5361      * @param original Iterator to copy from
5362      */
5363     inline NamedIterator& operator=(const NamedIterator& original)
5364 	{ m_list = original.m_list; m_item = original.m_item; return *this; }
5365 
5366     /**
5367      * Get the current parameter and advance in the list
5368      * @return Pointer to list parameter or NULL if advanced past end (eof)
5369      */
5370     const NamedString* get();
5371 
5372     /**
5373      * Check if the iteration reached end of the parameters list
5374      */
eof()5375     inline bool eof() const
5376 	{ return !m_item; }
5377 
5378     /**
5379      * Reset the iterator to the first position in the parameters list
5380      */
reset()5381     inline void reset()
5382 	{ m_item = m_list->m_params.skipNull(); }
5383 
5384 private:
5385     NamedIterator(); // no default constructor please
5386     const NamedList* m_list;
5387     const ObjList* m_item;
5388 };
5389 
5390 /**
5391  * Uniform Resource Identifier encapsulation and parser.
5392  * For efficiency reason the parsing is delayed as long as possible
5393  * @short Encapsulation for an URI
5394  */
5395 class YATE_API URI : public String
5396 {
5397 public:
5398     /**
5399      * Empty URI constructor
5400      */
5401     URI();
5402 
5403     /**
5404      * Copy constructor
5405      * @param uri Original URI to copy
5406      */
5407     URI(const URI& uri);
5408 
5409     /**
5410      * Constructor from a String that gets parsed later
5411      * @param uri String form of the URI
5412      */
5413     explicit URI(const String& uri);
5414 
5415     /**
5416      * Constructor from a C string that gets parsed later
5417      * @param uri String form of the URI
5418      */
5419     explicit URI(const char* uri);
5420 
5421     /**
5422      * Constructor from URI components
5423      * @param proto Protocol - something like "http", "sip", etc.
5424      * @param user User component of the URI
5425      * @param host Hostname component of the URI
5426      * @param port Port part of the URI (optional)
5427      * @param desc Description part in front of the URI (optional)
5428      */
5429     URI(const char* proto, const char* user, const char* host, int port = 0, const char* desc = 0);
5430 
5431     /**
5432      * Calling this method ensures the string URI is parsed into components
5433      */
5434     void parse() const;
5435 
5436     /**
5437      * Assignment operator from URI
5438      * @param value New URI value to assign
5439      */
5440     inline URI& operator=(const URI& value)
5441 	{ String::operator=(value); return *this; }
5442 
5443     /**
5444      * Assignment operator from String
5445      * @param value New URI value to assign
5446      */
5447     inline URI& operator=(const String& value)
5448 	{ String::operator=(value); return *this; }
5449 
5450     /**
5451      * Assignment operator from C string
5452      * @param value New URI value to assign
5453      */
5454     inline URI& operator=(const char* value)
5455 	{ String::operator=(value); return *this; }
5456 
5457     /**
5458      * Access method to the description part of the URI
5459      * @return Description part of the URI
5460      */
getDescription()5461     inline const String& getDescription() const
5462 	{ parse(); return m_desc; }
5463 
5464     /**
5465      * Access method to the protocol part of the URI
5466      * @return Protocol part of the URI
5467      */
getProtocol()5468     inline const String& getProtocol() const
5469 	{ parse(); return m_proto; }
5470 
5471     /**
5472      * Access method to the user part of the URI
5473      * @return User component of the URI
5474      */
getUser()5475     inline const String& getUser() const
5476 	{ parse(); return m_user; }
5477 
5478     /**
5479      * Access method to the host part of the URI
5480      * @return Hostname part of the URI
5481      */
getHost()5482     inline const String& getHost() const
5483 	{ parse(); return m_host; }
5484 
5485     /**
5486      * Access method to the port part of the URI
5487      * @return Port of the URI, zero if not set
5488      */
getPort()5489     inline int getPort() const
5490 	{ parse(); return m_port; }
5491 
5492     /**
5493      * Access method to the additional text part of the URI
5494      * @return Additional text of the URI including the separator
5495      */
getExtra()5496     inline const String& getExtra() const
5497 	{ parse(); return m_extra; }
5498 
5499 protected:
5500     /**
5501      * Notification method called whenever the string URI has changed.
5502      * The default behaviour is to invalidate the parsed flag and cal the
5503      *  method inherited from @ref String.
5504      */
5505     virtual void changed();
5506     mutable bool m_parsed;
5507     mutable String m_desc;
5508     mutable String m_proto;
5509     mutable String m_user;
5510     mutable String m_host;
5511     mutable String m_extra;
5512     mutable int m_port;
5513 };
5514 
5515 class MutexPrivate;
5516 class SemaphorePrivate;
5517 class ThreadPrivate;
5518 
5519 /**
5520  * An abstract base class for implementing lockable objects
5521  * @short Abstract interface for lockable objects
5522  */
5523 class YATE_API Lockable
5524 {
5525 public:
5526     /**
5527      * Destructor
5528      */
5529     virtual ~Lockable();
5530 
5531     /**
5532      * Attempt to lock the object and eventually wait for it
5533      * @param maxwait Time in microseconds to wait, -1 wait forever
5534      * @return True if successfully locked, false on failure
5535      */
5536     virtual bool lock(long maxwait = -1) = 0;
5537 
5538     /**
5539      * Unlock the object, does never wait
5540      * @return True if successfully unlocked the object
5541      */
5542     virtual bool unlock() = 0;
5543 
5544     /**
5545      * Check if the object is currently locked - as it's asynchronous it
5546      *  guarantees nothing if other thread changes the status
5547      * @return True if the object was locked when the function was called
5548      */
5549     virtual bool locked() const = 0;
5550 
5551     /**
5552      * Check if the object is unlocked (try to lock and unlock it)
5553      * @param maxwait Time in microseconds to wait, -1 to wait forever
5554      * @return True if successfully locked and unlocked, false on failure
5555      */
5556     virtual bool check(long maxwait = -1);
5557 
5558     /**
5559      * Fully unlock the object, even if it was previously multiple locked.
5560      * There is no guarantee about the object status after the function returns.
5561      * This function should be used only if you understand it very well
5562      * @return True if the object was fully unlocked
5563      */
5564     virtual bool unlockAll();
5565 
5566     /**
5567      * Set a maximum wait time for debugging purposes
5568      * @param maxwait Maximum time in microseconds to wait for any lockable
5569      *  object when no time limit was requested, zero to disable limit
5570      */
5571     static void wait(unsigned long maxwait);
5572 
5573     /**
5574      * Get the maximum wait time used for debugging purposes
5575      * @return Maximum time in microseconds, zero if no maximum is set
5576      */
5577     static unsigned long wait();
5578 
5579     /**
5580      * Start actually using lockables, for platforms where these objects are not
5581      *  usable in global object constructors.
5582      * This method must be called at least once somewhere from main() but
5583      *  before creating any threads and without holding any object locked.
5584      */
5585     static void startUsingNow();
5586 
5587     /**
5588      * Enable some safety and sanity check features.
5589      * This provides a safer code and easier locking debugging at the price of performance penalty.
5590      * This method must be called early and not changed after initialization
5591      * @param safe True to enable locking safety measures, false to disable
5592      */
5593     static void enableSafety(bool safe = true);
5594 
5595     /**
5596      * Retrieve safety and sanity check features flag value
5597      * @return Locking safety measures flag value
5598      */
5599     static bool safety();
5600 };
5601 
5602 /**
5603  * A simple mutual exclusion for locking access between threads
5604  * @short Mutex support
5605  */
5606 class YATE_API Mutex : public Lockable
5607 {
5608     friend class MutexPrivate;
5609 public:
5610     /**
5611      * Construct a new unlocked mutex
5612      * @param recursive True if the mutex has to be recursive (reentrant),
5613      *  false for a normal fast mutex
5614      * @param name Static name of the mutex (for debugging purpose only)
5615      */
5616     explicit Mutex(bool recursive = false, const char* name = 0);
5617 
5618     /**
5619      * Copy constructor, creates a shared mutex
5620      * @param original Reference of the mutex to share
5621      */
5622     Mutex(const Mutex& original);
5623 
5624     /**
5625      * Destroy the mutex
5626      */
5627     ~Mutex();
5628 
5629     /**
5630      * Assignment operator makes the mutex shared with the original
5631      * @param original Reference of the mutex to share
5632      */
5633     Mutex& operator=(const Mutex& original);
5634 
5635     /**
5636      * Attempt to lock the mutex and eventually wait for it
5637      * @param maxwait Time in microseconds to wait for the mutex, -1 wait forever
5638      * @return True if successfully locked, false on failure
5639      */
5640     virtual bool lock(long maxwait = -1);
5641 
5642     /**
5643      * Unlock the mutex, does never wait
5644      * @return True if successfully unlocked the mutex
5645      */
5646     virtual bool unlock();
5647 
5648     /**
5649      * Check if the mutex is currently locked - as it's asynchronous it
5650      *  guarantees nothing if other thread changes the mutex's status
5651      * @return True if the mutex was locked when the function was called
5652      */
5653     virtual bool locked() const;
5654 
5655     /**
5656      * Retrieve the name of the Thread (if any) holding the Mutex locked
5657      * @return Thread name() or NULL if thread not named
5658      */
5659     const char* owner() const;
5660 
5661     /**
5662      * Check if this mutex is recursive or not
5663      * @return True if this is a recursive mutex, false for a fast mutex
5664      */
5665     bool recursive() const;
5666 
5667     /**
5668      * Get the number of mutexes counting the shared ones only once
5669      * @return Count of individual mutexes
5670      */
5671     static int count();
5672 
5673     /**
5674      * Get the number of currently locked mutexes
5675      * @return Count of locked mutexes, -1 if unknown (not tracked)
5676      */
5677     static int locks();
5678 
5679     /**
5680      * Check if a timed lock() is efficient on this platform
5681      * @return True if a lock with a maxwait parameter is efficiently implemented
5682      */
5683     static bool efficientTimedLock();
5684 
5685 private:
5686     MutexPrivate* privDataCopy() const;
5687     MutexPrivate* m_private;
5688 };
5689 
5690 /**
5691  * This class holds a Mutex array. Mutexes can be retrieved based on object pointers.
5692  * A mutex pool can be used to associate a smaller set of Mutex objects with a much
5693  *  larger set of objects needing lock.
5694  * @short A Mutex pool
5695  */
5696 class YATE_API MutexPool
5697 {
5698 public:
5699     /**
5700      * Build the mutex pool
5701      * @param len The number of mutex objects to build. The length should be an
5702      *  odd number to obtain an optimal distribution of pointer based mutexes
5703      *  (usually pointers are aligned at even addresses): some mutexes might never
5704      *  get used if the length is an even number
5705      * @param recursive True if the mutex has to be recursive (reentrant),
5706      *  false for a normal fast mutex
5707      * @param name Static name of the mutex (for debugging purpose only)
5708      */
5709     MutexPool(unsigned int len = 13, bool recursive = false, const char* name = 0);
5710 
5711     /**
5712      * Destructor. Release data
5713      */
5714     ~MutexPool();
5715 
5716     /**
5717      * Build an index from object pointer (pointer value modulo array length).
5718      * Always cast the pointer to the same type when calling this method to
5719      *  make sure the same index is returned for a given object
5720      * @param ptr The pointer to object
5721      * @return Valid array index
5722      */
index(void * ptr)5723     inline unsigned int index(void* ptr) const
5724 	{ return ((unsigned int)(unsigned long)ptr) % m_length; }
5725 
5726     /**
5727      * Retrieve the mutex associated with a given pointer.
5728      * Always cast the pointer to the same type when calling this method to
5729      *  make sure the same mutex is returned for a given object
5730      * @param ptr The pointer to object
5731      * @return Valid Mutex pointer
5732      */
mutex(void * ptr)5733     inline Mutex* mutex(void* ptr) const
5734 	{ return m_data[index(ptr)]; }
5735 
5736     /**
5737      * Retrieve the mutex at a given index modulo array length
5738      * @param idx The index
5739      * @return Valid Mutex pointer
5740      */
mutex(unsigned int idx)5741     inline Mutex* mutex(unsigned int idx) const
5742 	{ return m_data[idx % m_length]; }
5743 
5744 private:
5745     String* m_name;                      // Mutex names
5746     Mutex** m_data;                      // The array
5747     unsigned int m_length;               // Array length
5748 };
5749 
5750 /**
5751  * A semaphore object for synchronizing threads, can also be used as a token bucket
5752  * @short Semaphore implementation
5753  */
5754 class YATE_API Semaphore : public Lockable
5755 {
5756     friend class SemaphorePrivate;
5757 public:
5758     /**
5759      * Construct a new unlocked semaphore
5760      * @param maxcount Maximum unlock count, must be strictly positive
5761      * @param name Static name of the semaphore (for debugging purpose only)
5762      * @param initialCount Initial semaphore count, must not be greater than maxcount
5763      */
5764     explicit Semaphore(unsigned int maxcount = 1, const char* name = 0,
5765 	unsigned int initialCount = 1);
5766 
5767     /**
5768      * Copy constructor, creates a shared semaphore
5769      * @param original Reference of the semaphore to share
5770      */
5771     Semaphore(const Semaphore& original);
5772 
5773     /**
5774      * Destroy the semaphore
5775      */
5776     ~Semaphore();
5777 
5778     /**
5779      * Assignment operator makes the semaphore shared with the original
5780      * @param original Reference of the semaphore to share
5781      */
5782     Semaphore& operator=(const Semaphore& original);
5783 
5784     /**
5785      * Attempt to get a lock on the semaphore and eventually wait for it
5786      * @param maxwait Time in microseconds to wait, -1 wait forever
5787      * @return True if successfully locked, false on failure
5788      */
5789     virtual bool lock(long maxwait = -1);
5790 
5791     /**
5792      * Unlock the semaphore, does never wait nor get over counter maximum
5793      * @return True if successfully unlocked
5794      */
5795     virtual bool unlock();
5796 
5797     /**
5798      * Check if the semaphore is currently locked (waiting) - as it's
5799      *  asynchronous it guarantees nothing if other thread changes status
5800      * @return True if the semaphore was locked when the function was called
5801      */
5802     virtual bool locked() const;
5803 
5804     /**
5805      * Get the number of semaphores counting the shared ones only once
5806      * @return Count of individual semaphores
5807      */
5808     static int count();
5809 
5810     /**
5811      * Get the number of currently locked (waiting) semaphores
5812      * @return Count of locked semaphores, -1 if unknown (not tracked)
5813      */
5814     static int locks();
5815 
5816     /**
5817      * Check if a timed lock() is efficient on this platform
5818      * @return True if a lock with a maxwait parameter is efficiently implemented
5819      */
5820     static bool efficientTimedLock();
5821 
5822 private:
5823     SemaphorePrivate* privDataCopy() const;
5824     SemaphorePrivate* m_private;
5825 };
5826 
5827 /**
5828  * A lock is a stack allocated (automatic) object that locks a lockable object
5829  *  on creation and unlocks it on destruction - typically when exiting a block
5830  * @short Ephemeral mutex or semaphore locking object
5831  */
5832 class YATE_API Lock
5833 {
5834     YNOCOPY(Lock); // no automatic copies please
5835 public:
5836     /**
5837      * Create the lock, try to lock the object
5838      * @param lck Reference to the object to lock
5839      * @param maxwait Time in microseconds to wait, -1 wait forever
5840      */
5841     inline Lock(Lockable& lck, long maxwait = -1)
5842 	{ m_lock = lck.lock(maxwait) ? &lck : 0; }
5843 
5844     /**
5845      * Create the lock, try to lock the object
5846      * @param lck Pointer to the object to lock
5847      * @param maxwait Time in microseconds to wait, -1 wait forever
5848      */
5849     inline Lock(Lockable* lck, long maxwait = -1)
5850 	{ m_lock = (lck && lck->lock(maxwait)) ? lck : 0; }
5851 
5852     /**
5853      * Destroy the lock, unlock the mutex if it was locked
5854      */
~Lock()5855     inline ~Lock()
5856 	{ if (m_lock) m_lock->unlock(); }
5857 
5858     /**
5859      * Return a pointer to the lockable object this lock holds
5860      * @return A pointer to a Lockable or NULL if locking failed
5861      */
locked()5862     inline Lockable* locked() const
5863 	{ return m_lock; }
5864 
5865     /**
5866      * Unlock the object if it was locked and drop the reference to it
5867      */
drop()5868     inline void drop()
5869 	{ if (m_lock) m_lock->unlock(); m_lock = 0; }
5870 
5871     /**
5872      * Attempt to acquire a new lock on another object
5873      * @param lck Pointer to the object to lock
5874      * @param maxwait Time in microseconds to wait, -1 wait forever
5875      * @return True if locking succeeded or same object was locked
5876      */
5877     inline bool acquire(Lockable* lck, long maxwait = -1)
5878 	{ return (lck && (lck == m_lock)) ||
5879 	    (drop(),(lck && (m_lock = lck->lock(maxwait) ? lck : 0))); }
5880 
5881     /**
5882      * Attempt to acquire a new lock on another object
5883      * @param lck Reference to the object to lock
5884      * @param maxwait Time in microseconds to wait, -1 wait forever
5885      * @return True if locking succeeded or same object was locked
5886      */
5887     inline bool acquire(Lockable& lck, long maxwait = -1)
5888 	{ return acquire(&lck,maxwait); }
5889 
5890 private:
5891     Lockable* m_lock;
5892 
5893     /** Make sure no Lock is ever created on heap */
5894     inline void* operator new(size_t);
5895 
5896     /** Never allocate an array of this class */
5897     inline void* operator new[](size_t);
5898 };
5899 
5900 /**
5901  * A dual lock is a stack allocated (automatic) object that locks a pair
5902  *  of mutexes on creation and unlocks them on destruction. The mutexes are
5903  *  always locked in the same order to prevent trivial deadlocks
5904  * @short Ephemeral double mutex locking object
5905  */
5906 class YATE_API Lock2
5907 {
5908     YNOCOPY(Lock2); // no automatic copies please
5909 public:
5910     /**
5911      * Create the dual lock, try to lock each mutex
5912      * @param mx1 Pointer to the first mutex to lock
5913      * @param mx2 Pointer to the second mutex to lock
5914      * @param maxwait Time in microseconds to wait for each mutex, -1 wait forever
5915      */
5916     inline Lock2(Mutex* mx1, Mutex* mx2, long maxwait = -1)
5917 	: m_mx1(0), m_mx2(0)
5918 	{ lock(mx1,mx2,maxwait); }
5919 
5920     /**
5921      * Create the dual lock, try to lock each mutex
5922      * @param mx1 Reference to the first mutex to lock
5923      * @param mx2 Reference to the second mutex to lock
5924      * @param maxwait Time in microseconds to wait for each mutex, -1 wait forever
5925      */
5926     inline Lock2(Mutex& mx1, Mutex& mx2, long maxwait = -1)
5927 	: m_mx1(0), m_mx2(0)
5928 	{ lock(&mx1,&mx2,maxwait); }
5929 
5930     /**
5931      * Destroy the lock, unlock the mutex if it was locked
5932      */
~Lock2()5933     inline ~Lock2()
5934 	{ drop(); }
5935 
5936     /**
5937      * Check if the locking succeeded
5938      * @return True if all mutexes were locked
5939      */
locked()5940     inline bool locked() const
5941 	{ return m_mx1 != 0; }
5942 
5943     /**
5944      * Lock in a new pair of mutexes. Any existing locks are dropped
5945      * @param mx1 Pointer to the first mutex to lock
5946      * @param mx2 Pointer to the second mutex to lock
5947      * @param maxwait Time in microseconds to wait for each mutex, -1 wait forever
5948      * @return True on success - non-NULL mutexes locked
5949      */
5950     bool lock(Mutex* mx1, Mutex* mx2, long maxwait = -1);
5951 
5952     /**
5953      * Lock in a new pair of mutexes
5954      * @param mx1 Reference to the first mutex to lock
5955      * @param mx2 Reference to the second mutex to lock
5956      * @param maxwait Time in microseconds to wait for each mutex, -1 wait forever
5957      * @return True on success - both locked
5958      */
5959     inline bool lock(Mutex& mx1, Mutex& mx2, long maxwait = -1)
5960 	{ return lock(&mx1,&mx2,maxwait); }
5961 
5962     /**
5963      * Unlock both mutexes if they were locked and drop the references
5964      */
5965     void drop();
5966 
5967 private:
5968     Mutex* m_mx1;
5969     Mutex* m_mx2;
5970 
5971     /** Make sure no Lock2 is ever created on heap */
5972     inline void* operator new(size_t);
5973 
5974     /** Never allocate an array of this class */
5975     inline void* operator new[](size_t);
5976 };
5977 
5978 /**
5979  * This class holds the action to execute a certain task, usually in a
5980  *  different execution thread.
5981  * @short Encapsulates a runnable task
5982  */
5983 class YATE_API Runnable
5984 {
5985 public:
5986     /**
5987      * This method is called in another thread to do the actual job.
5988      * When it returns the job or thread terminates.
5989      */
5990     virtual void run() = 0;
5991 
5992     /**
5993      * Do-nothing destructor, placed here just to shut up GCC 4+
5994      */
5995     virtual ~Runnable();
5996 };
5997 
5998 /**
5999  * A thread is a separate execution context that exists in the same address
6000  *  space. Threads make better use of multiple processor machines and allow
6001  *  blocking one execution thread while allowing other to run.
6002  * @short Thread support class
6003  */
6004 class YATE_API Thread : public Runnable
6005 {
6006     friend class ThreadPrivate;
6007     friend class MutexPrivate;
6008     friend class SemaphorePrivate;
6009     YNOCOPY(Thread); // no automatic copies please
6010 public:
6011     /**
6012      * Running priorities, their mapping is operating system dependent
6013      */
6014     enum Priority {
6015 	Lowest,
6016 	Low,
6017 	Normal,
6018 	High,
6019 	Highest
6020     };
6021 
6022     /**
6023      * This method is called when the current thread terminates.
6024      */
6025     virtual void cleanup();
6026 
6027     /**
6028      * Actually starts running the new thread which lingers after creation
6029      * @return False if an error occured, true if started ok
6030      */
6031     bool startup();
6032 
6033     /**
6034      * Check if the thread creation failed
6035      * @return True if an error occured, false if created ok
6036      */
6037     bool error() const;
6038 
6039     /**
6040      * Check if the thread is running or not
6041      * @return True if running, false if it has terminated or no startup called
6042      */
6043     bool running() const;
6044 
6045     /**
6046      * Get the affinity mask of this thread
6047      * @param outCpuMask Bit mask specifying CPUs  on which the thread is running on. Bit 0 of octet 0 in DataBlock is CPU 0,
6048      *   bit 1 in octet 0 is CPU 1,..., bit 0 in octet 2 is CPU 8, etc.
6049      * @return 0 on success, error otherwise
6050      */
6051     int getAffinity(DataBlock& outCpuMask);
6052 
6053     /**
6054      * Set the affinity of this thread by using a string that specifies the
6055      * allowed CPUs by listing them separated with commas or as ranges.
6056      * Mixing ranges with list is allowed (e.g. 0,2,5-6,10)
6057      * @param cpus String specifying CPUs on which this thread should run.
6058      * @return 0 on success, error otherwise
6059      */
6060     int setAffinity(const String& cpus);
6061 
6062     /**
6063      * Set the affinity of this thread
6064      * @param mask Bit mask specifying allowed CPUs kept in a DataBlock. Bit 0 of octet 0 in DataBlock is CPU 0,
6065      *   bit 1 in octet 0 is CPU 1,..., bit 0 in octet 1 is CPU 8, etc.
6066      * @return 0 on success, error otherwise
6067      */
6068     int setAffinity(const DataBlock& mask);
6069 
6070     /**
6071      * Count how many Yate mutexes are kept locked by this thread
6072      * @return Number of Mutex locks held by this thread
6073      */
locks()6074     inline int locks() const
6075 	{ return m_locks; }
6076 
6077     /**
6078      * Check if the thread is currently helding or attempting to lock a mutex
6079      * @return True if the current thread is in an unsafe to cancel state
6080      */
locked()6081     inline bool locked() const
6082 	{ return m_locking || m_locks; }
6083 
6084     /**
6085      * Get the name of this thread
6086      * @return The pointer that was passed in the constructor
6087      */
6088     const char* name() const;
6089 
6090     /**
6091      * Get the name of the currently running thread
6092      * @return The pointer that was passed in the thread's constructor
6093      */
6094     static const char* currentName();
6095 
6096     /**
6097      * Get the affinity mask of current thread
6098      * @param outCpuMask Bit mask specifying CPUs  on which the current thread is running on. Bit 0 of octet 0 in DataBlock is CPU 0,
6099      *   bit 1 in octet 0 is CPU 1,..., bit 0 in octet 1 is CPU 8, etc.
6100      * @return 0 on success, error otherwise
6101      */
6102     static int getCurrentAffinity(DataBlock& outCpuMask);
6103 
6104     /**
6105      * Get the affinity mask of current thread
6106      * @param outCpus String into which to put the affinity
6107      * @param hex True to put it as octet string, false as comma-separated list of CPUs
6108      * @return 0 on success, error otherwise
6109      */
6110     static int getCurrentAffinity(String& outCpus, bool hex = false);
6111 
6112     /**
6113      * Set the affinity of the current thread by using a string that specifies the
6114      * allowed CPUs by listing them separated with commas or as ranges.
6115      * Mixing ranges with list is allowed (e.g. 0,2,5-6,10)
6116      * @param cpus String specifying CPUs on which this thread should run.
6117      * @return 0 on success, error otherwise
6118      */
6119     static int setCurrentAffinity(const String& cpus);
6120 
6121     /**
6122      * Set the affinity of the current thread
6123      * @param mask Bit mask specifying allowed CPUs kept in a DataBlock. Bit 0 of octet 0 in DataBlock is CPU 0,
6124      *   bit 1 in octet 0 is CPU 1,..., bit 0 in octet 1 is CPU 8, etc.
6125      * @return 0 on success, error otherwise
6126      */
6127     static int setCurrentAffinity(const DataBlock& mask);
6128 
6129     /**
6130      * Parse a CPU list into a bitmask held in a DataBlock.
6131      * String is formated as a list of integers or integer ranges separated by commas..
6132      * Mixing ranges with list is allowed (e.g. 0,2,5-6,10)
6133      * @param cpus String specifying CPUs
6134      * @param mask Output bitmask resulted from parsing.
6135      * @return True if parsing succeeded, false otherwise
6136      */
6137     static bool parseCPUMask(const String& cpus, DataBlock& mask);
6138 
6139     /**
6140      * Stringify the CPU mask
6141      * @param mask Mask to stringify
6142      * @param str Output string
6143      * @param hexa Output as hexadecimal string if set, otherwise build a list of comma separated CPUs
6144      */
6145     static void printCPUMask(const DataBlock& mask, String& str, bool hexa = true);
6146 
6147     /**
6148      * Give up the currently running timeslice. Note that on some platforms
6149      *  it also sleeps for the operating system's scheduler resolution
6150      * @param exitCheck Terminate the thread if asked so
6151      */
6152     static void yield(bool exitCheck = false);
6153 
6154     /**
6155      * Sleep for a system dependent period adequate for an idle thread.
6156      * On most operating systems this is a 5 msec sleep.
6157      * @param exitCheck Terminate the thread if asked so
6158      */
6159     static void idle(bool exitCheck = false);
6160 
6161     /**
6162      * Sleep for a number of seconds
6163      * @param sec Number of seconds to sleep
6164      * @param exitCheck Terminate the thread if asked so
6165      */
6166     static void sleep(unsigned int sec, bool exitCheck = false);
6167 
6168     /**
6169      * Sleep for a number of milliseconds
6170      * @param msec Number of milliseconds to sleep
6171      * @param exitCheck Terminate the thread if asked so
6172      */
6173     static void msleep(unsigned long msec, bool exitCheck = false);
6174 
6175     /**
6176      * Sleep for a number of microseconds
6177      * @param usec Number of microseconds to sleep, may be rounded to
6178      *  milliseconds on some platforms
6179      * @param exitCheck Terminate the thread if asked so
6180      */
6181     static void usleep(unsigned long usec, bool exitCheck = false);
6182 
6183     /**
6184      * Get the platform dependent idle sleep interval in microseconds
6185      * @return Number of microseconds each call to idle() will sleep
6186      */
6187     static unsigned long idleUsec();
6188 
6189     /**
6190      * Get the platform dependent idle sleep interval in milliseconds
6191      * @return Number of milliseconds each call to idle() will sleep
6192      */
6193     static unsigned long idleMsec();
6194 
6195     /**
6196      * Set the idle sleep interval or reset to platform default
6197      * @param msec Sleep interval in milliseconds, platform default if zero
6198      */
6199     static void idleMsec(unsigned long msec);
6200 
6201     /**
6202      * Get a pointer to the currently running thread
6203      * @return A pointer to the current thread or NULL for the main thread
6204      *  or threads created by other libraries
6205      */
6206     static Thread* current();
6207 
6208     /**
6209      * Get the number of Yate created threads
6210      * @return Count of current Thread objects
6211      */
6212     static int count();
6213 
6214     /**
6215      * Check if the current thread was asked to terminate.
6216      * @param exitNow If thread is marked as cancelled then terminate immediately
6217      * @return False if thread should continue running, true if it should stop
6218      */
6219     static bool check(bool exitNow = true);
6220 
6221     /**
6222      * Terminates the current thread.
6223      */
6224     static void exit();
6225 
6226     /**
6227      * Terminates the specified thread.
6228      * @param hard Kill the thread the hard way rather than just setting an exit check marker
6229      */
6230     void cancel(bool hard = false);
6231 
6232     /**
6233      * Check if this thread is the currently running thread
6234      * @return True if this is the current thread
6235      */
isCurrent()6236     inline bool isCurrent() const
6237 	{ return current() == this; }
6238 
6239     /**
6240      * Get the object counter of this thread
6241      * @return Pointer to thread's counter for new objects
6242      */
6243     NamedCounter* getObjCounter() const;
6244 
6245     /**
6246      * Set the object counter of this thread
6247      * @param counter New counter object or NULL
6248      * @return Pointer to old counter object
6249      */
6250     NamedCounter* setObjCounter(NamedCounter* counter);
6251 
6252     /**
6253      * Get the object counter of the current thread
6254      * @param always Return the object even if counting is disabled
6255      * @return Pointer to current counter for new objects
6256      */
6257     static NamedCounter* getCurrentObjCounter(bool always = false);
6258 
6259     /**
6260      * Set the object counter of the current thread
6261      * @param counter New counter object or NULL
6262      * @return Pointer to old counter object
6263      */
6264     static NamedCounter* setCurrentObjCounter(NamedCounter* counter);
6265 
6266     /**
6267      * Convert a priority name to a thread priority level
6268      * @param name Name of the requested level
6269      * @param defvalue Priority to return in case of an invalid name
6270      * @return A thread priority level
6271      */
6272     static Priority priority(const char* name, Priority defvalue = Normal);
6273 
6274     /**
6275      * Convert a priority level to a textual name
6276      * @param prio Priority level to convert
6277      * @return Name of the level or NULL if an invalid argument was provided
6278      */
6279     static const char* priority(Priority prio);
6280 
6281     /**
6282      * Kills all other running threads. Ouch!
6283      * Must be called from the main thread or it does nothing.
6284      */
6285     static void killall();
6286 
6287     /**
6288      * On some platforms this method kills all other running threads.
6289      * Must be called after fork() but before any exec*() call.
6290      */
6291     static void preExec();
6292 
6293     /**
6294      * Get the last thread error
6295      * @return The value returned by GetLastError() (on Windows) or
6296      *  the value of C library 'errno' variable otherwise
6297      */
6298     static int lastError();
6299 
6300     /**
6301      * Get the last thread error's string from system.
6302      * @param buffer The destination string
6303      * @return True if an error string was retrieved. If false is returned, the buffer
6304      *  is filled with a generic string indicating an unknown error and its code
6305      */
errorString(String & buffer)6306     static inline bool errorString(String& buffer)
6307 	{ return errorString(buffer,lastError()); }
6308 
6309     /**
6310      * Get an error string from system.
6311      * On Windows the code parameter must be a code returned by GetLastError().
6312      * Otherwise, the error code should be a valid value for the C library 'errno'
6313      *  variable
6314      * @param buffer The destination string
6315      * @param code The error code
6316      * @return True if an error string was retrieved. If false is returned, the buffer
6317      *  is filled with a generic string indicating an unknown error and its code
6318      */
6319     static bool errorString(String& buffer, int code);
6320 
6321 protected:
6322     /**
6323      * Creates and starts a new thread
6324      * @param name Static name of the thread (for debugging purpose only)
6325      * @param prio Thread priority
6326      */
6327     Thread(const char *name = 0, Priority prio = Normal);
6328 
6329     /**
6330      * Creates and starts a new thread
6331      * @param name Static name of the thread (for debugging purpose only)
6332      * @param prio Thread priority level name
6333      */
6334     Thread(const char *name, const char* prio);
6335 
6336     /**
6337      * The destructor is called when the thread terminates
6338      */
6339     virtual ~Thread();
6340 
6341 private:
6342     ThreadPrivate* m_private;
6343     int m_locks;
6344     bool m_locking;
6345 };
6346 
6347 /**
6348  * This class changes the current thread's object counter for its lifetime
6349  * @short Ephemeral object counter changer
6350  */
6351 class YATE_API TempObjectCounter
6352 {
6353     YNOCOPY(TempObjectCounter); // no automatic copies please
6354 public:
6355     /**
6356      * Constructor, changes object counter if counting is enabled
6357      * @param counter Object counter to apply on the current thread
6358      * @param enable True to enable change, false to take no action
6359      */
6360     inline TempObjectCounter(NamedCounter* counter, bool enable = GenObject::getObjCounting())
6361 	: m_saved(0), m_enabled(enable)
6362 	{ if (m_enabled) m_saved = Thread::setCurrentObjCounter(counter); }
6363 
6364     /**
6365      * Constructor, changes object counter if counting is enabled
6366      * @param obj Object to copy the counter from
6367      * @param enable True to enable change, false to take no action
6368      */
6369     inline TempObjectCounter(const GenObject* obj, bool enable = GenObject::getObjCounting())
6370 	: m_saved(0), m_enabled(enable && obj)
6371 	{ if (m_enabled) m_saved = Thread::setCurrentObjCounter(obj->getObjCounter()); }
6372 
6373     /**
6374      * Constructor, changes object counter if counting is enabled
6375      * @param obj Object to copy the counter from
6376      * @param enable True to enable change, false to take no action
6377      */
6378     inline TempObjectCounter(const GenObject& obj, bool enable = GenObject::getObjCounting())
6379 	: m_saved(0), m_enabled(enable)
6380 	{ if (m_enabled) m_saved = Thread::setCurrentObjCounter(obj.getObjCounter()); }
6381 
6382     /**
6383      * Destructor, restores saved object counter
6384      */
~TempObjectCounter()6385     inline ~TempObjectCounter()
6386 	{ if (m_enabled) Thread::setCurrentObjCounter(m_saved); }
6387 
6388 private:
6389     NamedCounter* m_saved;
6390     bool m_enabled;
6391 };
6392 
6393 class Socket;
6394 
6395 /**
6396  * Wrapper class to keep a socket address
6397  * @short A socket address holder
6398  */
6399 class YATE_API SocketAddr : public GenObject
6400 {
6401     YCLASS(SocketAddr,GenObject)
6402 public:
6403     /**
6404      * Known address families
6405      */
6406     enum Family {
6407 	Unknown = AF_UNSPEC,
6408 	IPv4 = AF_INET,
6409 	AfMax = AF_MAX,
6410 	AfUnsupported = AfMax,
6411 #ifdef AF_INET6
6412 	IPv6 = AF_INET6,
6413 #else
6414 	IPv6 = AfUnsupported + 1,
6415 #endif
6416 #ifdef HAS_AF_UNIX
6417 	Unix = AF_UNIX,
6418 #else
6419 	Unix = AfUnsupported + 2,
6420 #endif
6421     };
6422 
6423     /**
6424      * Default constructor of an empty address
6425      */
SocketAddr()6426     inline SocketAddr()
6427 	: m_address(0), m_length(0)
6428 	{ }
6429 
6430     /**
6431      * Copy constructor
6432      * @param value Address to copy
6433      */
SocketAddr(const SocketAddr & value)6434     inline SocketAddr(const SocketAddr& value)
6435 	: GenObject(),
6436 	  m_address(0), m_length(0)
6437 	{ assign(value.address(),value.length()); }
6438 
6439     /**
6440      * Constructor of a null address
6441      * @param family Family of the address to create
6442      * @param raw Raw address data
6443      */
6444     explicit SocketAddr(int family, const void* raw = 0);
6445 
6446     /**
6447      * Constructor that stores a copy of an address
6448      * @param addr Pointer to the address to store
6449      * @param len Length of the stored address, zero to use default
6450      */
6451     SocketAddr(const struct sockaddr* addr, socklen_t len = 0);
6452 
6453     /**
6454      * Destructor that frees and zeroes out everything
6455      */
6456     virtual ~SocketAddr();
6457 
6458     /**
6459      * Assignment operator
6460      * @param value Address to copy
6461      */
6462     inline SocketAddr& operator=(const SocketAddr& value)
6463 	{ assign(value.address(),value.length()); return *this; }
6464 
6465     /**
6466      * Equality comparation operator
6467      * @param other Address to compare to
6468      * @return True if the addresses are equal
6469      */
6470     bool operator==(const SocketAddr& other) const;
6471 
6472     /**
6473      * Inequality comparation operator
6474      * @param other Address to compare to
6475      * @return True if the addresses are different
6476      */
6477     inline bool operator!=(const SocketAddr& other) const
6478 	{ return !operator==(other); }
6479 
6480     /**
6481      * Clears up the address, frees the memory
6482      */
6483     void clear();
6484 
6485     /**
6486      * Assigns an empty address of a specific type
6487      * @param family Family of the address to create
6488      * @return True if the address family is supported
6489      */
6490     bool assign(int family);
6491 
6492     /**
6493      * Assigns a new address
6494      * @param addr Pointer to the address to store
6495      * @param len Length of the stored address, zero to use default
6496      */
6497     void assign(const struct sockaddr* addr, socklen_t len = 0);
6498 
6499     /**
6500      * Assigns a new address
6501      * @param addr Packed binary address to store
6502      * @return True if the address family is supported
6503      */
6504     bool assign(const DataBlock& addr);
6505 
6506     /**
6507      * Attempt to guess a local address that will be used to reach a remote one
6508      * @param remote Remote address to reach
6509      * @return True if guessed an address, false if failed
6510      */
6511     bool local(const SocketAddr& remote);
6512 
6513     /**
6514      * Check if a non-null address is held
6515      * @return True if a valid address is held, false if null
6516      */
valid()6517     inline bool valid() const
6518 	{ return m_length && m_address; }
6519 
6520     /**
6521      * Check if a null address is held
6522      * @return True if a null address is held
6523      */
null()6524     inline bool null() const
6525 	{ return !(m_length && m_address); }
6526 
6527     /**
6528      * Get the family of the stored address
6529      * @return Address family of the stored address or zero (AF_UNSPEC)
6530      */
family()6531     inline int family() const
6532 	{ return m_address ? m_address->sa_family : 0; }
6533 
6534     /**
6535      * Retrieve address family name
6536      * @return Address family name
6537      */
familyName()6538     inline const char* familyName() const
6539 	{ return lookupFamily(family()); }
6540 
6541     /**
6542      * Retrieve the sin6_scope_id value of an IPv6 address
6543      * @return The requested value (it may be 0), 0 if not available
6544      */
scopeId()6545     inline unsigned int scopeId() const
6546 	{ return scopeId(address()); }
6547 
6548     /**
6549      * Set the sin6_scope_id value of an IPv6 address
6550      * @param val Value to set
6551      * @return True on success, false if not available
6552      */
scopeId(unsigned int val)6553     inline bool scopeId(unsigned int val)
6554 	{ return scopeId(address(),val); }
6555 
6556     /**
6557      * Get the host of this address
6558      * @return Host name as String
6559      */
host()6560     inline const String& host() const
6561 	{ return m_host; }
6562 
6563     /**
6564      * Get the host and port of this address
6565      * @return Address String (host:port)
6566      */
addr()6567     inline const String& addr() const {
6568 	    if (!m_addr)
6569 		updateAddr();
6570 	    return m_addr;
6571 	}
6572 
6573     /**
6574      * Set the hostname of this address.
6575      * Guess address family if not initialized
6576      * @param name Host to set
6577      * @return True if new host set, false if name could not be parsed
6578      */
6579     virtual bool host(const String& name);
6580 
6581     /**
6582      * Get the port of the stored address (if supported)
6583      * @return Port number of the socket address or zero
6584      */
6585     int port() const;
6586 
6587     /**
6588      * Set the port of the stored address (if supported)
6589      * @param newport Port number to set in the socket address
6590      * @return True if new port set, false if not supported
6591      */
6592     bool port(int newport);
6593 
6594     /**
6595      * Get the contained socket address
6596      * @return A pointer to the socket address
6597      */
address()6598     inline struct sockaddr* address() const
6599 	{ return m_address; }
6600 
6601     /**
6602      * Get the length of the address
6603      * @return Length of the stored address
6604      */
length()6605     inline socklen_t length() const
6606 	{ return m_length; }
6607 
6608     /**
6609      * Check if this address is empty or null
6610      * @return True if the address is empty or '0.0.0.0' (IPv4) or '::' IPv6
6611      */
isNullAddr()6612     inline bool isNullAddr() const
6613 	{ return isNullAddr(m_host,family()); }
6614 
6615     /**
6616      * Copy the host address to a buffer
6617      * @param addr Buffer to put the packed address into
6618      * @return Address family, Unknown on failure
6619      */
6620     int copyAddr(DataBlock& addr) const;
6621 
6622     /**
6623      * Check if an address family is supported by the library
6624      * @param family Family of the address to check
6625      * @return True if the address family is supported
6626      */
6627     static bool supports(int family);
6628 
6629     /**
6630      * Retrieve the family of an address
6631      * @param addr The address to check
6632      * @return Address family
6633      */
6634     static int family(const String& addr);
6635 
6636     /**
6637      * Convert the host address to a String
6638      * @param buf Destination buffer
6639      * @param addr Socket address
6640      * @return True on success, false if address family is not supported
6641      */
6642     static bool stringify(String& buf, struct sockaddr* addr);
6643 
6644     /**
6645      * Put a host address to a buffer
6646      * @param buf Destination buffer. It must be large enough to keep the address
6647      *  (4 bytes for IPv4, 16 bytes for IPv6)
6648      * @param host The host address
6649      * @param family Address family, set it to Unknown to detect
6650      * @return Address family, Unknown on failure
6651      */
6652     static inline int unStringify(uint8_t* buf, const String& host,
6653 	int family = Unknown) {
6654 	    SocketAddr sa(family);
6655 	    return sa.host(host) ? copyAddr(buf,sa.address()) : Unknown;
6656 	}
6657 
6658     /**
6659      * Copy a host address to a buffer
6660      * @param buf Destination buffer. It must be large enough to keep the address
6661      *  (4 bytes for IPv4, 16 bytes for IPv6)
6662      * @param addr The host address
6663      * @return Address family, Unknown on failure
6664      */
6665     static int copyAddr(uint8_t* buf, struct sockaddr* addr);
6666 
6667     /**
6668      * Retrieve the scope id value of an IPv6 address
6669      * @param addr The address
6670      * @return The requested value (it may be 0), 0 if not available
6671      */
scopeId(struct sockaddr * addr)6672     static inline unsigned int scopeId(struct sockaddr* addr) {
6673 #ifdef AF_INET6
6674 	    if (addr && addr->sa_family == AF_INET6)
6675 		return ((struct sockaddr_in6*)addr)->sin6_scope_id;
6676 #endif
6677 	    return 0;
6678 	}
6679 
6680     /**
6681      * Set the scope id value of an IPv6 address
6682      * @param addr Address to set
6683      * @param val Value to set
6684      * @return True on success, false if not available
6685      */
scopeId(struct sockaddr * addr,unsigned int val)6686     static inline bool scopeId(struct sockaddr* addr, unsigned int val) {
6687 #ifdef AF_INET6
6688 	    if (addr && addr->sa_family == AF_INET6) {
6689 		((struct sockaddr_in6*)addr)->sin6_scope_id = val;
6690 		return true;
6691 	    }
6692 #endif
6693 	    return false;
6694 	}
6695 
6696     /**
6697      * Append an address to a buffer
6698      * @param buf Destination buffer
6699      * @param addr Address to append
6700      * @param family Address family, set it to Unknown to detect
6701      * @return Buffer address
6702      */
6703     static String& appendAddr(String& buf, const String& addr, int family = Unknown);
6704 
6705     /**
6706      * Append an address to a buffer in the form addr:port
6707      * @param buf Destination buffer
6708      * @param addr Address to append
6709      * @param port Port to append
6710      * @param family Address family, set it to Unknown to detect
6711      * @return Buffer address
6712      */
6713     static inline String& appendTo(String& buf, const String& addr, int port,
6714 	int family = Unknown) {
6715 	    appendAddr(buf,addr,family) << ":" << port;
6716 	    return buf;
6717 	}
6718 
6719     /**
6720      * Append an address to a buffer in the form addr:port
6721      * @param addr Address to append
6722      * @param port Port to append
6723      * @param family Address family, set it to Unknown to detect
6724      * @return A String with concatenated address and port
6725      */
6726     static inline String appendTo(const String& addr, int port, int family = Unknown) {
6727 	    String buf;
6728 	    appendTo(buf,addr,port,family);
6729 	    return buf;
6730 	}
6731 
6732     /**
6733      * Check if an address is empty or null
6734      * @param addr Address to check
6735      * @param family Address family, set it to Unknown to detect
6736      * @return True if the address is empty or '0.0.0.0' (IPv4) or '::' IPv6
6737      */
6738     static bool isNullAddr(const String& addr, int family = Unknown);
6739 
6740     /**
6741      * Split an interface from address
6742      * An interface may be present in addr after a percent char (e.g. fe80::23%eth0)
6743      * It is safe call this method with the same destination and source string
6744      * @param buf Source buffer
6745      * @param addr Destination buffer for address
6746      * @param iface Optional pointer to be filled with interface name
6747      */
6748     static void splitIface(const String& buf, String& addr, String* iface = 0);
6749 
6750     /**
6751      * Split an address into ip/port.
6752      * Handled formats: addr, addr:port, [addr], [addr]:port
6753      * It is safe call this method with the same destination and source string
6754      * @param buf Source buffer
6755      * @param addr Destination buffer for address
6756      * @param port Destination port
6757      * @param portPresent Set it to true if the port is always present after the last ':'.
6758      *  This will handle IPv6 addresses without square brackets and port present
6759      *  (e.g. fe80::23:5060 will split into addr=fe80::23 and port=5060)
6760      */
6761     static void split(const String& buf, String& addr, int& port, bool portPresent = false);
6762 
6763     /**
6764      * Retrieve address family name
6765      * @param family Address family to retrieve
6766      * @return Address family name
6767      */
lookupFamily(int family)6768     static inline const char* lookupFamily(int family)
6769 	{ return lookup(family,s_familyName); }
6770 
6771     /**
6772      * Retrieve IPv4 null address
6773      * @return IPv4 null address (0.0.0.0)
6774      */
6775     static const String& ipv4NullAddr();
6776 
6777     /**
6778      * Retrieve IPv6 null address
6779      * @return IPv6 null address (::)
6780      */
6781     static const String& ipv6NullAddr();
6782 
6783     /**
6784      * Retrieve the family name dictionary
6785      * @return Pointer to family name dictionary
6786      */
6787     static const TokenDict* dictFamilyName();
6788 
6789 protected:
6790     /**
6791      * Convert the host address to a String stored in m_host
6792      */
6793     virtual void stringify();
6794 
6795     /**
6796      * Store host:port in m_addr
6797      */
6798     virtual void updateAddr() const;
6799 
6800     struct sockaddr* m_address;
6801     socklen_t m_length;
6802     String m_host;
6803     mutable String m_addr;
6804 
6805 private:
6806     static const TokenDict s_familyName[];
6807 };
6808 
6809 /**
6810  * Abstract interface for an object that filters socket received data packets
6811  * @short A filter for received socket data
6812  */
6813 class YATE_API SocketFilter : public GenObject
6814 {
6815     friend class Socket;
6816     YNOCOPY(SocketFilter); // no automatic copies please
6817 public:
6818     /**
6819      * Constructor
6820      */
6821     SocketFilter();
6822 
6823     /**
6824      * Destructor, unregisters from socket
6825      */
6826     virtual ~SocketFilter();
6827 
6828     /**
6829      * Get a pointer to a derived class given that class name
6830      * @param name Name of the class we are asking for
6831      * @return Pointer to the requested class or NULL if this object doesn't implement it
6832      */
6833     virtual void* getObject(const String& name) const;
6834 
6835     /**
6836      * Run whatever actions required on idle thread runs
6837      * @param when Time when the idle run started
6838      */
6839     virtual void timerTick(const Time& when);
6840 
6841     /**
6842      * Notify this filter about a received block of data
6843      * @param buffer Buffer for received data
6844      * @param length Length of the data in buffer
6845      * @param flags Operating system specific bit flags of the operation
6846      * @param addr Address of the incoming data, may be NULL
6847      * @param adrlen Length of the valid data in address structure
6848      * @return True if this filter claimed the data
6849      */
6850     virtual bool received(void* buffer, int length, int flags, const struct sockaddr* addr, socklen_t adrlen) = 0;
6851 
6852     /**
6853      * Get the socket to which the filter is currently attached
6854      * @return Pointer to the socket of this filter
6855      */
socket()6856     inline Socket* socket() const
6857 	{ return m_socket; }
6858 
6859     /**
6860      * Check if the socket of this filter is valid
6861      * @return True if the filter has a valid socket
6862      */
6863     bool valid() const;
6864 
6865 private:
6866     Socket* m_socket;
6867 };
6868 
6869 /**
6870  * Base class for encapsulating system dependent stream capable objects
6871  * @short An abstract stream class capable of reading and writing
6872  */
6873 class YATE_API Stream
6874 {
6875 public:
6876     /**
6877      * Enumerate seek start position
6878      */
6879     enum SeekPos {
6880 	SeekBegin,                       // Seek from start of stream
6881 	SeekEnd,                         // Seek from stream end
6882 	SeekCurrent                      // Seek from current position
6883     };
6884 
6885     /**
6886      * Destructor, terminates the stream
6887      */
6888     virtual ~Stream();
6889 
6890     /**
6891      * Get the error code of the last operation on this stream
6892      * @return Error code generated by the last operation on this stream
6893      */
error()6894     inline int error() const
6895 	{ return m_error; }
6896 
6897     /**
6898      * Closes the stream
6899      * @return True if the stream was (already) closed, false if an error occured
6900      */
6901     virtual bool terminate() = 0;
6902 
6903     /**
6904      * Check if the last error code indicates a retryable condition
6905      * @return True if error was temporary and operation should be retried
6906      */
6907     virtual bool canRetry() const;
6908 
6909     /**
6910      * Check if the last error code indicates a non blocking operation in progress
6911      * @return True if a non blocking operation is in progress
6912      */
6913     virtual bool inProgress() const;
6914 
6915     /**
6916      * Check if this stream is valid
6917      * @return True if the stream is valid, false if it's invalid or closed
6918      */
6919     virtual bool valid() const = 0;
6920 
6921     /**
6922      * Set the blocking or non-blocking operation mode of the stream
6923      * @param block True if I/O operations should block, false for non-blocking
6924      * @return True if operation was successfull, false if an error occured
6925      */
6926     virtual bool setBlocking(bool block = true);
6927 
6928     /**
6929      * Write data to a connected stream
6930      * @param buffer Buffer for data transfer
6931      * @param length Length of the buffer
6932      * @return Number of bytes transferred, negative if an error occurred
6933      */
6934     virtual int writeData(const void* buffer, int length) = 0;
6935 
6936     /**
6937      * Write a C string to a connected stream
6938      * @param str String to send over the stream
6939      * @return Number of bytes transferred, negative if an error occurred
6940      */
6941     int writeData(const char* str);
6942 
6943     /**
6944      * Write a String to a connected stream
6945      * @param str String to send over the stream
6946      * @return Number of bytes transferred, negative if an error occurred
6947      */
writeData(const String & str)6948     inline int writeData(const String& str)
6949 	{ return writeData(str.c_str(), str.length()); }
6950 
6951     /**
6952      * Write a Data block to a connected stream
6953      * @param buf DataBlock to send over the stream
6954      * @return Number of bytes transferred, negative if an error occurred
6955      */
writeData(const DataBlock & buf)6956     inline int writeData(const DataBlock& buf)
6957 	{ return writeData(buf.data(), buf.length()); }
6958 
6959     /**
6960      * Receive data from a connected stream
6961      * @param buffer Buffer for data transfer
6962      * @param length Length of the buffer
6963      * @return Number of bytes transferred, negative if an error occurred
6964      */
6965     virtual int readData(void* buffer, int length) = 0;
6966 
6967     /**
6968      * Find the length of the stream if it has one
6969      * @return Length of the stream or zero if length is not defined
6970      */
6971     virtual int64_t length();
6972 
6973     /**
6974      * Set the stream read/write pointer
6975      * @param pos The seek start as enumeration
6976      * @param offset The number of bytes to move the pointer from starting position
6977      * @return The new position of the stream read/write pointer. Negative on failure
6978      */
6979     virtual int64_t seek(SeekPos pos, int64_t offset = 0);
6980 
6981     /**
6982      * Set the read/write pointer from begin of stream
6983      * @param offset The position in stream to move the pointer
6984      * @return The new position of the stream read/write pointer. Negative on failure
6985      */
seek(int64_t offset)6986     inline int64_t seek(int64_t offset)
6987 	{ return seek(SeekBegin,offset); }
6988 
6989     /**
6990      * Allocate a new pair of unidirectionally pipe connected streams
6991      * @param reader Reference of a pointer receiving the newly allocated reading side of the pipe
6992      * @param writer Reference of a pointer receiving the newly allocated writing side of the pipe
6993      * @return True is the stream pipe was created successfully
6994      */
6995     static bool allocPipe(Stream*& reader, Stream*& writer);
6996 
6997     /**
6998      * Allocate a new pair of bidirectionally connected streams
6999      * @param str1 Reference of a pointer receiving the newly allocated 1st end of the pair
7000      * @param str2 Reference of a pointer receiving the newly allocated 2nd end of the pair
7001      * @return True is the stream pair was created successfully
7002      */
7003     static bool allocPair(Stream*& str1, Stream*& str2);
7004 
7005     /**
7006      * Check if operating system supports unidirectional stream pairs
7007      * @return True if unidirectional pipes can be created
7008      */
7009     static bool supportsPipes();
7010 
7011     /**
7012      * Check if operating system supports bidirectional stream pairs
7013      * @return True if bidirectional pairs can be created
7014      */
7015     static bool supportsPairs();
7016 
7017 protected:
7018     /**
7019      * Default constructor
7020      */
Stream()7021     inline Stream()
7022 	: m_error(0)
7023 	{ }
7024 
7025     /**
7026      * Clear the last error code
7027      */
clearError()7028     inline void clearError()
7029 	{ m_error = 0; }
7030 
7031     int m_error;
7032 };
7033 
7034 /**
7035  * An implementation of a Stream that reads and writes data in a DataBlock
7036  * @short A Stream that operates on DataBlocks in memory
7037  */
7038 class YATE_API MemoryStream : public Stream
7039 {
7040     YNOCOPY(MemoryStream); // no automatic copies please
7041 public:
7042     /**
7043      * Constructor of an empty stream
7044      */
MemoryStream()7045     inline MemoryStream()
7046 	: m_offset(0)
7047 	{ }
7048 
7049     /**
7050      * Constructor of aan initialized stream
7051      * @param data Initial data to be copied in the memory stream
7052      */
MemoryStream(const DataBlock & data)7053     inline MemoryStream(const DataBlock& data)
7054 	: m_data(data), m_offset(0)
7055 	{ }
7056 
7057     /**
7058      * Get read-only access to the DataBlock held
7059      * @return Const reference to the DataBlock
7060      */
data()7061     inline const DataBlock& data() const
7062 	{ return m_data; }
7063 
7064     /**
7065      * Do-nothing termination handler
7066      * @return True to signal the stream was closed
7067      */
terminate()7068     virtual bool terminate()
7069 	{ return true; }
7070     /**
7071      * Do-nothing validity check
7072      * @return True to indicate the stream is valid
7073      */
valid()7074     virtual bool valid() const
7075 	{ return true; }
7076 
7077     /**
7078      * Write new data to the DataBlock at current position, advance pointer
7079      * @param buffer Buffer of source data
7080      * @param len Length of data to be written
7081      * @return Number of bytes written, negative on error
7082      */
7083     virtual int writeData(const void* buffer, int len);
7084 
7085     /**
7086      * Get data from internal DataBlock, advance pointer
7087      * @param buffer Buffer for getting the data
7088      * @param len Length of the buffer
7089      * @return Number of bytes read, negative on error, zero on end of data
7090      */
7091     virtual int readData(void* buffer, int len);
7092 
7093     /**
7094      * Get the length of the stream
7095      * @return Length of the DataBlock in memory
7096      */
length()7097     virtual int64_t length()
7098 	{ return m_data.length(); }
7099 
7100     /**
7101      * Set the read/write pointer
7102      * @param pos The seek start as enumeration
7103      * @param offset The number of bytes to move the pointer from starting position
7104      * @return The new position of the stream read/write pointer. Negative on failure
7105      */
7106     virtual int64_t seek(SeekPos pos, int64_t offset = 0);
7107 
7108 protected:
7109     /**
7110      * The DataBlock holding the data in memory
7111      */
7112     DataBlock m_data;
7113 
7114     /**
7115      * The current position for read/write operation
7116      */
7117     int64_t m_offset;
7118 };
7119 
7120 /**
7121  * Class to encapsulate a system dependent file in a system independent abstraction
7122  * @short A stream file class
7123  */
7124 class YATE_API File : public Stream
7125 {
7126     YNOCOPY(File); // no automatic copies please
7127 public:
7128     /**
7129      * Default constructor, creates a closed file
7130      */
7131     File();
7132 
7133     /**
7134      * Constructor from an existing handle
7135      * @param handle Operating system handle to an open file
7136      */
7137     explicit File(HANDLE handle);
7138 
7139     /**
7140      * Destructor, closes the file
7141      */
7142     virtual ~File();
7143 
7144     /**
7145      * Opens a file from the filesystem pathname
7146      * @param name Name of the file according to the operating system's conventions
7147      * @param canWrite Open the file for writing
7148      * @param canRead Open the file for reading
7149      * @param create Create the file if it doesn't exist
7150      * @param append Set the write pointer at the end of an existing file
7151      * @param binary Open the file in binary mode if applicable
7152      * @param pubReadable If the file is created make it public readable
7153      * @param pubWritable If the file is created make it public writable
7154      * @return True if the file was successfully opened
7155      */
7156     virtual bool openPath(const char* name, bool canWrite = false, bool canRead = true,
7157 	bool create = false, bool append = false, bool binary = false,
7158 	bool pubReadable = false, bool pubWritable = false);
7159 
7160     /**
7161      * Closes the file handle
7162      * @return True if the file was (already) closed, false if an error occured
7163      */
7164     virtual bool terminate();
7165 
7166     /**
7167      * Attach an existing handle to the file, closes any existing first
7168      * @param handle Operating system handle to an open file
7169      */
7170     void attach(HANDLE handle);
7171 
7172     /**
7173      * Detaches the object from the file handle
7174      * @return The handle previously owned by this object
7175      */
7176     HANDLE detach();
7177 
7178     /**
7179      * Get the operating system handle to the file
7180      * @return File handle
7181      */
handle()7182     inline HANDLE handle() const
7183 	{ return m_handle; }
7184 
7185     /**
7186      * Check if the last error code indicates a retryable condition
7187      * @return True if error was temporary and operation should be retried
7188      */
7189     virtual bool canRetry() const;
7190 
7191     /**
7192      * Check if this file is valid
7193      * @return True if the file is valid, false if it's invalid or closed
7194      */
7195     virtual bool valid() const;
7196 
7197     /**
7198      * Get the operating system specific handle value for an invalid file
7199      * @return Handle value for an invalid file
7200      */
7201     static HANDLE invalidHandle();
7202 
7203     /**
7204      * Set the blocking or non-blocking operation mode of the file
7205      * @param block True if I/O operations should block, false for non-blocking
7206      * @return True if operation was successfull, false if an error occured
7207      */
7208     virtual bool setBlocking(bool block = true);
7209 
7210     /**
7211      * Find the length of the file if it has one
7212      * @return Length of the file or zero if length is not defined
7213      */
7214     virtual int64_t length();
7215 
7216     /**
7217      * Set the file read/write pointer
7218      * @param pos The seek start as enumeration
7219      * @param offset The number of bytes to move the pointer from starting position
7220      * @return The new position of the file read/write pointer. Negative on failure
7221      */
7222     virtual int64_t seek(SeekPos pos, int64_t offset = 0);
7223 
7224     /**
7225      * Write data to an open file
7226      * @param buffer Buffer for data transfer
7227      * @param length Length of the buffer
7228      * @return Number of bytes transferred, negative if an error occurred
7229      */
7230     virtual int writeData(const void* buffer, int length);
7231 
7232     /**
7233      * Read data from an open file
7234      * @param buffer Buffer for data transfer
7235      * @param length Length of the buffer
7236      * @return Number of bytes transferred, negative if an error occurred
7237      */
7238     virtual int readData(void* buffer, int length);
7239 
7240     /**
7241      * Retrieve the file's modification time (the file must be already opened)
7242      * @param secEpoch File creation time (seconds since Epoch)
7243      * @return True on success
7244      */
7245     bool getFileTime(unsigned int& secEpoch);
7246 
7247     /**
7248      * Build the MD5 hex digest of a file. The file must be opened for read access.
7249      * This method will move the file pointer
7250      * @param buffer Destination buffer
7251      * @return True on success
7252      */
7253     virtual bool md5(String& buffer);
7254 
7255     /**
7256      * Set a file's modification time.
7257      * @param name Path and name of the file
7258      * @param secEpoch File modification time (seconds since Epoch)
7259      * @param error Optional pointer to error code to be filled on failure
7260      * @return True on success
7261      */
7262     static bool setFileTime(const char* name, unsigned int secEpoch, int* error = 0);
7263 
7264     /**
7265      * Retrieve a file's modification time
7266      * @param name Path and name of the file
7267      * @param secEpoch File modification time (seconds since Epoch)
7268      * @param error Optional pointer to error code to be filled on failure
7269      * @return True on success
7270      */
7271     static bool getFileTime(const char* name, unsigned int& secEpoch, int* error = 0);
7272 
7273     /**
7274      * Check if a file exists
7275      * @param name The file to check
7276      * @param error Optional pointer to error code to be filled on failure
7277      * @return True if the file exists
7278      */
7279     static bool exists(const char* name, int* error = 0);
7280 
7281     /**
7282      * Rename (move) a file (or directory) entry from the filesystem
7283      * @param oldFile Path and name of the file to rename
7284      * @param newFile The new path and name of the file
7285      * @param error Optional pointer to error code to be filled on failure
7286      * @return True if the file was successfully renamed (moved)
7287      */
7288     static bool rename(const char* oldFile, const char* newFile, int* error = 0);
7289 
7290     /**
7291      * Deletes a file entry from the filesystem
7292      * @param name Absolute path and name of the file to delete
7293      * @param error Optional pointer to error code to be filled on failure
7294      * @return True if the file was successfully deleted
7295      */
7296     static bool remove(const char* name, int* error = 0);
7297 
7298     /**
7299      * Build the MD5 hex digest of a file.
7300      * @param name The file to build MD5 from
7301      * @param buffer Destination buffer
7302      * @param error Optional pointer to error code to be filled on failure
7303      * @return True on success
7304      */
7305     static bool md5(const char* name, String& buffer, int* error = 0);
7306 
7307     /**
7308      * Create a folder (directory). It only creates the last directory in the path
7309      * @param path The folder path
7310      * @param error Optional pointer to error code to be filled on failure
7311      * @param mode Optional file mode, ignored on some platforms
7312      * @return True on success
7313      */
7314     static bool mkDir(const char* path, int* error = 0, int mode = -1);
7315 
7316     /**
7317      * Remove an empty folder (directory)
7318      * @param path The folder path
7319      * @param error Optional pointer to error code to be filled on failure
7320      * @return True on success
7321      */
7322     static bool rmDir(const char* path, int* error = 0);
7323 
7324     /**
7325      * Enumerate a folder (directory) content.
7326      * Fill the given lists with children item names
7327      * @param path The folder path
7328      * @param dirs List to be filled with child directories.
7329      *  It can be NULL if not requested
7330      * @param files List to be filled with child files.
7331      *  It can be NULL if not requested
7332      * @param error Optional pointer to error code to be filled on failure
7333      * @return True on success
7334      */
7335     static bool listDirectory(const char* path, ObjList* dirs, ObjList* files,
7336 	int* error = 0);
7337 
7338     /**
7339      * Create a pair of unidirectionally pipe connected streams
7340      * @param reader Reference to a File that becomes the reading side of the pipe
7341      * @param writer Reference to a File that becomes the writing side of the pipe
7342      * @return True is the pipe was created successfully
7343      */
7344     static bool createPipe(File& reader, File& writer);
7345 
7346 protected:
7347 
7348     /**
7349      * Copy the last error code from the operating system
7350      */
7351     void copyError();
7352 
7353     HANDLE m_handle;
7354 };
7355 
7356 /**
7357  * This class encapsulates a system dependent socket in a system independent abstraction
7358  * @short A generic socket class
7359  */
7360 class YATE_API Socket : public Stream
7361 {
7362     YNOCOPY(Socket); // no automatic copies please
7363 public:
7364     /**
7365      * Types of service
7366      */
7367     enum TOS {
7368 	Normal         = 0,
7369 	LowDelay       = IPTOS_LOWDELAY,
7370 	MaxThroughput  = IPTOS_THROUGHPUT,
7371 	MaxReliability = IPTOS_RELIABILITY,
7372 	MinCost        = IPTOS_MINCOST,
7373     };
7374 
7375     /**
7376      * DiffServ bits
7377      */
7378     enum DSCP {
7379 	DefaultPHB     = 0x00,
7380 	// Class selectors
7381 	CS0            = 0x00,
7382 	CS1            = 0x20,
7383 	CS2            = 0x40,
7384 	CS3            = 0x60,
7385 	CS4            = 0x80,
7386 	CS5            = 0xa0,
7387 	CS6            = 0xc0,
7388 	CS7            = 0xe0,
7389 	// Assured forwarding
7390 	AF11           = 0x28,
7391 	AF12           = 0x30,
7392 	AF13           = 0x38,
7393 	AF21           = 0x48,
7394 	AF22           = 0x50,
7395 	AF23           = 0x58,
7396 	AF31           = 0x68,
7397 	AF32           = 0x70,
7398 	AF33           = 0x78,
7399 	AF41           = 0x88,
7400 	AF42           = 0x90,
7401 	AF43           = 0x98,
7402 	// Expedited forwarding
7403 	ExpeditedFwd   = 0xb8,
7404 	VoiceAdmit     = 0xb0,
7405     };
7406 
7407     /**
7408      * Default constructor, creates an invalid socket
7409      */
7410     Socket();
7411 
7412     /**
7413      * Constructor from an existing handle
7414      * @param handle Operating system handle to an existing socket
7415      */
7416     explicit Socket(SOCKET handle);
7417 
7418     /**
7419      * Constructor that also creates the socket handle
7420      * @param domain Communication domain for the socket (protocol family)
7421      * @param type Type specification of the socket
7422      * @param protocol Specific protocol for the domain, 0 to use default
7423      */
7424     Socket(int domain, int type, int protocol = 0);
7425 
7426     /**
7427      * Destructor - closes the handle if still open
7428      */
7429     virtual ~Socket();
7430 
7431     /**
7432      * Creates a new socket handle,
7433      * @param domain Communication domain for the socket (protocol family)
7434      * @param type Type specification of the socket
7435      * @param protocol Specific protocol for the domain, 0 to use default
7436      * @return True if socket was created, false if an error occured
7437      */
7438     virtual bool create(int domain, int type, int protocol = 0);
7439 
7440     /**
7441      * Closes the socket handle, terminates the connection
7442      * @return True if socket was (already) closed, false if an error occured
7443      */
7444     virtual bool terminate();
7445 
7446     /**
7447      * Attach an existing handle to the socket, closes any existing first
7448      * @param handle Operating system handle to an existing socket
7449      */
7450     void attach(SOCKET handle);
7451 
7452     /**
7453      * Detaches the object from the socket handle
7454      * @return The handle previously owned by this object
7455      */
7456     SOCKET detach();
7457 
7458     /**
7459      * Get the operating system handle to the socket
7460      * @return Socket handle
7461      */
handle()7462     inline SOCKET handle() const
7463 	{ return m_handle; }
7464 
7465     /**
7466      * Check if the last error code indicates a retryable condition
7467      * @return True if error was temporary and operation should be retried
7468      */
7469     virtual bool canRetry() const;
7470 
7471     /**
7472      * Check if the last error code indicates a non blocking operation in progress
7473      * @return True if a non blocking operation is in progress
7474      */
7475     virtual bool inProgress() const;
7476 
7477     /**
7478      * Check if this socket is valid
7479      * @return True if the handle is valid, false if it's invalid
7480      */
7481     virtual bool valid() const;
7482 
7483     /**
7484      * Get the operating system specific handle value for an invalid socket
7485      * @return Handle value for an invalid socket
7486      */
7487     static SOCKET invalidHandle();
7488 
7489     /**
7490      * Get the operating system specific return value of a failed operation
7491      * @return Return value of a failed socket operation
7492      */
7493     static int socketError();
7494 
7495     /**
7496      * Retrieve the keyword lookup table for TOS / DSCP values
7497      * @return Pointer to keyword dictionary for TOS and DSCP
7498      */
7499     static const TokenDict* tosValues();
7500 
7501     /**
7502      * Set socket options
7503      * @param level Level of the option to set
7504      * @param name Socket option for which the value is to be set
7505      * @param value Pointer to a buffer holding the value for the requested option
7506      * @param length Size of the supplied buffer
7507      * @return True if operation was successfull, false if an error occured
7508      */
7509     virtual bool setOption(int level, int name, const void* value = 0, socklen_t length = 0);
7510 
7511     /**
7512      * Set or reset socket IPv6 only option.
7513      * This option will tell to an IPv6 socket to accept only IPv6 packets.
7514      * IPv4 packets will be accepted if disabled.
7515      * This method will fail for non PF_INET6 sockets
7516      * @param on True to set, false to reset it
7517      * @return True if operation was successfull, false if an error occured
7518      */
setIpv6OnlyOption(bool on)7519     inline bool setIpv6OnlyOption(bool on) {
7520 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
7521 	    int value = on ? 1 : 0;
7522 	    return setOption(IPPROTO_IPV6,IPV6_V6ONLY,&value,sizeof(value));
7523 #else
7524 	    return false;
7525 #endif
7526 	}
7527 
7528     /**
7529      * Get socket options
7530      * @param level Level of the option to set
7531      * @param name Socket option for which the value is to be set
7532      * @param buffer Pointer to a buffer to return the value for the requested option
7533      * @param length Pointer to size of the supplied buffer, will be filled on return
7534      * @return True if operation was successfull, false if an error occured
7535      */
7536     virtual bool getOption(int level, int name, void* buffer, socklen_t* length);
7537 
7538     /**
7539      * Set specific socket parameters.
7540      * @param params List of parameters
7541      */
setParams(const NamedList & params)7542     virtual bool setParams(const NamedList& params)
7543 	{ return false; }
7544 
7545     /**
7546      * Get specific socket parameters.
7547      * @param params Coma separated list of parameters to obtain
7548      * @param result List of parameters to fill
7549      * @return True if operation was successful, false if an error occurred
7550      */
getParams(const String & params,NamedList & result)7551     virtual bool getParams(const String& params, NamedList& result)
7552 	{ return false; }
7553 
7554     /**
7555      * Set the Type of Service or Differentiated Services Code Point on the IP level of this socket
7556      * @param tos New TOS or DiffServ bits
7557      * @return True if operation was successfull, false if an error occured
7558      */
7559     virtual bool setTOS(int tos);
7560 
7561     /**
7562      * Set the Type of Service or Differentiated Services Code Point on the IP level of this socket
7563      * @param tos Keyword describing new TOS or DSCP value
7564      * @param defTos Default TOS or DiffServ value to set if the keyword is not recognized
7565      * @return True if operation was successfull, false if an error occured
7566      */
7567     inline bool setTOS(const char* tos, int defTos = Normal)
7568 	{ return setTOS(lookup(tos,tosValues(),defTos)); }
7569 
7570     /**
7571      * Retrieve the TOS / DSCP on the IP level of this socket
7572      * @return TOS or DiffServ value, Normal if not supported or an error occured
7573      */
7574     virtual int getTOS();
7575 
7576     /**
7577      * Set the blocking or non-blocking operation mode of the socket
7578      * @param block True if I/O operations should block, false for non-blocking
7579      * @return True if operation was successfull, false if an error occured
7580      */
7581     virtual bool setBlocking(bool block = true);
7582 
7583     /**
7584      * Set the local address+port reuse flag of the socket.
7585      * This method should be called before bind() or it will have no effect.
7586      * @param reuse True if other sockets may listen on same address+port
7587      * @param exclusive Grant exclusive access to the address
7588      * @return True if operation was successfull, false if an error occured
7589      */
7590     virtual bool setReuse(bool reuse = true, bool exclusive = false);
7591 
7592     /**
7593      * Set the way closing a socket is handled
7594      * @param seconds How much to block waiting for socket to close,
7595      *  negative to no wait (close in background), zero to reset connection
7596      * @return True if operation was successfull, false if an error occured
7597      */
7598     virtual bool setLinger(int seconds = -1);
7599 
7600     /**
7601      * Associates the socket with a local address
7602      * @param addr Address to assign to this socket
7603      * @param addrlen Length of the address structure
7604      * @return True if operation was successfull, false if an error occured
7605      */
7606     virtual bool bind(struct sockaddr* addr, socklen_t addrlen);
7607 
7608     /**
7609      * Associates the socket with a local address
7610      * @param addr Address to assign to this socket
7611      * @return True if operation was successfull, false if an error occured
7612      */
bind(const SocketAddr & addr)7613     inline bool bind(const SocketAddr& addr)
7614 	{ return bind(addr.address(), addr.length()); }
7615 
7616     /**
7617      * Start listening for incoming connections on the socket
7618      * @param backlog Maximum length of the queue of pending connections, 0 for system maximum
7619      * @return True if operation was successfull, false if an error occured
7620      */
7621     virtual bool listen(unsigned int backlog = 0);
7622 
7623     /**
7624      * Create a new socket for an incoming connection attempt on a listening socket
7625      * @param addr Address to fill in with the address of the incoming connection
7626      * @param addrlen Length of the address structure on input, length of address data on return
7627      * @return Open socket to the new connection or NULL on failure
7628      */
7629     virtual Socket* accept(struct sockaddr* addr = 0, socklen_t* addrlen = 0);
7630 
7631     /**
7632      * Create a new socket for an incoming connection attempt on a listening socket
7633      * @param addr Address to fill in with the address of the incoming connection
7634      * @return Open socket to the new connection or NULL on failure
7635      */
7636     Socket* accept(SocketAddr& addr);
7637 
7638     /**
7639      * Create a new socket for an incoming connection attempt on a listening socket
7640      * @param addr Address to fill in with the address of the incoming connection
7641      * @param addrlen Length of the address structure on input, length of address data on return
7642      * @return Operating system handle to the new connection or @ref invalidHandle() on failure
7643      */
7644     SOCKET acceptHandle(struct sockaddr* addr = 0, socklen_t* addrlen = 0);
7645 
7646     /**
7647      * Update socket error from socket options.
7648      * This method should be called when select() indicates a non blocking operation
7649      *  completed.
7650      * Note: if false is returned, the socket error is the reason of getOption() failure
7651      * @return Return true on success
7652      */
7653     bool updateError();
7654 
7655     /**
7656      * Check if select() is efficient on this platform and worth using frequently
7657      * @return True if select() is efficiently implemented
7658      */
7659     static bool efficientSelect();
7660 
7661     /**
7662      * Check if a socket handle can be used in select
7663      * @param handle The socket handle to check
7664      * @return True if the socket handle can be safely used in select
7665      */
7666     static bool canSelect(SOCKET handle);
7667 
7668     /**
7669      * Check if this socket object can be used in a select
7670      * @return True if this socket can be safely used in select
7671      */
7672     virtual bool canSelect() const;
7673 
7674     /**
7675      * Connects the socket to a remote address
7676      * @param addr Address to connect to
7677      * @param addrlen Length of the address structure
7678      * @return True if operation was successfull, false if an error occured
7679      */
7680     virtual bool connect(struct sockaddr* addr, socklen_t addrlen);
7681 
7682     /**
7683      * Connects the socket to a remote address
7684      * @param addr Socket address to connect to
7685      * @return True if operation was successfull, false if an error occured
7686      */
connect(const SocketAddr & addr)7687     inline bool connect(const SocketAddr& addr)
7688 	{ return connect(addr.address(), addr.length()); }
7689 
7690     /**
7691      * Asynchronously connects the socket to a remote address.
7692      * The socket must be selectable and in non-blocking operation mode
7693      * @param addr Address to connect to
7694      * @param addrlen Length of the address structure
7695      * @param toutUs Timeout interval in microseconds
7696      * @param timeout Optional boolean flag to signal timeout
7697      * @return True on success
7698      */
7699     virtual bool connectAsync(struct sockaddr* addr, socklen_t addrlen, unsigned int toutUs,
7700 	bool* timeout = 0);
7701 
7702     /**
7703      * Asynchronously connects the socket to a remote address.
7704      * The socket must be selectable and in non-blocking operation mode
7705      * @param addr Socket address to connect to
7706      * @param toutUs Timeout interval in microseconds
7707      * @param timeout Optional boolean flag to signal timeout
7708      * @return True on success
7709      */
7710     inline bool connectAsync(const SocketAddr& addr, unsigned int toutUs,
7711 	bool* timeout = 0)
7712 	{ return connectAsync(addr.address(),addr.length(),toutUs,timeout); }
7713 
7714     /**
7715      * Shut down one or both directions of a full-duplex socket.
7716      * @param stopReads Request to shut down the read side of the socket
7717      * @param stopWrites Request to shut down the write side of the socket
7718      * @return True if operation was successfull, false if an error occured
7719      */
7720     virtual bool shutdown(bool stopReads, bool stopWrites);
7721 
7722     /**
7723      * Retrieve the address of the local socket of a connection
7724      * @param addr Address to fill in with the address of the local socket
7725      * @param addrlen Length of the address structure on input, length of address data on return
7726      * @return True if operation was successfull, false if an error occured
7727      */
7728     virtual bool getSockName(struct sockaddr* addr, socklen_t* addrlen);
7729 
7730     /**
7731      * Retrieve the address of the local socket of a connection
7732      * @param addr Address to fill in with the address of the local socket
7733      * @return True if operation was successfull, false if an error occured
7734      */
7735     bool getSockName(SocketAddr& addr);
7736 
7737     /**
7738      * Retrieve the address of the remote socket of a connection
7739      * @param addr Address to fill in with the address of the remote socket
7740      * @param addrlen Length of the address structure on input, length of address data on return
7741      * @return True if operation was successfull, false if an error occured
7742      */
7743     virtual bool getPeerName(struct sockaddr* addr, socklen_t* addrlen);
7744 
7745     /**
7746      * Retrieve the address of the remote socket of a connection
7747      * @param addr Address to fill in with the address of the remote socket
7748      * @return True if operation was successfull, false if an error occured
7749      */
7750     bool getPeerName(SocketAddr& addr);
7751 
7752     /**
7753      * Send a message over a connected or unconnected socket
7754      * @param buffer Buffer for data transfer
7755      * @param length Length of the buffer
7756      * @param addr Address to send the message to, if NULL will behave like @ref send()
7757      * @param adrlen Length of the address structure
7758      * @param flags Operating system specific bit flags that change the behaviour
7759      * @return Number of bytes transferred, @ref socketError() if an error occurred
7760      */
7761     virtual int sendTo(const void* buffer, int length, const struct sockaddr* addr, socklen_t adrlen, int flags = 0);
7762 
7763     /**
7764      * Send a message over a connected or unconnected socket
7765      * @param buffer Buffer for data transfer
7766      * @param length Length of the buffer
7767      * @param addr Address to send the message to
7768      * @param flags Operating system specific bit flags that change the behaviour
7769      * @return Number of bytes transferred, @ref socketError() if an error occurred
7770      */
7771     inline int sendTo(const void* buffer, int length, const SocketAddr& addr, int flags = 0)
7772 	{ return sendTo(buffer, length, addr.address(), addr.length(), flags); }
7773 
7774     /**
7775      * Send a message over a connected socket
7776      * @param buffer Buffer for data transfer
7777      * @param length Length of the buffer
7778      * @param flags Operating system specific bit flags that change the behaviour
7779      * @return Number of bytes transferred, @ref socketError() if an error occurred
7780      */
7781     virtual int send(const void* buffer, int length, int flags = 0);
7782 
7783     /**
7784      * Write data to a connected stream socket
7785      * @param buffer Buffer for data transfer
7786      * @param length Length of the buffer
7787      * @return Number of bytes transferred, @ref socketError() if an error occurred
7788      */
7789     virtual int writeData(const void* buffer, int length);
7790 
7791     /**
7792      * Receive a message from a connected or unconnected socket
7793      * @param buffer Buffer for data transfer
7794      * @param length Length of the buffer
7795      * @param addr Address to fill in with the address of the incoming data
7796      * @param adrlen Length of the address structure on input, length of address data on return
7797      * @param flags Operating system specific bit flags that change the behaviour
7798      * @return Number of bytes transferred, @ref socketError() if an error occurred
7799      */
7800     virtual int recvFrom(void* buffer, int length, struct sockaddr* addr = 0, socklen_t* adrlen = 0, int flags = 0);
7801 
7802     /**
7803      * Receive a message from a connected or unconnected socket
7804      * @param buffer Buffer for data transfer
7805      * @param length Length of the buffer
7806      * @param addr Address to fill in with the address of the incoming data
7807      * @param flags Operating system specific bit flags that change the behaviour
7808      * @return Number of bytes transferred, @ref socketError() if an error occurred
7809      */
7810     int recvFrom(void* buffer, int length, SocketAddr& addr, int flags = 0);
7811 
7812     /**
7813      * Receive a message from a connected socket
7814      * @param buffer Buffer for data transfer
7815      * @param length Length of the buffer
7816      * @param flags Operating system specific bit flags that change the behaviour
7817      * @return Number of bytes transferred, @ref socketError() if an error occurred
7818      */
7819     virtual int recv(void* buffer, int length, int flags = 0);
7820 
7821     /**
7822      * Receive data from a connected stream socket
7823      * @param buffer Buffer for data transfer
7824      * @param length Length of the buffer
7825      * @return Number of bytes transferred, @ref socketError() if an error occurred
7826      */
7827     virtual int readData(void* buffer, int length);
7828 
7829     /**
7830      * Determines the availability to perform synchronous I/O of the socket
7831      * @param readok Address of a boolean variable to fill with readability status
7832      * @param writeok Address of a boolean variable to fill with writeability status
7833      * @param except Address of a boolean variable to fill with exceptions status
7834      * @param timeout Maximum time until the method returns, NULL for blocking
7835      * @return True if operation was successfull, false if an error occured
7836      */
7837     virtual bool select(bool* readok, bool* writeok, bool* except, struct timeval* timeout = 0);
7838 
7839     /**
7840      * Determines the availability to perform synchronous I/O of the socket
7841      * @param readok Address of a boolean variable to fill with readability status
7842      * @param writeok Address of a boolean variable to fill with writeability status
7843      * @param except Address of a boolean variable to fill with exceptions status
7844      * @param timeout Maximum time until the method returns, -1 for blocking
7845      * @return True if operation was successfull, false if an error occured
7846      */
7847     bool select(bool* readok, bool* writeok, bool* except, int64_t timeout);
7848 
7849     /**
7850      * Install a new packet filter in the socket
7851      * @param filter Pointer to the packet filter to install
7852      * @return True if the filter was installed
7853      */
7854     bool installFilter(SocketFilter* filter);
7855 
7856     /**
7857      * Removes a packet filter and optionally destroys it
7858      * @param filter Pointer to the packet filter to remove from socket
7859      * @param delobj Set to true to also delete the filter
7860      */
7861     void removeFilter(SocketFilter* filter, bool delobj = false);
7862 
7863     /**
7864      * Removes and destroys all packet filters
7865      */
7866     void clearFilters();
7867 
7868     /**
7869      * Run whatever actions required on idle thread runs.
7870      * The default implementation calls @ref SocketFilter::timerTick()
7871      *  for all installed filters.
7872      * @param when Time when the idle run started
7873      */
7874     virtual void timerTick(const Time& when);
7875 
7876     /**
7877      * Create a pair of bidirectionally connected sockets
7878      * @param sock1 Reference to first Socket to be paired
7879      * @param sock2 Reference to second Socket to be paired
7880      * @param domain Communication domain for the sockets (protocol family)
7881      * @return True is the stream pair was created successfully
7882      */
7883     static bool createPair(Socket& sock1, Socket& sock2, int domain = AF_UNIX);
7884 
7885 protected:
7886 
7887     /**
7888      * Copy the last error code from the operating system
7889      */
7890     void copyError();
7891 
7892     /**
7893      * Copy the last error code from the operating system if an error occured, clear if not
7894      * @param retcode Operation return code to check, 0 for success
7895      * @param strict True to consider errors only return codes of @ref socketError()
7896      * @return True if operation succeeded (retcode == 0), false otherwise
7897      */
7898     bool checkError(int retcode, bool strict = false);
7899 
7900     /**
7901      * Apply installed filters to a received block of data
7902      * @param buffer Buffer for received data
7903      * @param length Length of the data in buffer
7904      * @param flags Operating system specific bit flags of the operation
7905      * @param addr Address of the incoming data, may be NULL
7906      * @param adrlen Length of the valid data in address structure
7907      * @return True if one of the filters claimed the data
7908      */
7909     bool applyFilters(void* buffer, int length, int flags, const struct sockaddr* addr = 0, socklen_t adrlen = 0);
7910 
7911     SOCKET m_handle;
7912     ObjList m_filters;
7913 };
7914 
7915 /**
7916  * The SctpSocket interface provides access to SCTP specific functions
7917  * @short Abstract SCTP Socket
7918  */
7919 class YATE_API SctpSocket : public Socket
7920 {
7921     YNOCOPY(SctpSocket); // no automatic copies please
7922 public:
7923     /**
7924      * Constructor
7925      */
SctpSocket()7926      inline SctpSocket()
7927 	{ }
7928 
7929     /**
7930      * Constructor
7931      * @param fd File descriptor of an existing handle
7932      */
SctpSocket(SOCKET fd)7933     inline explicit SctpSocket(SOCKET fd)
7934 	: Socket(fd)
7935 	{ }
7936 
7937     /**
7938      * Destructor
7939      */
7940     virtual ~SctpSocket();
7941 
7942     /**
7943      * Bind this socket to multiple addresses
7944      * @param addresses The list of addresses (SocketAddr)
7945      * @return True if the socket bind succeded
7946      */
7947     virtual bool bindx(ObjList& addresses) = 0;
7948 
7949     /**
7950      * Connect this socket to multiple addresses
7951      * @param addresses the list of addresses (SocketAddr)
7952      * @return True if the socket connect succeded
7953      */
7954     virtual bool connectx(ObjList& addresses) = 0;
7955 
7956     /**
7957      * Send a message over a connected or unconnected socket
7958      * @param buffer Buffer for data transfer
7959      * @param length Length of the buffer
7960      * @param stream The stream number
7961      * @param addr Address to send the message to, if NULL will behave like @ref send()
7962      * @param flags Operating system specific bit flags that change the behaviour
7963      * @return Number of bytes transferred, @ref socketError() if an error occurred
7964      */
7965     virtual int sendTo(void* buffer, int length, int stream, SocketAddr& addr, int flags) = 0;
7966 
7967     /**
7968      * Accept an incoming connection
7969      * @param addr The socket address of the incoming connection
7970      * @return A new SctpSocket if an incoming connection was detected
7971      */
accept(SocketAddr & addr)7972     virtual Socket* accept(SocketAddr& addr)
7973 	{ return 0; }
7974 
7975     /**
7976      * Send a buffer of data over a connected socket
7977      * @param buf The data to send
7978      * @param length Data length
7979      * @param stream The stream number to send over
7980      * @param flags Flags, gets altered on return
7981      * @return The number of bytes sent
7982      */
7983     virtual int sendMsg(const void* buf, int length, int stream, int& flags) = 0;
7984 
7985     /**
7986      * Receive data from a connected socket
7987      * @param buf The buffer where the data will be stored
7988      * @param length The buffer length
7989      * @param addr Gets the remote address from which the data was received
7990      * @param stream Gets the stream number on which the data was read
7991      * @param flags Flags, gets altered on return
7992      * @return The number of bytes read
7993      */
7994     virtual int recvMsg(void* buf, int length, SocketAddr& addr, int& stream, int& flags) = 0;
7995 
7996     /**
7997      * Set the number of streams
7998      * @param inbound The number of inbound streams
7999      * @param outbound The number of outbound streams
8000      * @return True if the number of streams was set
8001      */
8002     virtual bool setStreams(int inbound, int outbound) = 0;
8003 
8004     /**
8005      * Subscribe to SCTP events
8006      * This method should be called if we need to find from which stream the data came
8007      * @return True if subscription has succeeded
8008      */
8009     virtual bool subscribeEvents() = 0;
8010 
8011     /**
8012      * Get the number of negotiated streams
8013      * @param inbound Number of inbound streams
8014      * @param outbound Number of outbound streams
8015      * @return True if operation has succeded
8016      */
8017     virtual bool getStreams(int& inbound, int& outbound) = 0;
8018 
8019     /**
8020      * Set the SCTP payload protocol identifier (RFC 4960)
8021      * @param payload Payload identifier code
8022      * @return True if set successfully
8023      */
8024     virtual bool setPayload(u_int32_t payload) = 0;
8025 };
8026 
8027 /**
8028  * Helper class for insering a Socket pointer as a RefObject in a Message
8029  * @short RefObject holding a Socket pointer
8030  */
8031 class YATE_API SocketRef : public RefObject
8032 {
8033 public:
8034     /**
8035      * Constructor from pointer
8036      * @param socket Pointer to the Socket* to hold
8037      */
SocketRef(Socket ** socket)8038     inline SocketRef(Socket** socket)
8039 	: m_socket(socket)
8040 	{ }
8041 
8042     /**
8043      * Constructor from reference
8044      * @param socket Reference to the Socket* to hold
8045      */
SocketRef(Socket * & socket)8046     inline SocketRef(Socket*& socket)
8047 	: m_socket(&socket)
8048 	{ }
8049 
8050     /**
8051      * Get a pointer to a derived class given that class name
8052      * @param name Name of the class we are asking for
8053      * @return Pointer to the requested class or NULL if this object doesn't implement it
8054      */
getObject(const String & name)8055     virtual void* getObject(const String& name) const
8056 	{ return (name == YATOM("Socket*")) ? m_socket : RefObject::getObject(name); }
8057 
8058 private:
8059     SocketRef();
8060     void* m_socket;
8061 };
8062 
8063 /**
8064  * This class holds a DNS (resolver) record
8065  * @short A DNS record
8066  */
8067 class YATE_API DnsRecord : public GenObject
8068 {
8069     YCLASS(DnsRecord,GenObject)
8070     YNOCOPY(DnsRecord);
8071 public:
8072     /**
8073      * Build a DNS record
8074      * @param ttl Record Time To Live
8075      * @param order Record order (priority)
8076      * @param pref Record preference
8077      */
DnsRecord(int ttl,int order,int pref)8078     inline DnsRecord(int ttl, int order, int pref)
8079 	: m_ttl(ttl), m_order(order), m_pref(pref)
8080 	{}
8081 
8082     /**
8083      * Default constructor
8084      */
DnsRecord()8085     inline DnsRecord()
8086 	: m_order(0), m_pref(0)
8087 	{}
8088 
8089     /**
8090      * Retrieve the Time To Live
8091      * @return Record TTL
8092      */
ttl()8093     inline int ttl() const
8094 	{ return m_ttl; }
8095 
8096     /**
8097      * Retrieve the record order
8098      * @return Record order
8099      */
order()8100     inline int order() const
8101 	{ return m_order; }
8102 
8103     /**
8104      * Retrieve the record preference
8105      * @return Record preference
8106      */
pref()8107     inline int pref() const
8108 	{ return m_pref; }
8109 
8110     /**
8111      * Dump a record for debug purposes
8112      * @param buf Destination buffer
8113      * @param sep Fields separator
8114      */
8115     virtual void dump(String& buf, const char* sep = " ");
8116 
8117     /**
8118      * Insert a DnsRecord into a list in the proper location given by order and preference
8119      * @param list Destination list
8120      * @param rec The item to insert
8121      * @param ascPref Order preference ascending
8122      * @return True on success, false on failure (already in the list)
8123      */
8124     static bool insert(ObjList& list, DnsRecord* rec, bool ascPref);
8125 
8126 protected:
8127     int m_ttl;
8128     int m_order;
8129     int m_pref;
8130 };
8131 
8132 /**
8133  * This class holds a A, AAAA or TXT record from DNS
8134  * @short A text based DNS record
8135  */
8136 class YATE_API TxtRecord : public DnsRecord
8137 {
8138     YCLASS(TxtRecord,DnsRecord)
8139     YNOCOPY(TxtRecord);
8140 public:
8141     /**
8142      * Build a TXT record
8143      * @param ttl Record Time To Live
8144      * @param text Text content of the record
8145      */
TxtRecord(int ttl,const char * text)8146     inline TxtRecord(int ttl, const char* text)
8147 	: DnsRecord(ttl,-1,-1), m_text(text)
8148 	{}
8149 
8150     /**
8151      * Retrieve the record text
8152      * @return Record text
8153      */
text()8154     inline const String& text() const
8155 	{ return m_text; }
8156 
8157     /**
8158      * Dump this record for debug purposes
8159      * @param buf Destination buffer
8160      * @param sep Fields separator
8161      */
8162     virtual void dump(String& buf, const char* sep = " ");
8163 
8164     /**
8165      * Copy a TxtRecord list into another one
8166      * @param dest Destination list
8167      * @param src Source list
8168      */
8169     static void copy(ObjList& dest, const ObjList& src);
8170 
8171 protected:
8172     String m_text;
8173 
8174 private:
TxtRecord()8175     TxtRecord() {}                       // No default contructor
8176 };
8177 
8178 /**
8179  * This class holds a SRV (Service Location) record
8180  * @short A SRV record
8181  */
8182 class YATE_API SrvRecord : public DnsRecord
8183 {
8184     YCLASS(SrvRecord,DnsRecord)
8185     YNOCOPY(SrvRecord);
8186 public:
8187     /**
8188      * Build a SRV record
8189      * @param ttl Record Time To Live
8190      * @param prio Record priority (order)
8191      * @param weight Record weight (preference)
8192      * @param addr Record address
8193      * @param port Record port
8194      */
SrvRecord(int ttl,int prio,int weight,const char * addr,int port)8195     inline SrvRecord(int ttl, int prio, int weight, const char* addr, int port)
8196 	: DnsRecord(ttl,prio,weight), m_address(addr), m_port(port)
8197 	{}
8198 
8199     /**
8200      * Retrieve the record address
8201      * @return Record address
8202      */
address()8203     inline const String& address() const
8204 	{ return m_address; }
8205 
8206     /**
8207      * Retrieve the record port
8208      * @return Record port
8209      */
port()8210     inline int port() const
8211 	{ return m_port; }
8212 
8213     /**
8214      * Dump this record for debug purposes
8215      * @param buf Destination buffer
8216      * @param sep Fields separator
8217      */
8218     virtual void dump(String& buf, const char* sep = " ");
8219 
8220     /**
8221      * Copy a SrvRecord list into another one
8222      * @param dest Destination list
8223      * @param src Source list
8224      */
8225     static void copy(ObjList& dest, const ObjList& src);
8226 
8227 protected:
8228     String m_address;
8229     int m_port;
8230 
8231 private:
SrvRecord()8232     SrvRecord() {}                       // No default contructor
8233 };
8234 
8235 /**
8236  * This class holds a NAPTR (Naming Authority Pointer) record
8237  * @short A NAPTR record
8238  */
8239 class YATE_API NaptrRecord : public DnsRecord
8240 {
8241     YCLASS(NaptrRecord,DnsRecord)
8242     YNOCOPY(NaptrRecord);
8243 public:
8244     /**
8245      * Build a NAPTR record
8246      * @param ttl Record Time To Live
8247      * @param ord Record order
8248      * @param pref Record preference
8249      * @param flags Interpretation flags
8250      * @param serv Available services
8251      * @param regexp Substitution expression
8252      * @param next Next name to query
8253      */
8254     NaptrRecord(int ttl, int ord, int pref, const char* flags, const char* serv,
8255 	const char* regexp, const char* next);
8256 
8257     /**
8258      * Replace the enclosed template in a given string if matching
8259      *  the substitution expression
8260      * @param str String to replace
8261      * @return True on success
8262      */
8263     bool replace(String& str) const;
8264 
8265     /**
8266      * Dump this record for debug purposes
8267      * @param buf Destination buffer
8268      * @param sep Fields separator
8269      */
8270     virtual void dump(String& buf, const char* sep = " ");
8271 
8272     /**
8273      * Retrieve record interpretation flags
8274      * @return Record interpretation flags
8275      */
flags()8276     inline const String& flags() const
8277 	{ return m_flags; }
8278 
8279     /**
8280      * Retrieve available services
8281      * @return Available services
8282      */
serv()8283     inline const String& serv() const
8284 	{ return m_service; }
8285 
8286     /**
8287      * Retrieve the regular expression match
8288      * @return Regular expression used in match
8289      */
regexp()8290     inline const Regexp& regexp() const
8291 	{ return m_regmatch; }
8292 
8293     /**
8294      * Retrieve the template for replacing
8295      * @return Template used to replace the match
8296      */
repTemplate()8297     inline const String& repTemplate() const
8298 	{ return m_template; }
8299 
8300     /**
8301      * Retrieve the next domain name to query
8302      * @return The next domain to query
8303      */
nextName()8304     inline const String& nextName() const
8305 	{ return m_next; }
8306 
8307 protected:
8308     String m_flags;
8309     String m_service;
8310     Regexp m_regmatch;
8311     String m_template;
8312     String m_next;
8313 
8314 private:
NaptrRecord()8315     NaptrRecord() {}                     // No default contructor
8316 };
8317 
8318 /**
8319  * This class offers DNS query services
8320  * @short DNS services
8321  */
8322 class YATE_API Resolver
8323 {
8324 public:
8325     /**
8326      * Resolver handled types
8327      */
8328     enum Type {
8329 	Unknown,
8330 	Srv,                             // SRV (Service Location)
8331 	Naptr,                           // NAPTR (Naming Authority Pointer)
8332 	A4,                              // A (Address)
8333 	A6,                              // AAAA (IPv6 Address)
8334 	Txt,                             // TXT (Text)
8335     };
8336 
8337     /**
8338      * Runtime check for resolver availability
8339      * @param type Optional type to check. Set it to Unknown (default) to check
8340      *  general resolver availability
8341      * @return True if the resolver is available on current platform
8342      */
8343     static bool available(Type type = Unknown);
8344 
8345     /**
8346      * Initialize the resolver in the current thread
8347      * @param timeout Query timeout. Negative to use default
8348      * @param retries The number of query retries. Negative to use default
8349      * @return True on success
8350      */
8351     static bool init(int timeout = -1, int retries = -1);
8352 
8353     /**
8354      * Make a query
8355      * @param type Query type as enumeration
8356      * @param dname Domain to query
8357      * @param result List of resulting record items
8358      * @param error Optional string to be filled with error string
8359      * @return 0 on success, error code otherwise (h_errno value on Linux)
8360      */
8361     static int query(Type type, const char* dname, ObjList& result, String* error = 0);
8362 
8363     /**
8364      * Make a SRV (Service Location) query
8365      * @param dname Domain to query
8366      * @param result List of resulting SrvRecord items
8367      * @param error Optional string to be filled with error string
8368      * @return 0 on success, error code otherwise (h_errno value on Linux)
8369      */
8370     static int srvQuery(const char* dname, ObjList& result, String* error = 0);
8371 
8372     /**
8373      * Make a NAPTR (Naming Authority Pointer) query
8374      * @param dname Domain to query
8375      * @param result List of resulting NaptrRecord items
8376      * @param error Optional string to be filled with error string
8377      * @return 0 on success, error code otherwise (h_errno value on Linux)
8378      */
8379     static int naptrQuery(const char* dname, ObjList& result, String* error = 0);
8380 
8381     /**
8382      * Make an A (IPv4 Address) query
8383      * @param dname Domain to query
8384      * @param result List of resulting TxtRecord items
8385      * @param error Optional string to be filled with error string
8386      * @return 0 on success, error code otherwise (h_errno value on Linux)
8387      */
8388     static int a4Query(const char* dname, ObjList& result, String* error = 0);
8389 
8390     /**
8391      * Make an AAAA (IPv6 Address) query
8392      * @param dname Domain to query
8393      * @param result List of resulting TxtRecord items
8394      * @param error Optional string to be filled with error string
8395      * @return 0 on success, error code otherwise (h_errno value on Linux)
8396      */
8397     static int a6Query(const char* dname, ObjList& result, String* error = 0);
8398 
8399     /**
8400      * Make a TXT (Text) query
8401      * @param dname Domain to query
8402      * @param result List of resulting TxtRecord items
8403      * @param error Optional string to be filled with error string
8404      * @return 0 on success, error code otherwise (h_errno value on Linux)
8405      */
8406     static int txtQuery(const char* dname, ObjList& result, String* error = 0);
8407 
8408     /**
8409      * Resolver type names
8410      */
8411     static const TokenDict s_types[];
8412 };
8413 
8414 /**
8415  * The Cipher class provides an abstraction for data encryption classes
8416  * @short An abstract cipher
8417  */
8418 class YATE_API Cipher : public GenObject
8419 {
8420 public:
8421     /**
8422      * Cipher direction
8423      */
8424     enum Direction {
8425 	Bidir,
8426 	Encrypt,
8427 	Decrypt,
8428     };
8429 
8430     /**
8431      * Get the dictionary of cipher directions
8432      * @return Pointer to the dictionary of cipher directions
8433      */
directions()8434     inline static const TokenDict* directions()
8435 	{ return s_directions; }
8436 
8437     /**
8438      * Get a direction from the dictionary given the name
8439      * @param name Name of the direction
8440      * @param defdir Default direction to return if name is empty or unknown
8441      * @return Direction associated with the given name
8442      */
8443     inline static Direction direction(const char* name, Direction defdir = Bidir)
8444 	{ return (Direction)TelEngine::lookup(name,s_directions,defdir); }
8445 
8446     /**
8447      * Destructor
8448      */
8449     virtual ~Cipher();
8450 
8451     /**
8452      * Get a pointer to a derived class given that class name
8453      * @param name Name of the class we are asking for
8454      * @return Pointer to the requested class or NULL if this object doesn't implement it
8455      */
8456     virtual void* getObject(const String& name) const;
8457 
8458     /**
8459      * Check if the cipher instance is valid for a specific direction
8460      * @param dir Direction to check
8461      * @return True if the cipher is able to perform operation on given direction
8462      */
8463     virtual bool valid(Direction dir = Bidir) const;
8464 
8465     /**
8466      * Get the cipher block size
8467      * @return Cipher block size in bytes
8468      */
8469     virtual unsigned int blockSize() const = 0;
8470 
8471     /**
8472      * Get the initialization vector size
8473      * @return Initialization vector size in bytes, 0 if not applicable
8474      */
8475     virtual unsigned int initVectorSize() const;
8476 
8477     /**
8478      * Round up a buffer length to a multiple of block size
8479      * @param len Length of data to encrypt or decrypt in bytes
8480      * @return Length of required buffer in bytes
8481      */
8482     unsigned int bufferSize(unsigned int len) const;
8483 
8484     /**
8485      * Check if a buffer length is multiple of block size
8486      * @param len Length of data to encrypt or decrypt in bytes
8487      * @return True if buffer length is multiple of block size
8488      */
8489     bool bufferFull(unsigned int len) const;
8490 
8491     /**
8492      * Set the key required to encrypt or decrypt data
8493      * @param key Pointer to binary key data
8494      * @param len Length of key in bytes
8495      * @param dir Direction to set key for
8496      * @return True if the key was set successfully
8497      */
8498     virtual bool setKey(const void* key, unsigned int len, Direction dir = Bidir) = 0;
8499 
8500     /**
8501      * Set the key required to encrypt or decrypt data
8502      * @param key Binary key data block
8503      * @param dir Direction to set key for
8504      * @return True if the key was set successfully
8505      */
8506     inline bool setKey(const DataBlock& key, Direction dir = Bidir)
8507 	{ return setKey(key.data(),key.length(),dir); }
8508 
8509     /**
8510      * Set the Initialization Vector if applicable
8511      * @param vect Pointer to binary Initialization Vector data
8512      * @param len Length of Initialization Vector in bytes
8513      * @param dir Direction to set the Initialization Vector for
8514      * @return True if the Initialization Vector was set successfully
8515      */
8516     virtual bool initVector(const void* vect, unsigned int len, Direction dir = Bidir);
8517 
8518     /**
8519      * Set the Initialization Vector is applicable
8520      * @param vect Binary Initialization Vector
8521      * @param dir Direction to set the Initialization Vector for
8522      * @return True if the Initialization Vector was set successfully
8523      */
8524     inline bool initVector(const DataBlock& vect, Direction dir = Bidir)
8525 	{ return initVector(vect.data(),vect.length(),dir); }
8526 
8527     /**
8528      * Encrypt data
8529      * @param outData Pointer to buffer for output (encrypted) and possibly input data
8530      * @param len Length of output data, may not be multiple of block size
8531      * @param inpData Pointer to buffer containing input (unencrypted) data, NULL to encrypt in place
8532      * @return True if data was successfully encrypted
8533      */
8534     virtual bool encrypt(void* outData, unsigned int len, const void* inpData = 0) = 0;
8535 
8536     /**
8537      * Encrypt a DataBlock in place
8538      * @param data Data block to encrypt
8539      * @return True if data was successfully encrypted
8540      */
encrypt(DataBlock & data)8541     inline bool encrypt(DataBlock& data)
8542 	{ return encrypt(data.data(),data.length()); }
8543 
8544     /**
8545      * Decrypt data
8546      * @param outData Pointer to buffer for output (decrypted) and possibly input data
8547      * @param len Length of output data, may not be multiple of block size
8548      * @param inpData Pointer to buffer containing input (encrypted) data, NULL to decrypt in place
8549      * @return True if data was successfully decrypted
8550      */
8551     virtual bool decrypt(void* outData, unsigned int len, const void* inpData = 0) = 0;
8552 
8553     /**
8554      * Decrypt a DataBlock in place
8555      * @param data Data block to decrypt
8556      * @return True if data was successfully decrypted
8557      */
decrypt(DataBlock & data)8558     inline bool decrypt(DataBlock& data)
8559 	{ return decrypt(data.data(),data.length()); }
8560 
8561 private:
8562     static const TokenDict s_directions[];
8563 };
8564 
8565 /**
8566  * The Compressor class provides an abstraction for data (de)compressor classes.
8567  * The String component keeps an optional object name to be used for debug purposes
8568  * @short An abstract data (de)compressor
8569  */
8570 class YATE_API Compressor : public String
8571 {
8572     YCLASS(Compressor,String)
8573     YNOCOPY(Compressor); // no automatic copies please
8574 public:
8575     /**
8576      * Constructor
8577      * @param format Compression format
8578      * @param name Optional object name
8579      */
8580     inline Compressor(const char* format, const char* name = 0)
String(name)8581 	: String(name), m_format(format)
8582 	{}
8583 
8584     /**
8585      * Destructor
8586      */
~Compressor()8587     virtual ~Compressor()
8588 	{}
8589 
8590     /**
8591      * Retrieve (de)compressor format
8592      * @return The format of this (de)compressor
8593      */
format()8594     inline const String& format() const
8595 	{ return m_format; }
8596 
8597     /**
8598      * Initialize
8599      * @param comp True to initialize compressor
8600      * @param decomp True to initialize decompressor
8601      * @param params Optional parameters
8602      * @return True on success
8603      */
8604     virtual bool init(bool comp = true, bool decomp = true,
8605 	const NamedList& params = NamedList::empty())
8606 	{ return true; }
8607 
8608     /**
8609      * Finalize the (de)compression
8610      * @param comp True to finalize compression, false to finalize decompression
8611      */
finalize(bool comp)8612     virtual void finalize(bool comp)
8613 	{}
8614 
8615     /**
8616      * Compress the input buffer, flush all pending data,
8617      *  append compressed data to the received data block
8618      * @param buf Pointer to input data
8619      * @param len Length of input in bytes
8620      * @param dest Destination buffer
8621      * @return The number of bytes wrote to compressor, negative on error
8622      */
8623     virtual int compress(const void* buf, unsigned int len, DataBlock& dest);
8624 
8625     /**
8626      * Decompress the input buffer, flush all pending data,
8627      *  append decompressed data to the received data block
8628      * @param buf Pointer to input data
8629      * @param len Length of input in bytes
8630      * @param dest Destination buffer
8631      * @return The number of bytes wrote to decompressor, negative on error
8632      */
8633     virtual int decompress(const void* buf, unsigned int len, DataBlock& dest);
8634 
8635     /**
8636      * Push data to compressor. Flush compressor input if input buffer is NULL
8637      *  or the length is 0 and flush is true
8638      * @param buf Pointer to input data
8639      * @param len Length of input in bytes
8640      * @param flush True to compress all now, false to let the compressor accumulate
8641      *  more data for better compression
8642      * @return The number of bytes written, negative on error. An incomplete write may occur
8643      *  if the output buffer is full
8644      */
8645     virtual int writeComp(const void* buf, unsigned int len, bool flush) = 0;
8646 
8647     /**
8648      * Push data to compressor
8649      * @param data Input data block
8650      * @param flush True to compress all now, false to let the compressor accumulate
8651      *  more data for better compression
8652      * @return The number of bytes written, negative on error. An incomplete write may occur
8653      *  if the output buffer is full
8654      */
writeComp(const DataBlock & data,bool flush)8655     inline int writeComp(const DataBlock& data, bool flush)
8656 	{ return writeComp(data.data(),data.length(),flush); }
8657 
8658     /**
8659      * Push data to compressor
8660      * @param data Input string
8661      * @param flush True to compress all now, false to let the compressor accumulate
8662      *  more data for better compression
8663      * @return The number of bytes written, negative on error. An incomplete write may occur
8664      *  if the output buffer is full
8665      */
writeComp(const String & data,bool flush)8666     inline int writeComp(const String& data, bool flush)
8667 	{ return writeComp(data.c_str(),data.length(),flush); }
8668 
8669     /**
8670      * Read data from compressor. Append it to 'buf'
8671      * @param buf Destination data block
8672      * @param flush True to flush all compressor input data
8673      * @return The number of bytes read, negative on error
8674      */
8675     virtual int readComp(DataBlock& buf, bool flush) = 0;
8676 
8677     /**
8678      * Push data to decompressor
8679      * @param buf Pointer to input data
8680      * @param len Length of input in bytes
8681      * @param flush True to try to decompress all data
8682      * @return The number of bytes written, negative on error. An incomplete write may occur
8683      *  if the output buffer is full
8684      */
8685     virtual int writeDecomp(const void* buf, unsigned int len, bool flush) = 0;
8686 
8687     /**
8688      * Push data to decompressor
8689      * @param data Input data block
8690      * @param flush True to try to decompress all data
8691      * @return The number of bytes written, negative on error. An incomplete write may occur
8692      *  if the output buffer is full
8693      */
writeDecomp(const DataBlock & data,bool flush)8694     inline int writeDecomp(const DataBlock& data, bool flush)
8695 	{ return writeDecomp(data.data(),data.length(),flush); }
8696 
8697     /**
8698      * Push data to decompressor
8699      * @param data Input string
8700      * @param flush True to try to decompress all data
8701      * @return The number of bytes written, negative on error. An incomplete write may occur
8702      *  if the output buffer is full
8703      */
writeDecomp(const String & data,bool flush)8704     inline int writeDecomp(const String& data, bool flush)
8705 	{ return writeDecomp(data.c_str(),data.length(),flush); }
8706 
8707     /**
8708      * Read data from decompressor. Append it to 'buf'
8709      * @param buf Destination data block
8710      * @param flush True to flush all decompressor input data
8711      * @return The number of bytes read, negative on error
8712      */
8713     virtual int readDecomp(DataBlock& buf, bool flush) = 0;
8714 
8715 protected:
8716     String m_format;
8717 };
8718 
8719 /**
8720  * The SysUsage class allows collecting some statistics about engine's usage
8721  *  of system resources
8722  * @short A class exposing system resources usage
8723  */
8724 class YATE_API SysUsage
8725 {
8726 public:
8727     /**
8728      * Type of time usage requested
8729      */
8730     enum Type {
8731 	WallTime,
8732 	UserTime,
8733 	KernelTime
8734     };
8735 
8736     /**
8737      * Initialize the system start variable
8738      */
8739     static void init();
8740 
8741     /**
8742      * Get the wall time used as start for the usage time
8743      * @return Time of the first direct or implicit call of @ref init()
8744      */
8745     static u_int64_t startTime();
8746 
8747     /**
8748      * Get the program's running time in microseconds
8749      * @param type Type of running time requested
8750      * @return Time in microseconds since the start of the program
8751      */
8752     static u_int64_t usecRunTime(Type type = WallTime);
8753 
8754     /**
8755      * Get the program's running time in milliseconds
8756      * @param type Type of running time requested
8757      * @return Time in milliseconds since the start of the program
8758      */
8759     static u_int64_t msecRunTime(Type type = WallTime);
8760 
8761     /**
8762      * Get the program's running time in seconds
8763      * @param type Type of running time requested
8764      * @return Time in seconds since the start of the program
8765      */
8766     static u_int32_t secRunTime(Type type = WallTime);
8767 
8768     /**
8769      * Get the program's running time in seconds
8770      * @param type Type of running time requested
8771      * @return Time in seconds since the start of the program
8772      */
8773     static double runTime(Type type = WallTime);
8774 
8775 };
8776 
8777 }; // namespace TelEngine
8778 
8779 #endif /* __YATECLASS_H */
8780 
8781 /* vi: set ts=8 sw=4 sts=4 noet: */
8782