blob: 5610c90713bf7987c16e306fc1ac103ae0c0b37f [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $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#include <pj/string.h>
21#include <pj/assert.h>
22#include <pj/pool.h>
23#include <pj/ctype.h>
24#include <pj/rand.h>
25#include <pj/os.h>
26
27#if PJ_FUNCTIONS_ARE_INLINED==0
28# include <pj/string_i.h>
29#endif
30
31
32PJ_DEF(char*) pj_strstr(const pj_str_t *str, const pj_str_t *substr)
33{
34 const char *s, *ends;
35
36 /* Special case when substr is zero */
37 if (substr->slen == 0) {
38 return (char*)str->ptr;
39 }
40
41 s = str->ptr;
42 ends = str->ptr + str->slen - substr->slen;
43 for (; s<=ends; ++s) {
44 if (pj_ansi_strncmp(s, substr->ptr, substr->slen)==0)
45 return (char*)s;
46 }
47 return NULL;
48}
49
50
51PJ_DEF(char*) pj_stristr(const pj_str_t *str, const pj_str_t *substr)
52{
53 const char *s, *ends;
54
55 /* Special case when substr is zero */
56 if (substr->slen == 0) {
57 return (char*)str->ptr;
58 }
59
60 s = str->ptr;
61 ends = str->ptr + str->slen - substr->slen;
62 for (; s<=ends; ++s) {
63 if (pj_ansi_strnicmp(s, substr->ptr, substr->slen)==0)
64 return (char*)s;
65 }
66 return NULL;
67}
68
69
70PJ_DEF(pj_str_t*) pj_strltrim( pj_str_t *str )
71{
72 char *end = str->ptr + str->slen;
73 register char *p = str->ptr;
74 while (p < end && pj_isspace(*p))
75 ++p;
76 str->slen -= (p - str->ptr);
77 str->ptr = p;
78 return str;
79}
80
81PJ_DEF(pj_str_t*) pj_strrtrim( pj_str_t *str )
82{
83 char *end = str->ptr + str->slen;
84 register char *p = end - 1;
85 while (p >= str->ptr && pj_isspace(*p))
86 --p;
87 str->slen -= ((end - p) - 1);
88 return str;
89}
90
91PJ_DEF(char*) pj_create_random_string(char *str, pj_size_t len)
92{
93 unsigned i;
94 char *p = str;
95
96 PJ_CHECK_STACK();
97
98 for (i=0; i<len/8; ++i) {
99 pj_uint32_t val = pj_rand();
100 pj_val_to_hex_digit( (val & 0xFF000000) >> 24, p+0 );
101 pj_val_to_hex_digit( (val & 0x00FF0000) >> 16, p+2 );
102 pj_val_to_hex_digit( (val & 0x0000FF00) >> 8, p+4 );
103 pj_val_to_hex_digit( (val & 0x000000FF) >> 0, p+6 );
104 p += 8;
105 }
106 for (i=i * 8; i<len; ++i) {
107 *p++ = pj_hex_digits[ pj_rand() & 0x0F ];
108 }
109 return str;
110}
111
112PJ_DEF(long) pj_strtol(const pj_str_t *str)
113{
114 PJ_CHECK_STACK();
115
116 if (str->slen > 0 && (str->ptr[0] == '+' || str->ptr[0] == '-')) {
117 pj_str_t s;
118
119 s.ptr = str->ptr + 1;
120 s.slen = str->slen - 1;
121 return (str->ptr[0] == '-'? -(long)pj_strtoul(&s) : pj_strtoul(&s));
122 } else
123 return pj_strtoul(str);
124}
125
126PJ_DEF(unsigned long) pj_strtoul(const pj_str_t *str)
127{
128 unsigned long value;
129 unsigned i;
130
131 PJ_CHECK_STACK();
132
133 value = 0;
134 for (i=0; i<(unsigned)str->slen; ++i) {
135 if (!pj_isdigit(str->ptr[i]))
136 break;
137 value = value * 10 + (str->ptr[i] - '0');
138 }
139 return value;
140}
141
142PJ_DEF(unsigned long) pj_strtoul2(const pj_str_t *str, pj_str_t *endptr,
143 unsigned base)
144{
145 unsigned long value;
146 unsigned i;
147
148 PJ_CHECK_STACK();
149
150 value = 0;
151 if (base <= 10) {
152 for (i=0; i<(unsigned)str->slen; ++i) {
153 unsigned c = (str->ptr[i] - '0');
154 if (c >= base)
155 break;
156 value = value * base + c;
157 }
158 } else if (base == 16) {
159 for (i=0; i<(unsigned)str->slen; ++i) {
160 if (!pj_isxdigit(str->ptr[i]))
161 break;
162 value = value * 16 + pj_hex_digit_to_val(str->ptr[i]);
163 }
164 } else {
165 pj_assert(!"Unsupported base");
166 i = 0;
167 value = 0xFFFFFFFFUL;
168 }
169
170 if (endptr) {
171 endptr->ptr = str->ptr + i;
172 endptr->slen = str->slen - i;
173 }
174
175 return value;
176}
177
178PJ_DEF(int) pj_utoa(unsigned long val, char *buf)
179{
180 return pj_utoa_pad(val, buf, 0, 0);
181}
182
183PJ_DEF(int) pj_utoa_pad( unsigned long val, char *buf, int min_dig, int pad)
184{
185 char *p;
186 int len;
187
188 PJ_CHECK_STACK();
189
190 p = buf;
191 do {
192 unsigned long digval = (unsigned long) (val % 10);
193 val /= 10;
194 *p++ = (char) (digval + '0');
195 } while (val > 0);
196
197 len = (int)(p-buf);
198 while (len < min_dig) {
199 *p++ = (char)pad;
200 ++len;
201 }
202 *p-- = '\0';
203
204 do {
205 char temp = *p;
206 *p = *buf;
207 *buf = temp;
208 --p;
209 ++buf;
210 } while (buf < p);
211
212 return len;
213}
214
215