nginx 0.1.1
[nginx-catap.git] / src / core / ngx_string.c
blob32a4079a09b04021ba41c0191f47b010dc1cf283
2 /*
3 * Copyright (C) Igor Sysoev
4 */
7 #include <ngx_config.h>
8 #include <ngx_core.h>
11 u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n)
13 if (n == 0) {
14 return dst;
17 for (/* void */; --n; dst++, src++) {
18 *dst = *src;
20 if (*dst == '\0') {
21 return dst;
25 *dst = '\0';
27 return dst;
31 ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
33 if (n == 0) {
34 return 0;
37 n--;
39 for ( ;; ) {
40 if (s1[n] != s2[n]) {
41 return s1[n] - s2[n];
44 if (n == 0) {
45 return 0;
48 n--;
53 ngx_int_t ngx_atoi(u_char *line, size_t n)
55 ngx_int_t value;
57 if (n == 0) {
58 return NGX_ERROR;
61 for (value = 0; n--; line++) {
62 if (*line < '0' || *line > '9') {
63 return NGX_ERROR;
66 value = value * 10 + (*line - '0');
69 if (value < 0) {
70 return NGX_ERROR;
72 } else {
73 return value;
78 ngx_int_t ngx_hextoi(u_char *line, size_t n)
80 u_char ch;
81 ngx_int_t value;
83 if (n == 0) {
84 return NGX_ERROR;
87 for (value = 0; n--; line++) {
88 ch = *line;
90 if (ch >= '0' && ch <= '9') {
91 value = value * 16 + (ch - '0');
92 continue;
95 if (ch >= 'A' && ch <= 'F') {
96 value = value * 16 + (ch - 'A' + 10);
97 continue;
100 if (ch >= 'a' && ch <= 'f') {
101 value = value * 16 + (ch - 'a' + 10);
102 continue;
105 return NGX_ERROR;
108 if (value < 0) {
109 return NGX_ERROR;
111 } else {
112 return value;
117 void ngx_md5_text(u_char *text, u_char *md5)
119 int i;
120 static u_char hex[] = "0123456789abcdef";
122 for (i = 0; i < 16; i++) {
123 *text++ = hex[md5[i] >> 4];
124 *text++ = hex[md5[i] & 0xf];
127 *text = '\0';
131 void ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
133 u_char *d, *s;
134 size_t len;
135 static u_char basis64[] =
136 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
138 len = src->len;
139 s = src->data;
140 d = dst->data;
142 while (len > 2) {
143 *d++ = basis64[(s[0] >> 2) & 0x3f];
144 *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
145 *d++ = basis64[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
146 *d++ = basis64[s[2] & 0x3f];
148 s += 3;
149 len -= 3;
152 if (len) {
153 *d++ = basis64[(s[0] >> 2) & 0x3f];
155 if (len == 1) {
156 *d++ = basis64[(s[0] & 3) << 4];
157 *d++ = '=';
159 } else {
160 *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
161 *d++ = basis64[(s[1] & 0x0f) << 2];
164 *d++ = '=';
167 dst->len = d - dst->data;
171 ngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
173 size_t len;
174 u_char *d, *s;
175 static u_char basis64[] =
176 { 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
177 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
178 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
179 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
180 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
181 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
182 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
183 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
185 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
186 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
187 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
188 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
189 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
190 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
191 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
192 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77 };
194 for (len = 0; len < src->len; len++) {
195 if (src->data[len] == '=') {
196 break;
199 if (basis64[src->data[len]] == 77) {
200 return NGX_ERROR;
204 if (len % 4 == 1) {
205 return NGX_ERROR;
208 s = src->data;
209 d = dst->data;
211 while (len > 3) {
212 *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4);
213 *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2);
214 *d++ = (u_char) (basis64[s[2]] << 6 | basis64[s[3]]);
216 s += 4;
217 len -= 4;
220 if (len > 1) {
221 *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4);
224 if (len > 2) {
225 *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2);
228 dst->len = d - dst->data;
230 return NGX_OK;
234 ngx_int_t ngx_escape_uri(u_char *dst, u_char *src, size_t size)
236 ngx_int_t n;
237 ngx_uint_t i;
238 static u_char hex[] = "0123456789abcdef";
239 static uint32_t escape[] =
240 { 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
242 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
243 0x80000021, /* 1000 0000 0000 0000 0000 0000 0010 0001 */
245 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
246 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
248 /* ~}| {zyx wvut srqp onml kjih gfed cba` */
249 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
251 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
252 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
253 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
254 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ };
256 if (dst == NULL) {
258 /* find the number of the characters to be escaped */
260 n = 0;
262 for (i = 0; i < size; i++) {
263 if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
264 n++;
266 src++;
269 return n;
272 for (i = 0; i < size; i++) {
273 if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
274 *dst++ = '%';
275 *dst++ = hex[*src >> 4];
276 *dst++ = hex[*src & 0xf];
277 src++;
279 } else {
280 *dst++ = *src++;
284 return NGX_OK;