ed842e1b786fe365e14522fc9337a243b919e388
[asterisk/asterisk.git] / include / asterisk / utils.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  * \brief Utility functions
21  */
22
23 #ifndef _ASTERISK_UTILS_H
24 #define _ASTERISK_UTILS_H
25
26 #include "asterisk/compat.h"
27
28 #include <stdlib.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>  /* we want to override inet_ntoa */
31 #include <netdb.h>
32 #include <limits.h>
33
34 #include "asterisk/lock.h"
35 #include "asterisk/time.h"
36 #include "asterisk/strings.h"
37 #include "asterisk/logger.h"
38
39 /*! \note
40  \verbatim
41    Note:
42    It is very important to use only unsigned variables to hold
43    bit flags, as otherwise you can fall prey to the compiler's
44    sign-extension antics if you try to use the top two bits in
45    your variable.
46
47    The flag macros below use a set of compiler tricks to verify
48    that the caller is using an "unsigned int" variable to hold
49    the flags, and nothing else. If the caller uses any other
50    type of variable, a warning message similar to this:
51
52    warning: comparison of distinct pointer types lacks cast
53    will be generated.
54
55    The "dummy" variable below is used to make these comparisons.
56
57    Also note that at -O2 or above, this type-safety checking
58    does _not_ produce any additional object code at all.
59  \endverbatim
60 */
61
62 extern unsigned int __unsigned_int_flags_dummy;
63
64 #define ast_test_flag(p,flag)           ({ \
65                                         typeof ((p)->flags) __p = (p)->flags; \
66                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
67                                         (void) (&__p == &__x); \
68                                         ((p)->flags & (flag)); \
69                                         })
70
71 #define ast_set_flag(p,flag)            do { \
72                                         typeof ((p)->flags) __p = (p)->flags; \
73                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
74                                         (void) (&__p == &__x); \
75                                         ((p)->flags |= (flag)); \
76                                         } while(0)
77
78 #define ast_clear_flag(p,flag)          do { \
79                                         typeof ((p)->flags) __p = (p)->flags; \
80                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
81                                         (void) (&__p == &__x); \
82                                         ((p)->flags &= ~(flag)); \
83                                         } while(0)
84
85 #define ast_copy_flags(dest,src,flagz)  do { \
86                                         typeof ((dest)->flags) __d = (dest)->flags; \
87                                         typeof ((src)->flags) __s = (src)->flags; \
88                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
89                                         (void) (&__d == &__x); \
90                                         (void) (&__s == &__x); \
91                                         (dest)->flags &= ~(flagz); \
92                                         (dest)->flags |= ((src)->flags & (flagz)); \
93                                         } while (0)
94
95 #define ast_set2_flag(p,value,flag)     do { \
96                                         typeof ((p)->flags) __p = (p)->flags; \
97                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
98                                         (void) (&__p == &__x); \
99                                         if (value) \
100                                                 (p)->flags |= (flag); \
101                                         else \
102                                                 (p)->flags &= ~(flag); \
103                                         } while (0)
104
105 /* Non-type checking variations for non-unsigned int flags.  You
106    should only use non-unsigned int flags where required by 
107    protocol etc and if you know what you're doing :)  */
108 #define ast_test_flag_nonstd(p,flag)            ({ \
109                                         ((p)->flags & (flag)); \
110                                         })
111
112 #define ast_set_flag_nonstd(p,flag)             do { \
113                                         ((p)->flags |= (flag)); \
114                                         } while(0)
115
116 #define ast_clear_flag_nonstd(p,flag)           do { \
117                                         ((p)->flags &= ~(flag)); \
118                                         } while(0)
119
120 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
121                                         (dest)->flags &= ~(flagz); \
122                                         (dest)->flags |= ((src)->flags & (flagz)); \
123                                         } while (0)
124
125 #define ast_set2_flag_nonstd(p,value,flag)      do { \
126                                         if (value) \
127                                                 (p)->flags |= (flag); \
128                                         else \
129                                                 (p)->flags &= ~(flag); \
130                                         } while (0)
131
132 #define AST_FLAGS_ALL UINT_MAX
133
134 struct ast_flags {
135         unsigned int flags;
136 };
137
138 struct ast_hostent {
139         struct hostent hp;
140         char buf[1024];
141 };
142
143 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
144
145 /* ast_md5_hash 
146         \brief Produces MD5 hash based on input string */
147 void ast_md5_hash(char *output, char *input);
148
149 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
150 int ast_base64decode(unsigned char *dst, const char *src, int max);
151
152 /*! ast_uri_encode
153         \brief Turn text string to URI-encoded %XX version 
154         At this point, we're converting from ISO-8859-x (8-bit), not UTF8
155         as in the SIP protocol spec 
156         If doreserved == 1 we will convert reserved characters also.
157         RFC 2396, section 2.4
158         outbuf needs to have more memory allocated than the instring
159         to have room for the expansion. Every char that is converted
160         is replaced by three ASCII characters.
161         \param string   String to be converted
162         \param outbuf   Resulting encoded string
163         \param buflen   Size of output buffer
164         \param doreserved       Convert reserved characters
165 */
166
167 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
168
169 /*!     \brief Decode URI, URN, URL (overwrite string)
170         \param s        String to be decoded 
171  */
172 void ast_uri_decode(char *s);
173
174 static force_inline void ast_slinear_saturated_add(short *input, short *value)
175 {
176         int res;
177
178         res = (int) *input + *value;
179         if (res > 32767)
180                 *input = 32767;
181         else if (res < -32767)
182                 *input = -32767;
183         else
184                 *input = (short) res;
185 }
186         
187 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
188 {
189         int res;
190
191         res = (int) *input * *value;
192         if (res > 32767)
193                 *input = 32767;
194         else if (res < -32767)
195                 *input = -32767;
196         else
197                 *input = (short) res;
198 }
199
200 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
201 {
202         *input /= *value;
203 }
204
205 int test_for_thread_safety(void);
206
207 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
208
209 #ifdef inet_ntoa
210 #undef inet_ntoa
211 #endif
212 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
213
214 int ast_utils_init(void);
215 int ast_wait_for_input(int fd, int ms);
216
217 /*! Compares the source address and port of two sockaddr_in */
218 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
219 {
220         return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
221                 || (sin1->sin_port != sin2->sin_port));
222 }
223
224 #define AST_STACKSIZE 256 * 1024
225 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
226 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
227
228 /*!
229         \brief Process a string to find and replace characters
230         \param start The string to analyze
231         \param find The character to find
232         \param replace_with The character that will replace the one we are looking for
233 */
234 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
235
236 #ifndef HAVE_GETLOADAVG
237 int getloadavg(double *list, int nelem);
238 #endif
239
240 #ifdef linux
241 #define ast_random random
242 #else
243 long int ast_random(void);
244 #endif
245
246 /*!
247   \brief A wrapper for malloc()
248
249   ast_malloc() is a wrapper for malloc() that will generate an Asterisk log
250   message in the case that the allocation fails.
251
252   The argument and return value are the same as malloc()
253 */
254 #define ast_malloc(len) \
255         ({ \
256                 (_ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__)); \
257         })
258
259 AST_INLINE_API(
260 void *_ast_malloc(size_t len, const char *file, int lineno, const char *func),
261 {
262         void *p;
263
264         p = malloc(len);
265
266         if (!p)
267                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
268
269         return p;
270 }
271 )
272
273 /*!
274   \brief A wrapper for calloc()
275
276   ast_calloc() is a wrapper for calloc() that will generate an Asterisk log
277   message in the case that the allocation fails.
278
279   The arguments and return value are the same as calloc()
280 */
281 #define ast_calloc(num, len) \
282         ({ \
283                 (_ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)); \
284         })
285
286 AST_INLINE_API(
287 void *_ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func),
288 {
289         void *p;
290
291         p = calloc(num, len);
292
293         if (!p)
294                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
295
296         return p;
297 }
298 )
299
300 /*!
301   \brief A wrapper for realloc()
302
303   ast_realloc() is a wrapper for realloc() that will generate an Asterisk log
304   message in the case that the allocation fails.
305
306   The arguments and return value are the same as realloc()
307 */
308 #define ast_realloc(p, len) \
309         ({ \
310                 (_ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)); \
311         })
312
313 AST_INLINE_API(
314 void *_ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func),
315 {
316         void *newp;
317
318         newp = realloc(p, len);
319
320         if (!newp)
321                 ast_log(LOG_ERROR, "Memory Allocation Failure - '%d' bytes in function %s at line %d of %s\n", (int)len, func, lineno, file);
322
323         return newp;
324 }
325 )
326
327 /*!
328   \brief A wrapper for strdup()
329
330   ast_strdup() is a wrapper for strdup() that will generate an Asterisk log
331   message in the case that the allocation fails.
332
333   ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL
334   argument is provided, ast_strdup will return NULL without generating any
335   kind of error log message.
336
337   The argument and return value are the same as strdup()
338 */
339 #define ast_strdup(str) \
340         ({ \
341                 (_ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__)); \
342         })
343
344 AST_INLINE_API(
345 void *_ast_strdup(const char *str, const char *file, int lineno, const char *func),
346 {
347         char *newstr = NULL;
348
349         if (str) {
350                 newstr = strdup(str);
351
352                 if (!newstr)
353                         ast_log(LOG_ERROR, "Memory Allocation Failure - Could not duplicate '%s' in function %s at line %d of %s\n", str, func, lineno, file);
354         }
355
356         return newstr;
357 }
358 )
359
360 /*!
361   \brief A wrapper for strndup()
362
363   ast_strndup() is a wrapper for strndup() that will generate an Asterisk log
364   message in the case that the allocation fails.
365
366   ast_strndup(), unlike strndup(), can safely accept a NULL argument for the
367   string to duplicate. If a NULL argument is provided, ast_strdup will return  
368   NULL without generating any kind of error log message.
369
370   The arguments and return value are the same as strndup()
371 */
372 #define ast_strndup(str, len) \
373         ({ \
374                 (_ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__)); \
375         })
376
377 AST_INLINE_API(
378 void *_ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func),
379 {
380         char *newstr = NULL;
381
382         if (str) {
383                 newstr = strndup(str, len);
384
385                 if (!newstr)
386                         ast_log(LOG_ERROR, "Memory Allocation Failure - Could not duplicate '%d' bytes of '%s' in function %s at line %d of %s\n", (int)len, str, func, lineno, file);
387         }
388
389         return newstr;
390 }
391 )
392
393 #endif /* _ASTERISK_UTILS_H */