blob: 1dcce8d6e09ba409777d922a9fa7608b3585c6fd [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{
35 if (src->slen) {
36 dst->ptr = (char*)pj_pool_alloc(pool, src->slen);
37 pj_memcpy(dst->ptr, src->ptr, src->slen);
38 }
39 dst->slen = src->slen;
40 return dst;
41}
42
43PJ_IDEF(pj_str_t*) pj_strdup_with_null( pj_pool_t *pool,
44 pj_str_t *dst,
45 const pj_str_t *src)
46{
Benny Prijono942452b2006-03-02 21:12:28 +000047 dst->ptr = (char*)pj_pool_alloc(pool, src->slen+1);
Benny Prijono9033e312005-11-21 02:08:39 +000048 if (src->slen) {
Benny Prijono9033e312005-11-21 02:08:39 +000049 pj_memcpy(dst->ptr, src->ptr, src->slen);
Benny Prijono9033e312005-11-21 02:08:39 +000050 }
51 dst->slen = src->slen;
52 dst->ptr[dst->slen] = '\0';
53 return dst;
54}
55
56PJ_IDEF(pj_str_t*) pj_strdup2(pj_pool_t *pool,
57 pj_str_t *dst,
58 const char *src)
59{
Benny Prijono5a9091c2006-02-14 20:59:53 +000060 dst->slen = src ? pj_ansi_strlen(src) : 0;
Benny Prijono9033e312005-11-21 02:08:39 +000061 if (dst->slen) {
62 dst->ptr = (char*)pj_pool_alloc(pool, dst->slen);
63 pj_memcpy(dst->ptr, src, dst->slen);
64 } else {
65 dst->ptr = NULL;
66 }
67 return dst;
68}
69
Benny Prijono942452b2006-03-02 21:12:28 +000070PJ_IDEF(pj_str_t*) pj_strdup2_with_null( pj_pool_t *pool,
71 pj_str_t *dst,
72 const char *src)
73{
74 dst->slen = src ? pj_ansi_strlen(src) : 0;
75 dst->ptr = (char*)pj_pool_alloc(pool, dst->slen+1);
76 if (dst->slen) {
77 pj_memcpy(dst->ptr, src, dst->slen);
78 }
79 dst->ptr[dst->slen] = '\0';
80 return dst;
81}
Benny Prijono9033e312005-11-21 02:08:39 +000082
83PJ_IDEF(pj_str_t) pj_strdup3(pj_pool_t *pool, const char *src)
84{
85 pj_str_t temp;
86 pj_strdup2(pool, &temp, src);
87 return temp;
88}
89
90PJ_IDEF(pj_str_t*) pj_strassign( pj_str_t *dst, pj_str_t *src )
91{
92 dst->ptr = src->ptr;
93 dst->slen = src->slen;
94 return dst;
95}
96
97PJ_IDEF(pj_str_t*) pj_strcpy(pj_str_t *dst, const pj_str_t *src)
98{
99 dst->slen = src->slen;
100 if (src->slen > 0)
101 pj_memcpy(dst->ptr, src->ptr, src->slen);
102 return dst;
103}
104
105PJ_IDEF(pj_str_t*) pj_strcpy2(pj_str_t *dst, const char *src)
106{
Benny Prijono5a9091c2006-02-14 20:59:53 +0000107 dst->slen = src ? pj_ansi_strlen(src) : 0;
Benny Prijono9033e312005-11-21 02:08:39 +0000108 if (dst->slen > 0)
109 pj_memcpy(dst->ptr, src, dst->slen);
110 return dst;
111}
112
113PJ_IDEF(pj_str_t*) pj_strncpy( pj_str_t *dst, const pj_str_t *src,
114 pj_ssize_t max)
115{
116 if (max > src->slen) max = src->slen;
117 pj_memcpy(dst->ptr, src->ptr, max);
118 dst->slen = max;
119 return dst;
120}
121
122PJ_IDEF(pj_str_t*) pj_strncpy_with_null( pj_str_t *dst, const pj_str_t *src,
123 pj_ssize_t max)
124{
125 if (max <= src->slen)
126 max = max-1;
127 else
128 max = src->slen;
129
130 pj_memcpy(dst->ptr, src->ptr, max);
131 dst->ptr[max] = '\0';
132 dst->slen = max;
133 return dst;
134}
135
136
137PJ_IDEF(int) pj_strcmp( const pj_str_t *str1, const pj_str_t *str2)
138{
Benny Prijono18a051b2007-06-28 00:50:10 +0000139 if (str1->slen == 0) {
140 return str2->slen==0 ? 0 : -1;
141 } else if (str2->slen == 0) {
142 return 1;
Benny Prijono9033e312005-11-21 02:08:39 +0000143 } else {
Benny Prijono18a051b2007-06-28 00:50:10 +0000144 int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
145 int res = pj_memcmp(str1->ptr, str2->ptr, min);
146 if (res == 0) {
147 return (str1->slen < str2->slen) ? -1 :
148 (str1->slen == str2->slen ? 0 : 1);
149 } else {
150 return res;
151 }
Benny Prijono9033e312005-11-21 02:08:39 +0000152 }
153}
154
155PJ_IDEF(int) pj_strncmp( const pj_str_t *str1, const pj_str_t *str2,
156 pj_size_t len)
157{
Benny Prijono18a051b2007-06-28 00:50:10 +0000158 pj_str_t copy1, copy2;
159
160 if (len < (unsigned)str1->slen) {
161 copy1.ptr = str1->ptr;
162 copy1.slen = len;
163 str1 = &copy1;
164 }
165
166 if (len < (unsigned)str2->slen) {
167 copy2.ptr = str2->ptr;
168 copy2.slen = len;
169 str2 = &copy2;
170 }
171
172 return pj_strcmp(str1, str2);
Benny Prijono9033e312005-11-21 02:08:39 +0000173}
174
175PJ_IDEF(int) pj_strncmp2( const pj_str_t *str1, const char *str2,
176 pj_size_t len)
177{
Benny Prijono18a051b2007-06-28 00:50:10 +0000178 pj_str_t copy2;
179
180 if (str2) {
181 copy2.ptr = (char*)str2;
182 copy2.slen = pj_ansi_strlen(str2);
183 } else {
184 copy2.slen = 0;
185 }
186
187 return pj_strncmp(str1, &copy2, len);
Benny Prijono9033e312005-11-21 02:08:39 +0000188}
189
190PJ_IDEF(int) pj_strcmp2( const pj_str_t *str1, const char *str2 )
191{
Benny Prijono18a051b2007-06-28 00:50:10 +0000192 pj_str_t copy2;
193
194 if (str2) {
195 copy2.ptr = (char*)str2;
196 copy2.slen = pj_ansi_strlen(str2);
197 } else {
Benny Prijono337fb5e2007-10-26 09:02:28 +0000198 copy2.ptr = NULL;
Benny Prijono18a051b2007-06-28 00:50:10 +0000199 copy2.slen = 0;
200 }
201
202 return pj_strcmp(str1, &copy2);
Benny Prijono9033e312005-11-21 02:08:39 +0000203}
204
205PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
206{
Benny Prijono18a051b2007-06-28 00:50:10 +0000207 if (str1->slen == 0) {
208 return str2->slen==0 ? 0 : -1;
209 } else if (str2->slen == 0) {
210 return 1;
Benny Prijono9033e312005-11-21 02:08:39 +0000211 } else {
Benny Prijono18a051b2007-06-28 00:50:10 +0000212 int min = (str1->slen < str2->slen)? str1->slen : str2->slen;
213 int res = pj_ansi_strnicmp(str1->ptr, str2->ptr, min);
214 if (res == 0) {
215 return (str1->slen < str2->slen) ? -1 :
216 (str1->slen == str2->slen ? 0 : 1);
217 } else {
218 return res;
219 }
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000220 }
221}
222
Benny Prijonodcf29962006-03-23 18:03:40 +0000223#if defined(PJ_HAS_STRICMP_ALNUM) && PJ_HAS_STRICMP_ALNUM!=0
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000224PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,
225 int len)
226{
227 if (len==0)
228 return 0;
229 else {
230 register const pj_uint32_t *p1 = (pj_uint32_t*)str1,
231 *p2 = (pj_uint32_t*)str2;
232 while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
233 ++p1, ++p2, len-=4;
234
235 if (len > 3)
236 return -1;
237#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
238 else if (len==3)
239 return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
240 else if (len==2)
241 return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
242 else if (len==1)
243 return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
244#else
245 else if (len==3)
246 return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
247 else if (len==2)
248 return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
249 else if (len==1)
250 return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
251#endif
252 else
253 return 0;
254 }
255}
256
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000257PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
258{
259 register int len = str1->slen;
260
261 if (len != str2->slen) {
Benny Prijono8220f902006-01-09 17:20:59 +0000262 return (len < str2->slen) ? -1 : 1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000263 } else if (len == 0) {
264 return 0;
265 } else {
266 register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr,
267 *p2 = (pj_uint32_t*)str2->ptr;
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000268 while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000269 ++p1, ++p2, len-=4;
270
271 if (len > 3)
272 return -1;
273#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
274 else if (len==3)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000275 return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000276 else if (len==2)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000277 return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000278 else if (len==1)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000279 return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000280#else
281 else if (len==3)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000282 return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000283 else if (len==2)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000284 return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000285 else if (len==1)
Benny Prijonocec5f4a2005-11-22 23:51:50 +0000286 return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000287#endif
288 else
289 return 0;
Benny Prijono9033e312005-11-21 02:08:39 +0000290 }
291}
Benny Prijonodcf29962006-03-23 18:03:40 +0000292#endif /* PJ_HAS_STRICMP_ALNUM */
Benny Prijono9033e312005-11-21 02:08:39 +0000293
294PJ_IDEF(int) pj_stricmp2( const pj_str_t *str1, const char *str2)
295{
Benny Prijono18a051b2007-06-28 00:50:10 +0000296 pj_str_t copy2;
297
298 if (str2) {
299 copy2.ptr = (char*)str2;
300 copy2.slen = pj_ansi_strlen(str2);
301 } else {
Benny Prijono337fb5e2007-10-26 09:02:28 +0000302 copy2.ptr = NULL;
Benny Prijono18a051b2007-06-28 00:50:10 +0000303 copy2.slen = 0;
304 }
305
306 return pj_stricmp(str1, &copy2);
Benny Prijono9033e312005-11-21 02:08:39 +0000307}
308
309PJ_IDEF(int) pj_strnicmp( const pj_str_t *str1, const pj_str_t *str2,
310 pj_size_t len)
311{
Benny Prijono18a051b2007-06-28 00:50:10 +0000312 pj_str_t copy1, copy2;
313
314 if (len < (unsigned)str1->slen) {
315 copy1.ptr = str1->ptr;
316 copy1.slen = len;
317 str1 = &copy1;
318 }
319
320 if (len < (unsigned)str2->slen) {
321 copy2.ptr = str2->ptr;
322 copy2.slen = len;
323 str2 = &copy2;
324 }
325
326 return pj_stricmp(str1, str2);
Benny Prijono9033e312005-11-21 02:08:39 +0000327}
328
329PJ_IDEF(int) pj_strnicmp2( const pj_str_t *str1, const char *str2,
330 pj_size_t len)
331{
Benny Prijono18a051b2007-06-28 00:50:10 +0000332 pj_str_t copy2;
Benny Prijono8220f902006-01-09 17:20:59 +0000333
Benny Prijono18a051b2007-06-28 00:50:10 +0000334 if (str2) {
335 copy2.ptr = (char*)str2;
336 copy2.slen = pj_ansi_strlen(str2);
337 } else {
338 copy2.slen = 0;
339 }
340
341 return pj_strnicmp(str1, &copy2, len);
Benny Prijono9033e312005-11-21 02:08:39 +0000342}
343
344PJ_IDEF(void) pj_strcat(pj_str_t *dst, const pj_str_t *src)
345{
346 if (src->slen) {
347 pj_memcpy(dst->ptr + dst->slen, src->ptr, src->slen);
348 dst->slen += src->slen;
349 }
350}
351
Benny Prijono5a9091c2006-02-14 20:59:53 +0000352PJ_IDEF(void) pj_strcat2(pj_str_t *dst, const char *str)
353{
Benny Prijono18a051b2007-06-28 00:50:10 +0000354 unsigned len = str? pj_ansi_strlen(str) : 0;
Benny Prijono5a9091c2006-02-14 20:59:53 +0000355 if (len) {
356 pj_memcpy(dst->ptr + dst->slen, str, len);
357 dst->slen += len;
358 }
359}
360
Benny Prijono9033e312005-11-21 02:08:39 +0000361PJ_IDEF(pj_str_t*) pj_strtrim( pj_str_t *str )
362{
363 pj_strltrim(str);
364 pj_strrtrim(str);
365 return str;
366}
367