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