Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
[asterisk/asterisk.git] / res / pjproject / pjlib / include / pj / string_i.h
1 /* $Id$ */
2 /* 
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
19  */
20
21 #include <pj/pool.h>
22
23 PJ_IDEF(pj_str_t) pj_str(char *str)
24 {
25     pj_str_t dst;
26     dst.ptr = str;
27     dst.slen = str ? pj_ansi_strlen(str) : 0;
28     return dst;
29 }
30
31 PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,
32                               pj_str_t *dst,
33                               const pj_str_t *src)
34 {
35     /* Without this, destination will be corrupted */
36     if (dst == src)
37         return dst;
38
39     if (src->slen) {
40         dst->ptr = (char*)pj_pool_alloc(pool, src->slen);
41         pj_memcpy(dst->ptr, src->ptr, src->slen);
42     }
43     dst->slen = src->slen;
44     return dst;
45 }
46
47 PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,
48                                         pj_str_t *dst,
49                                         const pj_str_t *src)
50 {
51     dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);
52     if (src->slen) {
53         pj_memcpy(dst->ptr, src->ptr, src->slen);
54     }
55     dst->slen = src->slen;
56     dst->ptr[dst->slen] = '\0';
57     return dst;
58 }
59
60 PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,
61                               pj_str_t *dst,
62                               const char *src)
63 {
64     dst->slen = src ? pj_ansi_strlen(src) : 0;
65     if (dst->slen) {
66         dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);
67         pj_memcpy(dst->ptr, src, dst->slen);
68     } else {
69         dst->ptr = NULL;
70     }
71     return dst;
72 }
73
74 PJ_IDEF(pj_str_t*) pj_strdup2_with_null( pj_pool_t *pool,
75                                          pj_str_t *dst,
76                                          const char *src)
77 {
78     dst->slen = src ? pj_ansi_strlen(src) : 0;
79     dst->ptr = (char*)pj_pool_alloc(pool, dst->slen+1);
80     if (dst->slen) {
81         pj_memcpy(dst->ptr, src, dst->slen);
82     }
83     dst->ptr[dst->slen] = '\0';
84     return dst;
85 }
86
87 PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)
88 {
89     pj_str_t temp;
90     pj_strdup2(pool, &temp, src);
91     return temp;
92 }
93
94 PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )
95 {
96     dst->ptr = src->ptr;
97     dst->slen = src->slen;
98     return dst;
99 }
100
101 PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)
102 {
103     dst->slen = src->slen;
104     if (src->slen > 0)
105         pj_memcpy(dst->ptr, src->ptr, src->slen);
106     return dst;
107 }
108
109 PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
110 {
111     dst->slen = src ? pj_ansi_strlen(src) : 0;
112     if (dst->slen > 0)
113         pj_memcpy(dst->ptr, src, dst->slen);
114     return dst;
115 }
116
117 PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src, 
118                                pj_ssize_t max)
119 {
120     if (max > src->slen) max = src->slen;
121     pj_memcpy(dst->ptr, src->ptr, max);
122     dst->slen = max;
123     return dst;
124 }
125
126 PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,
127                                          pj_ssize_t max)
128 {
129     if (max <= src->slen)
130         max = max-1;
131     else
132         max = src->slen;
133
134     pj_memcpy(dst->ptr, src->ptr, max);
135     dst->ptr[max] = '\0';
136     dst->slen = max;
137     return dst;
138 }
139
140
141 PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
142 {
143     if (str1->slen == 0) {
144         return str2->slen==0 ? 0 : -1;
145     } else if (str2->slen == 0) {
146         return 1;
147     } else {
148         int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
149         int res = pj_memcmp(str1->ptr, str2->ptr, min);
150         if (res == 0) {
151             return (str1->slen < str2->slen) ? -1 :
152                     (str1->slen == str2->slen ? 0 : 1);
153         } else {
154             return res;
155         }
156     }
157 }
158
159 PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2, 
160                          pj_size_t len)
161 {
162     pj_str_t copy1, copy2;
163
164     if (len < (unsigned)str1->slen) {
165         copy1.ptr = str1->ptr;
166         copy1.slen = len;
167         str1 = &copy1;
168     }
169
170     if (len < (unsigned)str2->slen) {
171         copy2.ptr = str2->ptr;
172         copy2.slen = len;
173         str2 = &copy2;
174     }
175
176     return pj_strcmp(str1, str2);
177 }
178
179 PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2, 
180                           pj_size_t len)
181 {
182     pj_str_t copy2;
183
184     if (str2) {
185         copy2.ptr = (char*)str2;
186         copy2.slen = pj_ansi_strlen(str2);
187     } else {
188         copy2.slen = 0;
189     }
190
191     return pj_strncmp(str1, &copy2, len);
192 }
193
194 PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
195 {
196     pj_str_t copy2;
197
198     if (str2) {
199         copy2.ptr = (char*)str2;
200         copy2.slen = pj_ansi_strlen(str2);
201     } else {
202         copy2.ptr = NULL;
203         copy2.slen = 0;
204     }
205
206     return pj_strcmp(str1, &copy2);
207 }
208
209 PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
210 {
211     if (str1->slen == 0) {
212         return str2->slen==0 ? 0 : -1;
213     } else if (str2->slen == 0) {
214         return 1;
215     } else {
216         int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
217         int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);
218         if (res == 0) {
219             return (str1->slen < str2->slen) ? -1 :
220                     (str1->slen == str2->slen ? 0 : 1);
221         } else {
222             return res;
223         }
224     }
225 }
226
227 #if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
228 PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,
229                              int len)
230 {
231     if (len==0)
232         return 0;
233     else {
234         register const pj_uint32_t *p1 = (pj_uint32_t*)str1, 
235                                    *p2 = (pj_uint32_t*)str2;
236         while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
237             ++p1, ++p2, len-=4;
238
239         if (len > 3)
240             return -1;
241 #if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
242         else if (len==3)
243             return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
244         else if (len==2)
245             return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
246         else if (len==1)
247             return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
248 #else
249         else if (len==3)
250             return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
251         else if (len==2)
252             return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
253         else if (len==1)
254             return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
255 #endif
256         else 
257             return 0;
258     }
259 }
260
261 PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
262 {
263     register int len = str1->slen;
264
265     if (len != str2->slen) {
266         return (len < str2->slen) ? -1 : 1;
267     } else if (len == 0) {
268         return 0;
269     } else {
270         register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr, 
271                                    *p2 = (pj_uint32_t*)str2->ptr;
272         while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
273             ++p1, ++p2, len-=4;
274
275         if (len > 3)
276             return -1;
277 #if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
278         else if (len==3)
279             return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
280         else if (len==2)
281             return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
282         else if (len==1)
283             return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
284 #else
285         else if (len==3)
286             return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
287         else if (len==2)
288             return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
289         else if (len==1)
290             return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
291 #endif
292         else 
293             return 0;
294     }
295 }
296 #endif  /* PJ_HAS_STRICMP_ALNUM */
297
298 PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
299 {
300     pj_str_t copy2;
301
302     if (str2) {
303         copy2.ptr = (char*)str2;
304         copy2.slen = pj_ansi_strlen(str2);
305     } else {
306         copy2.ptr = NULL;
307         copy2.slen = 0;
308     }
309
310     return pj_stricmp(str1, &copy2);
311 }
312
313 PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2, 
314                           pj_size_t len)
315 {
316     pj_str_t copy1, copy2;
317
318     if (len < (unsigned)str1->slen) {
319         copy1.ptr = str1->ptr;
320         copy1.slen = len;
321         str1 = &copy1;
322     }
323
324     if (len < (unsigned)str2->slen) {
325         copy2.ptr = str2->ptr;
326         copy2.slen = len;
327         str2 = &copy2;
328     }
329
330     return pj_stricmp(str1, str2);
331 }
332
333 PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2, 
334                            pj_size_t len)
335 {
336     pj_str_t copy2;
337
338     if (str2) {
339         copy2.ptr = (char*)str2;
340         copy2.slen = pj_ansi_strlen(str2);
341     } else {
342         copy2.slen = 0;
343     }
344
345     return pj_strnicmp(str1, &copy2, len);
346 }
347
348 PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
349 {
350     if (src->slen) {
351         pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);
352         dst->slen += src->slen;
353     }
354 }
355
356 PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)
357 {
358     unsigned len = str? pj_ansi_strlen(str) : 0;
359     if (len) {
360         pj_memcpy(dst->ptr + dst->slen, str, len);
361         dst->slen += len;
362     }
363 }
364
365 PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )
366 {
367     pj_strltrim(str);
368     pj_strrtrim(str);
369     return str;
370 }
371