1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Anthony Minessale II <anthm@freeswitch.org>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Seven Du <dujinfang@gmail.com>
28  *
29  *
30  * switch_utils.h -- Compatability and Helper Code
31  *
32  */
33 /*! \file switch_utils.h
34     \brief Compatability and Helper Code
35 
36 	Just a miscelaneaous set of general utility/helper functions.
37 
38 */
39 #ifndef SWITCH_UTILS_H
40 #define SWITCH_UTILS_H
41 
42 #include <switch.h>
43 #include <math.h>
44 
45 SWITCH_BEGIN_EXTERN_C
46 
47 #define SWITCH_URL_UNSAFE "\r\n #%&+:;<=>?@[\\]^`{|}\""
48 
49 #define MAX_NETWORK_PORTS 10
50 
51 struct switch_network_port_range {
52 	int port;
53 	int ports[MAX_NETWORK_PORTS];
54 	int min_port;
55 	int max_port;
56 };
57 typedef struct switch_network_port_range switch_network_port_range_t;
58 typedef switch_network_port_range_t* switch_network_port_range_p;
59 
switch_get_hex_bytes(switch_byte_t * buf,switch_size_t datalen,char * new_buf,switch_size_t new_datalen)60 static inline char *switch_get_hex_bytes(switch_byte_t *buf, switch_size_t datalen, char *new_buf, switch_size_t new_datalen)
61 {
62 	switch_byte_t *p, *e;
63 	char *pp, *ee;
64 
65 	e = buf + datalen;
66 	ee = new_buf + new_datalen;
67 	pp = new_buf;
68 
69 	for (p = buf; p < e && pp < ee - 4; p++) {
70 		if (snprintf(pp, 4, "%.2x ", (int)*p) < 0) {
71 			return NULL;
72 		}
73 		pp += 3;
74 	}
75 	*(pp-1) = '\0';
76 
77 	return new_buf;
78 }
79 
80 
switch_round_to_step(uint32_t num,uint32_t step)81 static inline uint32_t switch_round_to_step(uint32_t num, uint32_t step)
82 {
83 	uint32_t r;
84 	uint32_t x;
85 
86 	if (!num) return 0;
87 
88 	r = (num % step);
89 	x = num - r;
90 
91 	if (r > step / 2) {
92 		x += step;
93 	}
94 
95 	return x;
96 }
97 
98 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
99    http://www.azillionmonkeys.com/qed/asmexample.html
100 */
switch_toupper(uint32_t eax)101 static inline uint32_t switch_toupper(uint32_t eax)
102 {
103 uint32_t ebx = (0x7f7f7f7ful & eax) + 0x05050505ul;
104 ebx = (0x7f7f7f7ful & ebx) + 0x1a1a1a1aul;
105  ebx = ((ebx & ~eax) >> 2 ) & 0x20202020ul;
106  return eax - ebx;
107 }
108 
109 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
110    http://www.azillionmonkeys.com/qed/asmexample.html
111 */
switch_tolower(uint32_t eax)112 static inline uint32_t switch_tolower(uint32_t eax)
113 {
114 	uint32_t ebx = (0x7f7f7f7ful & eax) + 0x25252525ul;
115 	ebx = (0x7f7f7f7ful & ebx) + 0x1a1a1a1aul;
116 	ebx = ((ebx & ~eax) >> 2)  & 0x20202020ul;
117 	return eax + ebx;
118 }
119 
120 
121 #ifdef FS_64BIT
122 
123 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
124    http://www.azillionmonkeys.com/qed/asmexample.html
125 */
switch_toupper64(uint64_t eax)126 static inline uint64_t switch_toupper64(uint64_t eax)
127 {
128 uint64_t ebx = (0x7f7f7f7f7f7f7f7full & eax) + 0x0505050505050505ull;
129  ebx = (0x7f7f7f7f7f7f7f7full & ebx) + 0x1a1a1a1a1a1a1a1aull;
130  ebx = ((ebx & ~eax) >> 2 ) & 0x2020202020202020ull;
131  return eax - ebx;
132 }
133 
134 /* https://code.google.com/p/stringencoders/wiki/PerformanceAscii
135    http://www.azillionmonkeys.com/qed/asmexample.html
136 */
switch_tolower64(uint64_t eax)137 static inline uint64_t switch_tolower64(uint64_t eax)
138 {
139 	uint64_t ebx = (0x7f7f7f7f7f7f7f7full & eax) + 0x2525252525252525ull;
140 	ebx = (0x7f7f7f7f7f7f7f7full & ebx) + 0x1a1a1a1a1a1a1a1aull;
141 	ebx = ((ebx & ~eax) >> 2)  & 0x2020202020202020ull;
142 	return eax + ebx;
143 }
144 
switch_toupper_max(char * s)145 static inline void switch_toupper_max(char *s)
146 {
147 	uint64_t *b,*p;
148 	char *c;
149 	size_t l;
150 
151 	l = strlen(s);
152 
153 	p = (uint64_t *) s;
154 
155 	while (l > 8) {
156 		b = p;
157 		*b = (uint64_t) switch_toupper64(*b);
158 		b++;
159 		p++;
160 		l -= 8;
161 	}
162 
163 	c = (char *)p;
164 
165 	while(l > 0) {
166 		*c = (char) switch_toupper(*c);
167 		c++;
168 		l--;
169 	}
170 
171 }
172 
switch_tolower_max(char * s)173 static inline void switch_tolower_max(char *s)
174 {
175 	uint64_t *b,*p;
176 	char *c;
177 	size_t l;
178 
179 	l = strlen(s);
180 
181 	p = (uint64_t *) s;
182 
183 	while (l > 8) {
184 		b = p;
185 		*b = (uint64_t) switch_tolower64(*b);
186 		b++;
187 		p++;
188 		l -= 8;
189 	}
190 
191 	c = (char *)p;
192 
193 	while(l > 0) {
194 		*c = (char) switch_tolower(*c);
195 		c++;
196 		l--;
197 	}
198 
199 }
200 
201 #else
202 
switch_toupper_max(char * s)203 static inline void switch_toupper_max(char *s)
204 {
205 	uint32_t *b,*p;
206 	char *c;
207 	size_t l;
208 
209 	l = strlen(s);
210 
211 	p = (uint32_t *) s;
212 
213 	while (l > 4) {
214 		b = p;
215 		*b = (uint32_t) switch_toupper(*b);
216 		b++;
217 		p++;
218 		l -= 4;
219 	}
220 
221 	c = (char *)p;
222 
223 	while(l > 0) {
224 		*c = (char) switch_toupper(*c);
225 		c++;
226 		l--;
227 	}
228 
229 }
230 
switch_tolower_max(char * s)231 static inline void switch_tolower_max(char *s)
232 {
233 	uint32_t *b,*p;
234 	char *c;
235 	size_t l;
236 
237 	l = strlen(s);
238 
239 	p = (uint32_t *) s;
240 
241 	while (l > 4) {
242 		b = p;
243 		*b = (uint32_t) switch_tolower(*b);
244 		b++;
245 		p++;
246 		l -= 4;
247 	}
248 
249 	c = (char *)p;
250 
251 	while(l > 0) {
252 		*c = (char) switch_tolower(*c);
253 		c++;
254 		l--;
255 	}
256 
257 }
258 #endif
259 
260 
261 
262 
263 SWITCH_DECLARE(int) old_switch_toupper(int c);
264 SWITCH_DECLARE(int) old_switch_tolower(int c);
265 SWITCH_DECLARE(int) switch_isalnum(int c);
266 SWITCH_DECLARE(int) switch_isalpha(int c);
267 SWITCH_DECLARE(int) switch_iscntrl(int c);
268 SWITCH_DECLARE(int) switch_isdigit(int c);
269 SWITCH_DECLARE(int) switch_isgraph(int c);
270 SWITCH_DECLARE(int) switch_islower(int c);
271 SWITCH_DECLARE(int) switch_isprint(int c);
272 SWITCH_DECLARE(int) switch_ispunct(int c);
273 SWITCH_DECLARE(int) switch_isspace(int c);
274 SWITCH_DECLARE(int) switch_isupper(int c);
275 SWITCH_DECLARE(int) switch_isxdigit(int c);
276 
277 typedef union{
278     uint32_t v4;
279     struct in6_addr v6;
280 } ip_t;
281 
282 SWITCH_DECLARE(switch_bool_t) switch_testv6_subnet(ip_t _ip, ip_t _net, ip_t _mask);
283 
284 
285 SWITCH_DECLARE(char *) switch_print_host(switch_sockaddr_t *addr, char *buf, switch_size_t len);
286 
287 #define switch_goto_status(_status, _label) status = _status; goto _label
288 #define switch_goto_int(_n, _i, _label) _n = _i; goto _label
289 #define switch_samples_per_packet(rate, interval) ((uint32_t)((float)rate / (1000.0f / (float)interval)))
290 #define SWITCH_SMAX 32767
291 #define SWITCH_SMIN -32768
292 #define switch_normalize_to_16bit(n) if (n > SWITCH_SMAX) n = SWITCH_SMAX; else if (n < SWITCH_SMIN) n = SWITCH_SMIN;
293 #define switch_codec2str(codec,buf,len) snprintf(buf, len, "%s@%uh@%ui", \
294                                                  codec->implementation->iananame, \
295                                                  codec->implementation->samples_per_second, \
296                                                  codec->implementation->microseconds_per_packet / 1000)
297 
298 
299 
300 /*!
301   \brief Test for NULL or zero length string
302   \param s the string to test
303   \return true value if the string is NULL or zero length
304 */
_zstr(_In_opt_z_ const char * s)305 _Check_return_ static inline int _zstr(_In_opt_z_ const char *s)
306 {
307 	if (!s) return 1;
308 	if (*s == '\0') return 1;
309 	return 0;
310 }
311 #ifdef _PREFAST_
312 #define zstr(x) (_zstr(x) ? 1 : __analysis_assume(x),0)
313 #else
314 #define zstr(x) _zstr(x)
315 #endif
316 #define switch_strlen_zero(x) zstr(x)
317 #define switch_strlen_zero_buf(x) zstr_buf(x)
318 #define zstr_buf(s) (*(s) == '\0')
switch_is_moh(const char * s)319 static inline switch_bool_t switch_is_moh(const char *s)
320 {
321 	if (zstr(s) || !strcasecmp(s, "silence") || !strcasecmp(s, "indicate_hold")) {
322 		return SWITCH_FALSE;
323 	}
324 	return SWITCH_TRUE;
325 }
326 
327 
328 #define zset(_a, _b) if (!zstr(_b)) _a = _b
329 
330 
331 /* find a character (find) in a string (in) and return a pointer to that point in the string where the character was found
332    using the array (allowed) as allowed non-matching characters, when (allowed) is NULL, behaviour should be identical to strchr()
333  */
switch_strchr_strict(const char * in,char find,const char * allowed)334 static inline char *switch_strchr_strict(const char *in, char find, const char *allowed)
335 {
336 	const char *p;
337 
338 	switch_assert(in);
339 
340 	p = in;
341 
342 	if (!*p) return NULL;
343 
344 	while(p && *p) {
345 		const char *a = allowed;
346 		int acceptable = 0;
347 
348 		if (*p == find) break;
349 
350 		if (!a) {
351 			acceptable = 1;
352 		} else {
353 
354 			while(a && *a) {
355 
356 				if (*p == *a) {
357 					acceptable = 1;
358 					break;
359 				}
360 
361 				a++;
362 			}
363 
364 		}
365 
366 		if (!acceptable) return NULL;
367 
368 		p++;
369 	}
370 
371 	return (char *) p;
372 }
373 
374 #define switch_arraylen(_a) (sizeof(_a) / sizeof(_a[0]))
375 #define switch_split(_data, _delim, _array) switch_separate_string(_data, _delim, _array, switch_arraylen(_array))
376 
377 #define switch_is_valid_rate(_tmp) (_tmp == 8000 || _tmp == 12000 || _tmp == 16000 || _tmp == 24000 || _tmp == 32000 || _tmp == 11025 || _tmp == 22050 || _tmp == 44100 || _tmp == 48000)
378 
379 
380 #ifdef _MSC_VER
381 #pragma warning(disable:6011)
382 #endif
switch_string_has_escaped_data(const char * in)383 static inline int switch_string_has_escaped_data(const char *in)
384 {
385 	const char *i;
386 
387 	switch_assert(in);
388 
389 	i = strchr(in, '\\');
390 
391 	while (i && *i == '\\') {
392 		i++;
393 		if (*i == '\\' || *i == 'n' || *i == 's' || *i == 't' || *i == '\'') {
394 			return 1;
395 		}
396 		i = strchr(i, '\\');
397 	}
398 
399 	return 0;
400 }
401 #ifdef _MSC_VER
402 #pragma warning(default:6011)
403 #endif
404 
405 SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size_t ilen, unsigned char *out, switch_size_t olen);
406 SWITCH_DECLARE(switch_size_t) switch_b64_decode(const char *in, char *out, switch_size_t olen);
407 SWITCH_DECLARE(char *) switch_amp_encode(char *s, char *buf, switch_size_t len);
408 
409 
410 
switch_print_bits(const unsigned char * byte,char * buf,switch_size_t buflen)411 static inline char *switch_print_bits(const unsigned char *byte, char *buf, switch_size_t buflen)
412 {
413 	int i;
414 	switch_size_t j = 0, k = 0, l = 0;
415 
416 	while(k < buflen) {
417 		l = 0;
418 		for (i = 7; i >= 0; i--) {
419 			buf[j++] = (*byte & (1 << i)) ? '1' : '0';
420 			if (++l % 4 == 0) {
421 				buf[j++] = ' ';
422 			}
423 		}
424 		k++;
425 		byte++;
426 	}
427 
428 	if (buf[j-1] == ' ') j--;
429 	buf[j++] = '\0';
430 	return buf;
431 }
432 
433 
434 
435 
switch_is_digit_string(const char * s)436 static inline switch_bool_t switch_is_digit_string(const char *s)
437 {
438 
439 	while (s && *s) {
440 		if (*s < 48 || *s > 57) {
441 			return SWITCH_FALSE;
442 		}
443 		s++;
444 	}
445 
446 	return SWITCH_TRUE;
447 }
448 
switch_itodtmf(char i)449 static inline char switch_itodtmf(char i)
450 {
451 	char r = i;
452 
453 	if (i > 9 && i < 14) {
454 		r += 55;
455 	} else {
456 		r += 48;
457 	}
458 
459 	return r;
460 }
461 
switch_dtmftoi(char * s)462 static inline int switch_dtmftoi(char *s)
463 {
464 	int r;
465 
466 	switch_assert(s);
467 
468 	if (!(r = atoi(s))) {
469 		int l = tolower((unsigned char)*s);
470 		if (l > 96 && l < 101) {
471 			r = l - 87;
472 		}
473 	}
474 
475 	return r;
476 }
477 
switch_known_bitrate(switch_payload_t payload)478 static inline uint32_t switch_known_bitrate(switch_payload_t payload)
479 {
480 	switch(payload) {
481 	case 0: /* PCMU */ return 64000;
482 	case 3: /* GSM */ return 13200;
483 	case 4: /* G723 */ return 6300;
484 	case 7: /* LPC */ return 2400;
485 	case 8: /* PCMA */ return 64000;
486 	case 9: /* G722 */ return 64000;
487 	case 18: /* G729 */ return 8000;
488 	default: break;
489 	}
490 
491 	return 0;
492 }
493 
494 SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size_t len);
495 SWITCH_DECLARE(switch_size_t) switch_fd_read_dline(int fd, char **buf, switch_size_t *len);
496 SWITCH_DECLARE(switch_size_t) switch_fp_read_dline(FILE *fd, char **buf, switch_size_t *len);
497 
498 SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size);
499 SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone);
500 SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
501 SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
502 SWITCH_DECLARE(switch_bool_t) switch_is_leading_number(const char *str);
503 SWITCH_DECLARE(char *) switch_find_parameter(const char *str, const char *param, switch_memory_pool_t *pool);
504 
505 /*!
506   \brief Evaluate the truthfullness of a string expression
507   \param expr a string expression
508   \return true or false
509 */
switch_true(const char * expr)510 static inline switch_bool_t switch_true(const char *expr)
511 {
512 	return ((expr && ( !strcasecmp(expr, "yes") ||
513 					   !strcasecmp(expr, "on") ||
514 					   !strcasecmp(expr, "true") ||
515 					   !strcasecmp(expr, "t") ||
516 					   !strcasecmp(expr, "enabled") ||
517 					   !strcasecmp(expr, "active") ||
518 					   !strcasecmp(expr, "allow") ||
519 					   (switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
520 }
521 
switch_true_byte(const char * expr)522 static inline switch_byte_t switch_true_byte(const char *expr)
523 {
524 	return (switch_byte_t)switch_true(expr);
525 }
526 
527 #define switch_true_buf(expr)\
528 ((( !strcasecmp(expr, "yes") ||\
529 !strcasecmp(expr, "on") ||\
530 !strcasecmp(expr, "true") ||\
531 !strcasecmp(expr, "t") ||\
532 !strcasecmp(expr, "enabled") ||\
533 !strcasecmp(expr, "active") ||\
534 !strcasecmp(expr, "allow") ||\
535 (switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE)
536 
537 /*!
538   \brief Evaluate the falsefullness of a string expression
539   \param expr a string expression
540   \return true or false
541 */
switch_false(const char * expr)542 static inline int switch_false(const char *expr)
543 {
544 	return ((expr && ( !strcasecmp(expr, "no") ||
545 					   !strcasecmp(expr, "off") ||
546 					   !strcasecmp(expr, "false") ||
547 					   !strcasecmp(expr, "f") ||
548 					   !strcasecmp(expr, "disabled") ||
549 					   !strcasecmp(expr, "inactive") ||
550 					   !strcasecmp(expr, "disallow") ||
551 					   (switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
552 }
553 
554 
555 SWITCH_DECLARE(switch_status_t) switch_resolve_host(const char *host, char *buf, size_t buflen);
556 
557 
558 /*!
559   \brief find local ip of the box
560   \param buf the buffer to write the ip address found into
561   \param len the length of the buf
562   \param mask the CIDR found (AF_INET only)
563   \param family the address family to return (AF_INET or AF_INET6)
564   \return SWITCH_STATUS_SUCCESSS for success, otherwise failure
565 */
566 SWITCH_DECLARE(switch_status_t) switch_find_local_ip(_Out_opt_bytecapcount_(len)
567 													 char *buf, _In_ int len, _In_opt_ int *mask, _In_ int family);
568 
569 /*!
570   \brief find primary ip of the specified interface
571   \param buf the buffer to write the ip address found into
572   \param len the length of the buf
573   \param mask the CIDR found (AF_INET only)
574   \param ifname interface name to check
575   \param family the address family to return (AF_INET or AF_INET6)
576   \return SWITCH_STATUS_SUCCESSS for success, otherwise failure
577 */
578 SWITCH_DECLARE(switch_status_t) switch_find_interface_ip(_Out_opt_bytecapcount_(len)
579 													 char *buf, _In_ int len, _In_opt_ int *mask, _In_ const char *ifname, _In_ int family);
580 
581 /*!
582   \brief find the char representation of an ip adress
583   \param buf the buffer to write the ip adress found into
584   \param len the length of the buf
585   \param sa the struct sockaddr * to get the adress from
586   \param salen the length of sa
587   \return the ip adress string
588 */
589 SWITCH_DECLARE(char *) get_addr(char *buf, switch_size_t len, struct sockaddr *sa, socklen_t salen);
590 SWITCH_DECLARE(char *) get_addr6(char *buf, switch_size_t len, struct sockaddr_in6 *sa, socklen_t salen);
591 
592 SWITCH_DECLARE(int) get_addr_int(switch_sockaddr_t *sa);
593 SWITCH_DECLARE(int) switch_cmp_addr(switch_sockaddr_t *sa1, switch_sockaddr_t *sa2);
594 SWITCH_DECLARE(int) switch_cp_addr(switch_sockaddr_t *sa1, switch_sockaddr_t *sa2);
595 
596 /*!
597   \brief get the port number of an ip address
598   \param sa the struct sockaddr * to get the port from
599   \return the ip adress string
600 */
601 SWITCH_DECLARE(unsigned short) get_port(struct sockaddr *sa);
602 
603 /*!
604   \brief flags to be used with switch_build_uri()
605  */
606 	 enum switch_uri_flags {
607 		 SWITCH_URI_NUMERIC_HOST = 1,
608 		 SWITCH_URI_NUMERIC_PORT = 2,
609 		 SWITCH_URI_NO_SCOPE = 4
610 	 };
611 
612 /*!
613   \brief build a URI string from components
614   \param uri output string
615   \param size maximum size of output string (including trailing null)
616   \param scheme URI scheme
617   \param user user part or null if none
618   \param sa host address
619   \param flags logical OR-ed combination of flags from \ref switch_uri_flags
620   \return number of characters printed (not including the trailing null)
621  */
622 SWITCH_DECLARE(int) switch_build_uri(char *uri, switch_size_t size, const char *scheme, const char *user, const switch_sockaddr_t *sa, int flags);
623 
624 #define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35 || x == SWITCH_STATUS_INTR)
625 
626 
627 #ifdef _MSC_VER
628 
629 #define switch_errno() WSAGetLastError()
630 
switch_errno_is_break(int errcode)631 static inline int switch_errno_is_break(int errcode)
632 {
633 	return errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == WSAEINTR;
634 }
635 
636 #else
637 
638 #define switch_errno() errno
639 
switch_errno_is_break(int errcode)640 static inline int switch_errno_is_break(int errcode)
641 {
642   return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR || errcode == ETIMEDOUT;
643 }
644 
645 #endif
646 
647 
648 /*!
649   \brief Return a printable name of a switch_priority_t
650   \param priority the priority to get the name of
651   \return the printable form of the priority
652 */
653 SWITCH_DECLARE(const char *) switch_priority_name(switch_priority_t priority);
654 
655 /*!
656   \brief Return the RFC2833 character based on an event id
657   \param event the event id to convert
658   \return the character represented by the event or null for an invalid event
659 */
660 SWITCH_DECLARE(char) switch_rfc2833_to_char(int event);
661 
662 /*!
663   \brief Return the RFC2833 event based on an key character
664   \param key the charecter to encode
665   \return the event id for the specified character or -1 on an invalid input
666 */
667 SWITCH_DECLARE(unsigned char) switch_char_to_rfc2833(char key);
668 
669 /*!
670   \brief determine if a character is a valid DTMF key
671   \param key the key to test
672   \return TRUE or FALSE
673  */
674 #define is_dtmf(key)  ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119 || key == 70 || key == 102)
675 
676 #define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
677 #define end_of_p(_s) (*_s == '\0' ? _s : _s + strlen(_s) - 1)
678 /*!
679   \brief Test for the existance of a flag on an arbitary object
680   \param obj the object to test
681   \param flag the or'd list of flags to test
682   \return true value if the object has the flags defined
683 */
684 #define switch_test_flag(obj, flag) ((obj)->flags & flag)
685 
686 /*!
687   \brief Set a flag on an arbitrary object
688   \param obj the object to set the flags on
689   \param flag the or'd list of flags to set
690 */
691 #define switch_set_flag(obj, flag) (obj)->flags |= (flag)
692 
693 /*!
694   \brief Set a flag on an arbitrary object while locked
695   \param obj the object to set the flags on
696   \param flag the or'd list of flags to set
697 */
698 #define switch_set_flag_locked(obj, flag) assert((obj)->flag_mutex != NULL); \
699 switch_mutex_lock((obj)->flag_mutex);								\
700 (obj)->flags |= (flag);\
701 switch_mutex_unlock((obj)->flag_mutex);
702 
703 /*!
704   \brief Clear a flag on an arbitrary object
705   \param obj the object to test
706   \param flag the or'd list of flags to clear
707 */
708 #define switch_clear_flag_locked(obj, flag) switch_mutex_lock((obj)->flag_mutex); (obj)->flags &= ~(flag); switch_mutex_unlock((obj)->flag_mutex);
709 
710 /*!
711   \brief Clear a flag on an arbitrary object while locked
712   \param obj the object to test
713   \param flag the or'd list of flags to clear
714 */
715 #define switch_clear_flag(obj, flag) (obj)->flags &= ~(flag)
716 
717 /*!
718   \brief Copy flags from one arbitrary object to another
719   \param dest the object to copy the flags to
720   \param src the object to copy the flags from
721   \param flags the flags to copy
722 */
723 #define switch_copy_flags(dest, src, flags) (dest)->flags &= ~(flags);	(dest)->flags |= ((src)->flags & (flags))
724 
725 #define switch_set_string(_dst, _src) switch_copy_string(_dst, _src, sizeof(_dst))
726 
727 
switch_sanitize_number(char * number)728 static inline char *switch_sanitize_number(char *number)
729 {
730 	char *p = number, *q;
731 	char warp[] = "/:";
732 	int i;
733 
734 	switch_assert(number);
735 
736 	if (!(strchr(p, '/') || strchr(p, ':') || strchr(p, '@'))) {
737 		return number;
738 	}
739 
740 	while ((q = strrchr(p, '@')))
741 		*q = '\0';
742 
743 	for (i = 0; i < (int) strlen(warp); i++) {
744 		while (p && (q = strchr(p, warp[i])))
745 			p = q + 1;
746 	}
747 
748 	return p;
749 }
750 
switch_string_var_check(char * s,switch_bool_t disable)751 static inline switch_bool_t switch_string_var_check(char *s, switch_bool_t disable)
752 {
753 	char *p;
754 	char *dol = NULL;
755 
756 	for (p = s; p && *p; p++) {
757 		if (*p == '$') {
758 			dol = p;
759 		} else if (dol) {
760 			if (*p == '{') {
761 				if (disable) {
762 					*dol = '%';
763 					dol = NULL;
764 				} else {
765 					return SWITCH_TRUE;
766 				}
767 			} else if (*p != '\\') {
768 				dol = NULL;
769 			}
770 		}
771 	}
772 	return SWITCH_FALSE;
773 }
774 
775 
switch_string_var_check_const(const char * s)776 static inline switch_bool_t switch_string_var_check_const(const char *s)
777 {
778 	const char *p;
779 	int dol = 0;
780 
781 	for (p = s; p && *p; p++) {
782 		if (*p == '$') {
783 			dol = 1;
784 		} else if (dol) {
785 			if (*p == '{') {
786 				return SWITCH_TRUE;
787 			} else if (*p != '\\') {
788 				dol = 0;
789 			}
790 		}
791 	}
792 	return SWITCH_FALSE;
793 }
794 
switch_var_clean_string(char * s)795 static inline char *switch_var_clean_string(char *s)
796 {
797 	switch_string_var_check(s, SWITCH_TRUE);
798 	return s;
799 }
800 
switch_clean_string(char * s)801 static inline char *switch_clean_string(char *s)
802 {
803 	char *p;
804 	for (p = s; p && *p; p++) {
805 		uint8_t x = (uint8_t) * p;
806 		if ((x < 32) && x != '\n' && x != '\r') {
807 			*p = ' ';
808 		}
809 	}
810 
811 	return s;
812 }
813 
814 
switch_clean_name_string(char * s)815 static inline char *switch_clean_name_string(char *s)
816 {
817 	char *p;
818 	for (p = s; p && *p; p++) {
819 		uint8_t x = (uint8_t) * p;
820 		if ((x < 32) ||	x == '\'' || x == '"' || x == '<' || x == '>' || x == '\\' || x == ':' || x == '@' || x == '/') {
821 			*p = ' ';
822 		}
823 		if ( (p == s) && (*p == ' ') ) {
824 			s++;
825 		}
826 	}
827 
828 	return s;
829 }
830 
831 
832 
833 /*!
834   \brief Turn a string into a number (default if NULL)
835   \param nptr the string
836   \param dft the default
837   \return the number version of the string or the default
838 */
switch_safe_atoi(const char * nptr,int dft)839 static inline int switch_safe_atoi(const char *nptr, int dft)
840 {
841 	return nptr ? atoi(nptr) : dft;
842 }
843 
844 
845 /*!
846   \brief Free a pointer and set it to NULL unless it already is NULL
847   \param it the pointer
848 */
849 #define switch_safe_free(it) if (it) {free(it);it=NULL;}
850 
switch_safe_strdup(const char * it)851 static inline char *switch_safe_strdup(const char *it)
852 {
853 	if (it) {
854 		return strdup(it);
855 	}
856 
857 	return NULL;
858 }
859 
860 
861 #ifdef _MSC_VER
862 #pragma warning(disable:6011)
863 #endif
switch_lc_strdup(const char * it)864 static inline char *switch_lc_strdup(const char *it)
865 {
866 	char *dup;
867 	char *p;
868 
869 	if (it) {
870 		dup = strdup(it);
871 		for (p = dup; p && *p; p++) {
872 			*p = (char) switch_tolower(*p);
873 		}
874 		return dup;
875 	}
876 
877 	return NULL;
878 }
879 
880 
switch_uc_strdup(const char * it)881 static inline char *switch_uc_strdup(const char *it)
882 {
883 	char *dup;
884 	char *p;
885 
886 	if (it) {
887 		dup = strdup(it);
888 		for (p = dup; p && *p; p++) {
889 			*p = (char) switch_toupper(*p);
890 		}
891 		return dup;
892 	}
893 
894 	return NULL;
895 }
896 #ifdef _MSC_VER
897 #pragma warning(default:6011)
898 #endif
899 
900 
901 /*!
902   \brief Test if one string is inside another with extra case checking
903   \param s the inner string
904   \param q the big string
905   \return SWITCH_TRUE or SWITCH_FALSE
906 */
switch_strstr(char * s,char * q)907 static inline switch_bool_t switch_strstr(char *s, char *q)
908 {
909 	char *p, *S = NULL, *Q = NULL;
910 	switch_bool_t tf = SWITCH_FALSE;
911 
912 	if (!s || !q) {
913 		return SWITCH_FALSE;
914 	}
915 
916 	if (strstr(s, q)) {
917 		return SWITCH_TRUE;
918 	}
919 
920 	S = strdup(s);
921 
922 	switch_assert(S != NULL);
923 
924 	for (p = S; p && *p; p++) {
925 		*p = (char) switch_toupper(*p);
926 	}
927 
928 	if (strstr(S, q)) {
929 		tf = SWITCH_TRUE;
930 		goto done;
931 	}
932 
933 	Q = strdup(q);
934 	switch_assert(Q != NULL);
935 
936 	for (p = Q; p && *p; p++) {
937 		*p = (char) switch_toupper(*p);
938 	}
939 
940 	if (strstr(s, Q)) {
941 		tf = SWITCH_TRUE;
942 		goto done;
943 	}
944 
945 	if (strstr(S, Q)) {
946 		tf = SWITCH_TRUE;
947 		goto done;
948 	}
949 
950   done:
951 	switch_safe_free(S);
952 	switch_safe_free(Q);
953 
954 	return tf;
955 }
956 
957 
958 /*!
959   \brief Make a null string a blank string instead
960   \param s the string to test
961   \return the original string or blank string.
962 */
963 #define switch_str_nil(s) (s ? s : "")
964 
965 /*!
966   \brief Wait a desired number of microseconds and yield the CPU
967 */
968 #define switch_yield(ms) switch_sleep(ms);
969 
970 /*!
971   \brief Converts a string representation of a date into a switch_time_t
972   \param in the string
973   \return the epoch time in usec
974 */
975 SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in);
976 #define switch_time_from_sec(sec)   ((switch_time_t)(sec) * 1000000)
977 
978 /*!
979   \brief Declares a function designed to set a dynamic global string
980   \param fname the function name to declare
981   \param vname the name of the global pointer to modify with the new function
982 */
983 #define SWITCH_DECLARE_GLOBAL_STRING_FUNC(fname, vname) static void fname(const char *string) { if (!string) return;\
984 		if (vname) {free(vname); vname = NULL;}vname = strdup(string);} static void fname(const char *string)
985 
986 /*!
987   \brief Separate a string into an array based on a character delimiter
988   \param buf the string to parse
989   \param delim the character delimiter
990   \param array the array to split the values into
991   \param arraylen the max number of elements in the array
992   \return the number of elements added to the array
993 */
994 SWITCH_DECLARE(unsigned int) switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen);
995 SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen);
996 
997 
998 SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup);
999 SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str);
1000 SWITCH_DECLARE(char *) switch_strip_commas(char *in, char *out, switch_size_t len);
1001 SWITCH_DECLARE(char *) switch_strip_nonnumerics(char *in, char *out, switch_size_t len);
1002 SWITCH_DECLARE(char *) switch_separate_paren_args(char *str);
1003 SWITCH_DECLARE(const char *) switch_stristr(const char *instr, const char *str);
1004 SWITCH_DECLARE(switch_bool_t) switch_is_lan_addr(const char *ip);
1005 SWITCH_DECLARE(char *) switch_replace_char(char *str, char from, char to, switch_bool_t dup);
1006 SWITCH_DECLARE(switch_bool_t) switch_ast2regex(const char *pat, char *rbuf, size_t len);
1007 SWITCH_DECLARE(char *) switch_pool_strip_whitespace(switch_memory_pool_t *pool, const char *str);
1008 
1009 /*!
1010   \brief Escape a string by prefixing a list of characters with an escape character
1011   \param pool a memory pool to use
1012   \param in the string
1013   \param delim the list of characters to escape
1014   \param esc the escape character
1015   \return the escaped string
1016 */
1017 SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in, const char *delim, char esc);
1018 
1019 SWITCH_DECLARE(char *) switch_escape_string(const char *in, char *out, switch_size_t outlen);
1020 SWITCH_DECLARE(char *) switch_escape_string_pool(const char *in, switch_memory_pool_t *pool);
1021 
1022 /*!
1023   \brief Wait for a socket
1024   \param poll the pollfd to wait on
1025   \param ms the number of milliseconds to wait
1026   \return the requested condition
1027 */
1028 SWITCH_DECLARE(int) switch_socket_waitfor(switch_pollfd_t *poll, int ms);
1029 
1030 /*!
1031   \brief Create a pointer to the file name in a given file path eliminating the directory name
1032   \return the pointer to the next character after the final / or \\ characters
1033 */
1034 SWITCH_DECLARE(const char *) switch_cut_path(const char *in);
1035 
1036 SWITCH_DECLARE(char *) switch_string_replace(const char *string, const char *search, const char *replace);
1037 SWITCH_DECLARE(switch_status_t) switch_string_match(const char *string, size_t string_len, const char *search, size_t search_len);
1038 SWITCH_DECLARE(int) switch_strcasecmp_any(const char *str, ...);
1039 
1040 /*!
1041   \brief Quote shell argument
1042   \param string the string to quote (example: a ' b"' c)
1043   \return the quoted string (gives: 'a '\'' b"'\'' c' for unices, "a ' b ' c" for MS Windows), should be freed
1044 */
1045 SWITCH_DECLARE(char *) switch_util_quote_shell_arg(const char *string);
1046 
1047 /*!
1048   \brief Quote shell argument, allocating from pool if provided
1049   \param string the string to quote (example: a ' b"' c)
1050   \param pool a memory pool to use
1051   \return the quoted string (gives: 'a '\'' b"'\'' c' for unices, "a ' b ' c" for MS Windows), if pool not provided, returned value should be freed
1052 */
1053 SWITCH_DECLARE(char *) switch_util_quote_shell_arg_pool(const char *string, switch_memory_pool_t *pool);
1054 
1055 
1056 #define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)
1057 
1058 
switch_calc_bitrate(int w,int h,float quality,double fps)1059 static inline int32_t switch_calc_bitrate(int w, int h, float quality, double fps)
1060 {
1061     int r;
1062 
1063     if (quality == 0) {
1064         quality = 1;
1065     }
1066 
1067     /* KUSH GAUGE*/
1068 
1069     if (!fps) fps = 15;
1070 
1071     r = (int32_t)((double)(w * h * fps * quality) * 0.07) / 1000;
1072 
1073     if (!quality) r /= 2;
1074 
1075     if (quality < 0.0f) {
1076         r = (int) ((float)r * quality);
1077     }
1078 
1079     return r;
1080 
1081 }
1082 
switch_calc_fps(switch_fps_t * fpsP,float fps,int samplerate)1083 static inline void switch_calc_fps(switch_fps_t *fpsP, float fps, int samplerate)
1084 {
1085 	/*
1086 	  implicit/truncf() - leave us with equal-or-smaller ms and thus equal-or-bigger fps, which is better for quality (than roundf()).
1087 	  also equal-or-bigger fps is better for things like (int)fps
1088 	*/
1089 	fpsP->ms = (int)(1000.0f / fps);
1090 	fpsP->fps = 1000.0f / fpsP->ms;
1091 	fpsP->samples = (int)(samplerate / 1000 * fpsP->ms); // samplerate 99.99% is a factor of 1000, so we safe here with integer div by 1000
1092 	return;
1093 }
1094 #define switch_calc_video_fps(fpsP, fps) switch_calc_fps(fpsP, fps, 90000)
1095 
switch_parse_bandwidth_string(const char * bwv)1096 static inline int32_t switch_parse_bandwidth_string(const char *bwv)
1097 {
1098 	float bw = 0;
1099 
1100 	if (!bwv) return 0;
1101 
1102 	if (!strcasecmp(bwv, "auto")) {
1103 		return -1;
1104 	}
1105 
1106 	if ((bw = (float) atof(bwv))) {
1107 		if (bw < 0) return 0;
1108 
1109 		if (strstr(bwv, "KB")) {
1110 			bw *= 8;
1111 		} else if (strstr(bwv, "mb")) {
1112 			bw *= 1024;
1113 		} else if (strstr(bwv, "MB")) {
1114 			bw *= 8192;
1115 		}
1116 	}
1117 
1118 	return (int32_t) roundf(bw);
1119 }
1120 
switch_parse_cpu_string(const char * cpu)1121 static inline uint32_t switch_parse_cpu_string(const char *cpu)
1122 {
1123 	int cpu_count = switch_core_cpu_count();
1124 	int ncpu;
1125 
1126 	if (!cpu) return 1;
1127 
1128 	if (!strcasecmp(cpu, "auto")) {
1129 		if (cpu_count > 4) return 4;
1130 		if (cpu_count <= 2) return 1;
1131 
1132 		return (uint32_t)(cpu_count / 2);
1133 	}
1134 
1135 	if (!strncasecmp(cpu, "cpu/", 4)) { /* cpu/2 or cpu/2/<max>  */
1136 		const char *has_max = cpu;
1137 		float divisor;
1138 		int max = cpu_count;
1139 
1140 		cpu +=4;
1141 
1142 		has_max = strchr(cpu, '/');
1143 
1144 		if (has_max > cpu) {
1145 			max = atoi(has_max + 1);
1146 		}
1147 
1148 		divisor = (float)atof(cpu);
1149 
1150 		if (divisor <= 0) divisor = 1;
1151 
1152 		ncpu = (int)(cpu_count / divisor);
1153 
1154 		if (ncpu <= 0) return 1;
1155 
1156 		if (ncpu > max) return (uint32_t)max;
1157 
1158 		return (uint32_t)ncpu;
1159 	} else if (!strcasecmp(cpu, "cpu")) {
1160 		ncpu = cpu_count;
1161 	} else {
1162 		ncpu = atoi(cpu);
1163 
1164 		if (strrchr(cpu, '%')) {
1165 			ncpu = (int) (cpu_count * ((float)ncpu / 100));
1166 		}
1167 	}
1168 
1169 	if (ncpu > cpu_count) return (uint32_t)cpu_count;
1170 
1171 	if (ncpu <= 0) return 1;
1172 
1173 	return ncpu;
1174 }
1175 
switch_needs_url_encode(const char * s)1176 static inline int switch_needs_url_encode(const char *s)
1177 {
1178 	const char hex[] = "0123456789ABCDEF";
1179 	const char *p, *e = end_of_p(s);
1180 
1181 
1182 	for(p = s; p && *p; p++) {
1183 		if (*p == '%' && e-p > 1) {
1184 			if (strchr(hex, *(p+1)) && strchr(hex, *(p+2))) {
1185 				p++;
1186 				continue;
1187 			}
1188 		}
1189 
1190 		if (strchr(SWITCH_URL_UNSAFE, *p)) {
1191 			return 1;
1192 		}
1193 	}
1194 
1195 	return 0;
1196 }
1197 
1198 SWITCH_DECLARE(char *) switch_url_encode_opt(const char *url, char *buf, size_t len, switch_bool_t double_encode);
1199 SWITCH_DECLARE(char *) switch_url_encode(const char *url, char *buf, size_t len);
1200 SWITCH_DECLARE(char *) switch_url_decode(char *s);
1201 
1202 SWITCH_DECLARE(char *) switch_core_url_encode_opt(switch_memory_pool_t *pool, const char *url, switch_bool_t double_encode);
1203 SWITCH_DECLARE(char *) switch_core_url_encode(switch_memory_pool_t *pool, const char *url);
1204 SWITCH_DECLARE(char *) switch_core_session_url_encode_opt(switch_core_session_t *session, const char *url, switch_bool_t double_encode);
1205 SWITCH_DECLARE(char *) switch_core_session_url_encode(switch_core_session_t *session, const char *url);
1206 
1207 
1208 SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to,
1209 												  const char *from,
1210 												  const char *headers,
1211 												  const char *body, const char *file, const char *convert_cmd, const char *convert_ext);
1212 SWITCH_DECLARE(char *) switch_find_end_paren(const char *s, char open, char close);
1213 
switch_separate_file_params(const char * file,char ** file_portion,char ** params_portion)1214 static inline void switch_separate_file_params(const char *file, char **file_portion, char **params_portion)
1215 {
1216 	char *e = NULL;
1217 	char *space = strdup(file);
1218 
1219 	switch_assert(space);
1220 	file = space;
1221 
1222 	*file_portion = NULL;
1223 	*params_portion = NULL;
1224 
1225 	while (*file == '{') {
1226 		e = switch_find_end_paren(file, '{', '}');
1227 		file = e + 1;
1228 		while(*file == ' ') file++;
1229 	}
1230 
1231 
1232 	if (e) {
1233 		*file_portion = strdup((char *)file);
1234 		*++e = '\0';
1235 		*params_portion = (char *)space;
1236 	} else {
1237 		*file_portion = (char *)space;
1238 	}
1239 
1240 	return;
1241 }
1242 
switch_is_file_path(const char * file)1243 static inline switch_bool_t switch_is_file_path(const char *file)
1244 {
1245 	const char *e;
1246 	int r;
1247 
1248 	if (zstr(file)) {
1249 		return SWITCH_FALSE;
1250 	}
1251 
1252 	while(*file == '{') {
1253 		if ((e = switch_find_end_paren(file, '{', '}'))) {
1254 			file = e + 1;
1255 			while(*file == ' ') file++;
1256 		}
1257 	}
1258 
1259 #ifdef WIN32
1260 	r = (*file == '\\' || *(file + 1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR));
1261 #else
1262 	r = ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR));
1263 #endif
1264 
1265 	return r ? SWITCH_TRUE : SWITCH_FALSE;
1266 }
1267 
1268 
switch_parse_audio_col(switch_audio_col_t col)1269 static inline const char *switch_parse_audio_col(switch_audio_col_t col)
1270 {
1271 	const char *field = NULL;
1272 
1273 	switch (col) {
1274 	case SWITCH_AUDIO_COL_STR_TITLE:
1275 		field = "title";
1276 		break;
1277 	case SWITCH_AUDIO_COL_STR_COMMENT:
1278 		field = "comment";
1279 		break;
1280 	case SWITCH_AUDIO_COL_STR_ARTIST:
1281 		field = "artist";
1282 		break;
1283 	case SWITCH_AUDIO_COL_STR_DATE:
1284 		field = "date";
1285 		break;
1286 	case SWITCH_AUDIO_COL_STR_SOFTWARE:
1287 		field = "software";
1288 		break;
1289 	case SWITCH_AUDIO_COL_STR_COPYRIGHT:
1290 		field = "copyright";
1291 		break;
1292 	default:
1293 		break;
1294 	}
1295 
1296 	return field;
1297 }
1298 
1299 SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp);
1300 SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, const char *name, switch_bool_t default_type,
1301 														   switch_memory_pool_t *pool);
1302 SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token);
1303 #define switch_network_list_add_cidr(_list, _cidr_str, _ok) switch_network_list_add_cidr_token(_list, _cidr_str, _ok, NULL)
1304 
1305 SWITCH_DECLARE(char *) switch_network_ipv4_mapped_ipv6_addr(const char* ip_str);
1306 SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok);
1307 
1308 SWITCH_DECLARE(switch_status_t) switch_network_list_add_cidr_port_token(switch_network_list_t *list, const char *cidr_str, switch_bool_t ok, const char *token, switch_network_port_range_p port);
1309 SWITCH_DECLARE(switch_status_t) switch_network_list_add_host_port_mask(switch_network_list_t *list, const char *host, const char *mask_str, switch_bool_t ok, switch_network_port_range_p port);
1310 
1311 SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_port_token(switch_network_list_t *list, uint32_t ip, int port, const char **token);
1312 SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_port_token(switch_network_list_t *list, ip_t ip, int port, const char **token);
1313 SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip_token(switch_network_list_t *list, uint32_t ip, const char **token);
1314 SWITCH_DECLARE(switch_bool_t) switch_network_list_validate_ip6_token(switch_network_list_t *list, ip_t ip, const char **token);
1315 #define switch_network_list_validate_ip(_list, _ip) switch_network_list_validate_ip_token(_list, _ip, NULL);
1316 
1317 #define switch_test_subnet(_ip, _net, _mask) (_mask ? ((_net & _mask) == (_ip & _mask)) : _net ? _net == _ip : 1)
1318 
1319 SWITCH_DECLARE(int) switch_inet_pton(int af, const char *src, void *dst);
1320 
1321 SWITCH_DECLARE(const char *) switch_dow_int2str(int val);
1322 SWITCH_DECLARE(int) switch_dow_str2int(const char *exp);
1323 SWITCH_DECLARE(switch_bool_t) switch_dow_cmp(const char *exp, int val);
1324 SWITCH_DECLARE(int) switch_number_cmp(const char *exp, int val);
1325 SWITCH_DECLARE(int) switch_tod_cmp(const char *exp, int val);
1326 
1327 SWITCH_DECLARE(int) switch_fulldate_cmp(const char *exp, switch_time_t *ts);
1328 SWITCH_DECLARE(void) switch_split_date(const char *exp, int *year, int *month, int *day);
1329 SWITCH_DECLARE(void) switch_split_time(const char *exp, int *hour, int *min, int *sec);
1330 
1331 /*!
1332   \brief Split a user@domain string as user and domain
1333   \param in the input string
1334   \param user the string to put the user into
1335   \param domain the string to put the domain into
1336   \return 1 if successfull
1337   \note Extended formats protocol:user@domain:port (Example: sip:toto@example.org)
1338 */
1339 SWITCH_DECLARE(int) switch_split_user_domain(char *in, char **user, char **domain);
1340 
1341 SWITCH_DECLARE(void *) switch_calloc(size_t nmemb, size_t size);
1342 
1343 #ifdef __clang_analyzer__
1344 #define calloc switch_calloc
1345 #endif
1346 
1347 /* malloc or DIE macros */
1348 #ifdef NDEBUG
1349 #define switch_malloc(ptr, len) (void)( (!!(ptr = malloc(len))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr )
1350 #define switch_zmalloc(ptr, len) (void)( (!!(ptr = calloc(1, (len)))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
1351 #if (_MSC_VER >= 1500)			// VC9+
1352 #define switch_strdup(ptr, s) (void)( (!!(ptr = _strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
1353 #else
1354 #define switch_strdup(ptr, s) (void)( (!!(ptr = strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
1355 #endif
1356 #else
1357 #if (_MSC_VER >= 1500)            // VC9+
1358 #define switch_malloc(ptr, len) (void)(assert(((ptr) = malloc((len)))),ptr);__analysis_assume( ptr )
1359 #define switch_zmalloc(ptr, len) (void)(assert((ptr = calloc(1, (len)))),ptr);__analysis_assume( ptr )
1360 #define switch_strdup(ptr, s) (void)(assert(((ptr) = _strdup(s))),ptr);__analysis_assume( ptr )
1361 #else
1362 #define switch_malloc(ptr, len) (void)(switch_assert(((ptr) = malloc((len)))),ptr)
1363 #define switch_zmalloc(ptr, len) (void)(switch_assert((ptr = calloc(1, (len)))),ptr)
1364 #define switch_strdup(ptr, s) (void)(switch_assert(((ptr) = strdup((s)))),ptr)
1365 #endif
1366 #endif
1367 
1368 #define DUMP_EVENT(_e) 	{char *event_str;switch_event_serialize(_e, &event_str, SWITCH_FALSE);switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "DUMP\n%s\n", event_str);free(event_str);}
1369 
1370 #ifndef _MSC_VER
1371 #define switch_inet_ntop inet_ntop
1372 #else
1373 SWITCH_DECLARE(const char *) switch_inet_ntop(int af, void const *src, char *dst, size_t size);
1374 #endif
1375 
1376 SWITCH_DECLARE(char *) switch_uuid_str(char *buf, switch_size_t len);
1377 SWITCH_DECLARE(char *) switch_format_number(const char *num);
1378 
1379 SWITCH_DECLARE(unsigned int) switch_atoui(const char *nptr);
1380 SWITCH_DECLARE(unsigned long) switch_atoul(const char *nptr);
1381 
1382 /**
1383  * Portable version of strerror_r(), work around for the incompatible
1384  * return type of GNU and XSI variants.
1385  * \param[in]	errnum	Error number
1386  * \param[both]	buf	Buffer for error message
1387  * \param[in]	buflen	Size of message buffer
1388  * \return	Pointer to message buffer, returning error message or "Unknown error xxx" if none found
1389  */
1390 SWITCH_DECLARE(char *) switch_strerror_r(int errnum, char *buf, switch_size_t buflen);
1391 SWITCH_DECLARE(int) switch_wait_sock(switch_os_socket_t sock, uint32_t ms, switch_poll_t flags);
1392 SWITCH_DECLARE(int) switch_wait_socklist(switch_waitlist_t *waitlist, uint32_t len, uint32_t ms);
1393 
1394 typedef struct switch_http_request_s {
1395 	const char *method;        /* GET POST PUT DELETE OPTIONS PATCH HEAD */
1396 	const char *uri;
1397 	const char *qs;            /* query string*/
1398 	const char *host;
1399 	switch_port_t port;
1400 	const char *from;
1401 	const char *user_agent;
1402 	const char *referer;
1403 	const char *user;
1404 	switch_bool_t keepalive;
1405 	const char *content_type;
1406 	switch_size_t content_length;
1407 	switch_size_t bytes_header;
1408 	switch_size_t bytes_read;
1409 	switch_size_t bytes_buffered;
1410 	switch_event_t *headers;
1411 	void *user_data;           /* private user data */
1412 
1413 	/* private members used by the parser internally */
1414 	char *_buffer;
1415 	switch_bool_t _destroy_headers;
1416 } switch_http_request_t;
1417 
1418 /**
1419  * parse http headers in a buffer
1420  * return status of success or not
1421  * \param[in]	buffer the buffer start from the very begining of the http request, e.g. 'GET '
1422  * \param[in]	datalen the buffer length
1423  * \param[out]	the http request pointer or null, need destroy later if got non-NULL pointer
1424  * \return	SWITCH_STATUS_SUCCESS | SWITCH_STATUS_FALSE
1425  */
1426 SWITCH_DECLARE(switch_status_t) switch_http_parse_header(char *buffer, uint32_t datalen, switch_http_request_t *request);
1427 SWITCH_DECLARE(void) switch_http_free_request(switch_http_request_t *request);
1428 SWITCH_DECLARE(void) switch_http_dump_request(switch_http_request_t *request);
1429 /**
1430  * parse http query string
1431  * \param[in]	request the http request object
1432  * \param[in]	qs the query string buffer
1433  *
1434  * qs buffer will be modified, so be sure to dup the qs before passing into this function if you want to keep the original string untouched
1435  * if qs is NULL, the it will parse request->qs, request->qs will be duplicated before parse to avoid being modified
1436  */
1437 
1438 SWITCH_DECLARE(void) switch_http_parse_qs(switch_http_request_t *request, char *qs);
1439 
1440 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_free(switch_frame_buffer_t *fb, switch_frame_t **frameP);
1441 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_dup(switch_frame_buffer_t *fb, switch_frame_t *orig, switch_frame_t **clone);
1442 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_destroy(switch_frame_buffer_t **fbP);
1443 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_create(switch_frame_buffer_t **fbP, switch_size_t qlen);
1444 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_push(switch_frame_buffer_t *fb, void *ptr);
1445 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_trypush(switch_frame_buffer_t *fb, void *ptr);
1446 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_pop(switch_frame_buffer_t *fb, void **ptr);
1447 SWITCH_DECLARE(switch_status_t) switch_frame_buffer_trypop(switch_frame_buffer_t *fb, void **ptr);
1448 SWITCH_DECLARE(int) switch_frame_buffer_size(switch_frame_buffer_t *fb);
1449 
1450 typedef struct {
1451 	int64_t userms;
1452 	int64_t kernelms;
1453 } switch_cputime;
1454 /**
1455 / Return used CPU time in this process for user and kernel code
1456 **/
1457 SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t);
1458 
1459 SWITCH_DECLARE(char *)switch_html_strip(const char *str);
1460 
1461 SWITCH_DECLARE(unsigned long) switch_getpid(void);
1462 
1463 SWITCH_END_EXTERN_C
1464 #endif
1465 /* For Emacs:
1466  * Local Variables:
1467  * mode:c
1468  * indent-tabs-mode:t
1469  * tab-width:4
1470  * c-basic-offset:4
1471  * End:
1472  * For VIM:
1473  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
1474  */
1475