blob: f7e72eb96fe42247a91ee39627ee03a0ccb08c2b [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00005 *
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
Benny Prijonoa7944bb2005-11-21 17:01:50 +000021#include <pj/pool.h>
22
Benny Prijono9033e312005-11-21 02:08:39 +000023PJ_IDEF(pj_str_t) pj_str(char *str)
24{
25 pj_str_t dst;
26 dst.ptr = str;
Benny Prijono5a9091c2006-02-14 20:59:53 +000027 dst.slen = str ? pj_ansi_strlen(str) : 0;
Benny Prijono9033e312005-11-21 02:08:39 +000028 return dst;
29}
30
31PJ_IDEF(pj_str_t*) pj_strdup(pj_pool_t *pool,
32 pj_str_t *dst,
33 const pj_str_t *src)
34{
Benny Prijono7764f172009-06-04 22:08:16 +000035 /* Without this, destination will be corrupted */
36 if (dst == src)
37 return dst;
38
Benny Prijono9033e312005-11-21 02:08:39 +000039 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
47PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,
48 pj_str_t *dst,
49 const pj_str_t *src)
50{
Benny Prijono942452b2006-03-02 21:12:28 +000051 dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);
Benny Prijono9033e312005-11-21 02:08:39 +000052 if (src->slen) {
Benny Prijono9033e312005-11-21 02:08:39 +000053 pj_memcpy(dst->ptr, src->ptr, src->slen);
Benny Prijono9033e312005-11-21 02:08:39 +000054 }
55 dst->slen = src->slen;
56 dst->ptr[dst->slen] = '\0';
57 return dst;
58}
59
60PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,
61 pj_str_t *dst,
62 const char *src)
63{
Benny Prijono5a9091c2006-02-14 20:59:53 +000064 dst->slen = src ? pj_ansi_strlen(src) : 0;
Benny Prijono9033e312005-11-21 02:08:39 +000065 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
Benny Prijono942452b2006-03-02 21:12:28 +000074PJ_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}
Benny Prijono9033e312005-11-21 02:08:39 +000086
87PJ_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
94PJ_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
101PJ_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
109PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
110{
Benny Prijono5a9091c2006-02-14 20:59:53 +0000111 dst->slen = src ? pj_ansi_strlen(src) : 0;
Benny Prijono9033e312005-11-21 02:08:39 +0000112 if (dst->slen > 0)
113 pj_memcpy(dst->ptr, src, dst->slen);
114 return dst;
115}
116
117PJ_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
126PJ_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
141PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
142{
Benny Prijono18a051b2007-06-28 00:50:10 +0000143 if (str1->slen == 0) {
144 return str2->slen==0 ? 0 : -1;
145 } else if (str2->slen == 0) {
146 return 1;
Benny Prijono9033e312005-11-21 02:08:39 +0000147 } else {
Benny Prijono18a051b2007-06-28 00:50:10 +0000148 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 }
Benny Prijono9033e312005-11-21 02:08:39 +0000156 }
157}
158
159PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2,
160 pj_size_t len)
161{
Benny Prijono18a051b2007-06-28 00:50:10 +0000162 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);
Benny Prijono9033e312005-11-21 02:08:39 +0000177}
178
179PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
180 pj_size_t len)
181{
Benny Prijono18a051b2007-06-28 00:50:10 +0000182 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);
Benny Prijono9033e312005-11-21 02:08:39 +0000192}
193
194PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
195{
Benny Prijono18a051b2007-06-28 00:50:10 +0000196 pj_str_t copy2;
197
198 if (str2) {
199 copy2.ptr = (char*)str2;
200 copy2.slen = pj_ansi_strlen(str2);
201 } else {
Benny Prijono337fb5e2007-10-26 09:02:28 +0000202 copy2.ptr = NULL;
Benny Prijono18a051b2007-06-28 00:50:10 +0000203 copy2.slen = 0;
204 }
205
206 return pj_strcmp(str1, &copy2);
Benny Prijono9033e312005-11-21 02:08:39 +0000207}
208
209PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
210{
Benny Prijono18a051b2007-06-28 00:50:10 +0000211 if (str1->slen == 0) {
212 return str2->slen==0 ? 0 : -1;
213 } else if (str2->slen == 0) {
214 return 1;
Benny Prijono9033e312005-11-21 02:08:39 +0000215 } else {
Benny Prijono18a051b2007-06-28 00:50:10 +0000216 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 }
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000224 }
225}
226
Benny Prijonodcf29962006-03-23 18:03:40 +0000227#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000228PJ_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
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000261PJ_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) {
Benny Prijono8220f902006-01-09 17:20:59 +0000266 return (len < str2->slen) ? -1 : 1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000267 } 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;
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000272 while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000273 ++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)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000279 return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000280 else if (len==2)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000281 return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000282 else if (len==1)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000283 return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000284#else
285 else if (len==3)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000286 return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000287 else if (len==2)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000288 return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000289 else if (len==1)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000290 return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000291#endif
292 else
293 return 0;
Benny Prijono9033e312005-11-21 02:08:39 +0000294 }
295}
Benny Prijonodcf29962006-03-23 18:03:40 +0000296#endif /* PJ_HAS_STRICMP_ALNUM */
Benny Prijono9033e312005-11-21 02:08:39 +0000297
298PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
299{
Benny Prijono18a051b2007-06-28 00:50:10 +0000300 pj_str_t copy2;
301
302 if (str2) {
303 copy2.ptr = (char*)str2;
304 copy2.slen = pj_ansi_strlen(str2);
305 } else {
Benny Prijono337fb5e2007-10-26 09:02:28 +0000306 copy2.ptr = NULL;
Benny Prijono18a051b2007-06-28 00:50:10 +0000307 copy2.slen = 0;
308 }
309
310 return pj_stricmp(str1, &copy2);
Benny Prijono9033e312005-11-21 02:08:39 +0000311}
312
313PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
314 pj_size_t len)
315{
Benny Prijono18a051b2007-06-28 00:50:10 +0000316 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);
Benny Prijono9033e312005-11-21 02:08:39 +0000331}
332
333PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2,
334 pj_size_t len)
335{
Benny Prijono18a051b2007-06-28 00:50:10 +0000336 pj_str_t copy2;
Benny Prijono8220f902006-01-09 17:20:59 +0000337
Benny Prijono18a051b2007-06-28 00:50:10 +0000338 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);
Benny Prijono9033e312005-11-21 02:08:39 +0000346}
347
348PJ_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
Benny Prijono5a9091c2006-02-14 20:59:53 +0000356PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)
357{
Benny Prijono18a051b2007-06-28 00:50:10 +0000358 unsigned len = str? pj_ansi_strlen(str) : 0;
Benny Prijono5a9091c2006-02-14 20:59:53 +0000359 if (len) {
360 pj_memcpy(dst->ptr + dst->slen, str, len);
361 dst->slen += len;
362 }
363}
364
Benny Prijono9033e312005-11-21 02:08:39 +0000365PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )
366{
367 pj_strltrim(str);
368 pj_strrtrim(str);
369 return str;
370}
371