Mercurial > hg > nginx
comparison src/core/ngx_string.c @ 7736:a46fcf101cfc
Core: added format specifiers to output binary data as hex.
Now "s", "V", and "v" format specifiers may be prefixed with "x" (lowercase)
or "X" (uppercase) to output corresponding data in hexadecimal format.
In collaboration with Maxim Dounin.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 28 Oct 2020 10:56:11 +0300 |
parents | a42a6dfeb01a |
children | 5772da03faf8 |
comparison
equal
deleted
inserted
replaced
7735:908f48bd3c2f | 7736:a46fcf101cfc |
---|---|
9 #include <ngx_core.h> | 9 #include <ngx_core.h> |
10 | 10 |
11 | 11 |
12 static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, | 12 static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, |
13 u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width); | 13 u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width); |
14 static u_char *ngx_sprintf_str(u_char *buf, u_char *last, u_char *src, | |
15 size_t len, ngx_uint_t hexadecimal); | |
14 static void ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src, | 16 static void ngx_encode_base64_internal(ngx_str_t *dst, ngx_str_t *src, |
15 const u_char *basis, ngx_uint_t padding); | 17 const u_char *basis, ngx_uint_t padding); |
16 static ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src, | 18 static ngx_int_t ngx_decode_base64_internal(ngx_str_t *dst, ngx_str_t *src, |
17 const u_char *basis); | 19 const u_char *basis); |
18 | 20 |
99 * %[0][width][.width]f double, max valid number fits to %18.15f | 101 * %[0][width][.width]f double, max valid number fits to %18.15f |
100 * %P ngx_pid_t | 102 * %P ngx_pid_t |
101 * %M ngx_msec_t | 103 * %M ngx_msec_t |
102 * %r rlim_t | 104 * %r rlim_t |
103 * %p void * | 105 * %p void * |
104 * %V ngx_str_t * | 106 * %[x|X]V ngx_str_t * |
105 * %v ngx_variable_value_t * | 107 * %[x|X]v ngx_variable_value_t * |
106 * %s null-terminated string | 108 * %[x|X]s null-terminated string |
107 * %*s length and string | 109 * %*[x|X]s length and string |
108 * %Z '\0' | 110 * %Z '\0' |
109 * %N '\n' | 111 * %N '\n' |
110 * %c char | 112 * %c char |
111 * %% % | 113 * %% % |
112 * | 114 * |
163 ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args) | 165 ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args) |
164 { | 166 { |
165 u_char *p, zero; | 167 u_char *p, zero; |
166 int d; | 168 int d; |
167 double f; | 169 double f; |
168 size_t len, slen; | 170 size_t slen; |
169 int64_t i64; | 171 int64_t i64; |
170 uint64_t ui64, frac; | 172 uint64_t ui64, frac; |
171 ngx_msec_t ms; | 173 ngx_msec_t ms; |
172 ngx_uint_t width, sign, hex, max_width, frac_width, scale, n; | 174 ngx_uint_t width, sign, hex, max_width, frac_width, scale, n; |
173 ngx_str_t *v; | 175 ngx_str_t *v; |
248 switch (*fmt) { | 250 switch (*fmt) { |
249 | 251 |
250 case 'V': | 252 case 'V': |
251 v = va_arg(args, ngx_str_t *); | 253 v = va_arg(args, ngx_str_t *); |
252 | 254 |
253 len = ngx_min(((size_t) (last - buf)), v->len); | 255 buf = ngx_sprintf_str(buf, last, v->data, v->len, hex); |
254 buf = ngx_cpymem(buf, v->data, len); | |
255 fmt++; | 256 fmt++; |
256 | 257 |
257 continue; | 258 continue; |
258 | 259 |
259 case 'v': | 260 case 'v': |
260 vv = va_arg(args, ngx_variable_value_t *); | 261 vv = va_arg(args, ngx_variable_value_t *); |
261 | 262 |
262 len = ngx_min(((size_t) (last - buf)), vv->len); | 263 buf = ngx_sprintf_str(buf, last, vv->data, vv->len, hex); |
263 buf = ngx_cpymem(buf, vv->data, len); | |
264 fmt++; | 264 fmt++; |
265 | 265 |
266 continue; | 266 continue; |
267 | 267 |
268 case 's': | 268 case 's': |
269 p = va_arg(args, u_char *); | 269 p = va_arg(args, u_char *); |
270 | 270 |
271 if (slen == (size_t) -1) { | 271 buf = ngx_sprintf_str(buf, last, p, slen, hex); |
272 while (*p && buf < last) { | |
273 *buf++ = *p++; | |
274 } | |
275 | |
276 } else { | |
277 len = ngx_min(((size_t) (last - buf)), slen); | |
278 buf = ngx_cpymem(buf, p, len); | |
279 } | |
280 | |
281 fmt++; | 272 fmt++; |
282 | 273 |
283 continue; | 274 continue; |
284 | 275 |
285 case 'O': | 276 case 'O': |
574 | 565 |
575 return ngx_cpymem(buf, p, len); | 566 return ngx_cpymem(buf, p, len); |
576 } | 567 } |
577 | 568 |
578 | 569 |
570 static u_char * | |
571 ngx_sprintf_str(u_char *buf, u_char *last, u_char *src, size_t len, | |
572 ngx_uint_t hexadecimal) | |
573 { | |
574 static u_char hex[] = "0123456789abcdef"; | |
575 static u_char HEX[] = "0123456789ABCDEF"; | |
576 | |
577 if (hexadecimal == 0) { | |
578 | |
579 if (len == (size_t) -1) { | |
580 while (*src && buf < last) { | |
581 *buf++ = *src++; | |
582 } | |
583 | |
584 } else { | |
585 len = ngx_min((size_t) (last - buf), len); | |
586 buf = ngx_cpymem(buf, src, len); | |
587 } | |
588 | |
589 } else if (hexadecimal == 1) { | |
590 | |
591 if (len == (size_t) -1) { | |
592 | |
593 while (*src && buf < last - 1) { | |
594 *buf++ = hex[*src >> 4]; | |
595 *buf++ = hex[*src++ & 0xf]; | |
596 } | |
597 | |
598 } else { | |
599 | |
600 while (len-- && buf < last - 1) { | |
601 *buf++ = hex[*src >> 4]; | |
602 *buf++ = hex[*src++ & 0xf]; | |
603 } | |
604 } | |
605 | |
606 } else { /* hexadecimal == 2 */ | |
607 | |
608 if (len == (size_t) -1) { | |
609 | |
610 while (*src && buf < last - 1) { | |
611 *buf++ = HEX[*src >> 4]; | |
612 *buf++ = HEX[*src++ & 0xf]; | |
613 } | |
614 | |
615 } else { | |
616 | |
617 while (len-- && buf < last - 1) { | |
618 *buf++ = HEX[*src >> 4]; | |
619 *buf++ = HEX[*src++ & 0xf]; | |
620 } | |
621 } | |
622 } | |
623 | |
624 return buf; | |
625 } | |
626 | |
627 | |
579 /* | 628 /* |
580 * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only, | 629 * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only, |
581 * and implement our own ngx_strcasecmp()/ngx_strncasecmp() | 630 * and implement our own ngx_strcasecmp()/ngx_strncasecmp() |
582 * to avoid libc locale overhead. Besides, we use the ngx_uint_t's | 631 * to avoid libc locale overhead. Besides, we use the ngx_uint_t's |
583 * instead of the u_char's, because they are slightly faster. | 632 * instead of the u_char's, because they are slightly faster. |