Bug 5961 - new RAND() function
[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 <netinet/in.h>
29 #include <arpa/inet.h>  /* we want to override inet_ntoa */
30 #include <netdb.h>
31 #include <limits.h>
32
33 #include "asterisk/lock.h"
34 #include "asterisk/time.h"
35 #include "asterisk/strings.h"
36
37 /*! \note
38  \verbatim
39    Note:
40    It is very important to use only unsigned variables to hold
41    bit flags, as otherwise you can fall prey to the compiler's
42    sign-extension antics if you try to use the top two bits in
43    your variable.
44
45    The flag macros below use a set of compiler tricks to verify
46    that the caller is using an "unsigned int" variable to hold
47    the flags, and nothing else. If the caller uses any other
48    type of variable, a warning message similar to this:
49
50    warning: comparison of distinct pointer types lacks cast
51    will be generated.
52
53    The "dummy" variable below is used to make these comparisons.
54
55    Also note that at -O2 or above, this type-safety checking
56    does _not_ produce any additional object code at all.
57  \endverbatim
58 */
59
60 extern unsigned int __unsigned_int_flags_dummy;
61
62 #define ast_test_flag(p,flag)           ({ \
63                                         typeof ((p)->flags) __p = (p)->flags; \
64                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
65                                         (void) (&__p == &__x); \
66                                         ((p)->flags & (flag)); \
67                                         })
68
69 #define ast_set_flag(p,flag)            do { \
70                                         typeof ((p)->flags) __p = (p)->flags; \
71                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
72                                         (void) (&__p == &__x); \
73                                         ((p)->flags |= (flag)); \
74                                         } while(0)
75
76 #define ast_clear_flag(p,flag)          do { \
77                                         typeof ((p)->flags) __p = (p)->flags; \
78                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
79                                         (void) (&__p == &__x); \
80                                         ((p)->flags &= ~(flag)); \
81                                         } while(0)
82
83 #define ast_copy_flags(dest,src,flagz)  do { \
84                                         typeof ((dest)->flags) __d = (dest)->flags; \
85                                         typeof ((src)->flags) __s = (src)->flags; \
86                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
87                                         (void) (&__d == &__x); \
88                                         (void) (&__s == &__x); \
89                                         (dest)->flags &= ~(flagz); \
90                                         (dest)->flags |= ((src)->flags & (flagz)); \
91                                         } while (0)
92
93 #define ast_set2_flag(p,value,flag)     do { \
94                                         typeof ((p)->flags) __p = (p)->flags; \
95                                         typeof (__unsigned_int_flags_dummy) __x = 0; \
96                                         (void) (&__p == &__x); \
97                                         if (value) \
98                                                 (p)->flags |= (flag); \
99                                         else \
100                                                 (p)->flags &= ~(flag); \
101                                         } while (0)
102
103 /* Non-type checking variations for non-unsigned int flags.  You
104    should only use non-unsigned int flags where required by 
105    protocol etc and if you know what you're doing :)  */
106 #define ast_test_flag_nonstd(p,flag)            ({ \
107                                         ((p)->flags & (flag)); \
108                                         })
109
110 #define ast_set_flag_nonstd(p,flag)             do { \
111                                         ((p)->flags |= (flag)); \
112                                         } while(0)
113
114 #define ast_clear_flag_nonstd(p,flag)           do { \
115                                         ((p)->flags &= ~(flag)); \
116                                         } while(0)
117
118 #define ast_copy_flags_nonstd(dest,src,flagz)   do { \
119                                         (dest)->flags &= ~(flagz); \
120                                         (dest)->flags |= ((src)->flags & (flagz)); \
121                                         } while (0)
122
123 #define ast_set2_flag_nonstd(p,value,flag)      do { \
124                                         if (value) \
125                                                 (p)->flags |= (flag); \
126                                         else \
127                                                 (p)->flags &= ~(flag); \
128                                         } while (0)
129
130 #define AST_FLAGS_ALL UINT_MAX
131
132 struct ast_flags {
133         unsigned int flags;
134 };
135
136 struct ast_hostent {
137         struct hostent hp;
138         char buf[1024];
139 };
140
141 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp);
142
143 /* ast_md5_hash 
144         \brief Produces MD5 hash based on input string */
145 void ast_md5_hash(char *output, char *input);
146
147 int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max);
148 int ast_base64decode(unsigned char *dst, const char *src, int max);
149
150 /*! ast_uri_encode
151         \brief Turn text string to URI-encoded %XX version 
152         At this point, we're converting from ISO-8859-x (8-bit), not UTF8
153         as in the SIP protocol spec 
154         If doreserved == 1 we will convert reserved characters also.
155         RFC 2396, section 2.4
156         outbuf needs to have more memory allocated than the instring
157         to have room for the expansion. Every char that is converted
158         is replaced by three ASCII characters.
159         \param string   String to be converted
160         \param outbuf   Resulting encoded string
161         \param buflen   Size of output buffer
162         \param doreserved       Convert reserved characters
163 */
164
165 char *ast_uri_encode(const char *string, char *outbuf, int buflen, int doreserved);
166
167 /*!     \brief Decode URI, URN, URL (overwrite string)
168         \param s        String to be decoded 
169  */
170 void ast_uri_decode(char *s);
171
172 static force_inline void ast_slinear_saturated_add(short *input, short *value)
173 {
174         int res;
175
176         res = (int) *input + *value;
177         if (res > 32767)
178                 *input = 32767;
179         else if (res < -32767)
180                 *input = -32767;
181         else
182                 *input = (short) res;
183 }
184         
185 static force_inline void ast_slinear_saturated_multiply(short *input, short *value)
186 {
187         int res;
188
189         res = (int) *input * *value;
190         if (res > 32767)
191                 *input = 32767;
192         else if (res < -32767)
193                 *input = -32767;
194         else
195                 *input = (short) res;
196 }
197
198 static force_inline void ast_slinear_saturated_divide(short *input, short *value)
199 {
200         *input /= *value;
201 }
202
203 int test_for_thread_safety(void);
204
205 const char *ast_inet_ntoa(char *buf, int bufsiz, struct in_addr ia);
206
207 #ifdef inet_ntoa
208 #undef inet_ntoa
209 #endif
210 #define inet_ntoa __dont__use__inet_ntoa__use__ast_inet_ntoa__instead__
211
212 int ast_utils_init(void);
213 int ast_wait_for_input(int fd, int ms);
214
215 /*! Compares the source address and port of two sockaddr_in */
216 static force_inline int inaddrcmp(const struct sockaddr_in *sin1, const struct sockaddr_in *sin2)
217 {
218         return ((sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) 
219                 || (sin1->sin_port != sin2->sin_port));
220 }
221
222 #define AST_STACKSIZE 256 * 1024
223 #define ast_pthread_create(a,b,c,d) ast_pthread_create_stack(a,b,c,d,0)
224 int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *data, size_t stacksize);
225
226 /*!
227         \brief Process a string to find and replace characters
228         \param start The string to analyze
229         \param find The character to find
230         \param replace_with The character that will replace the one we are looking for
231 */
232 char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
233
234 #ifndef HAVE_GETLOADAVG
235 int getloadavg(double *list, int nelem);
236 #endif
237
238 #ifdef linux
239 #define ast_random random
240 #else
241 long int ast_random(void);
242 #endif
243
244 #endif /* _ASTERISK_UTILS_H */