📄 ngx_string.c
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n){ if (n == 0) { return dst; } for ( /* void */ ; --n; dst++, src++) { *dst = *src; if (*dst == '\0') { return dst; } } *dst = '\0'; return dst;}u_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src){ u_char *dst; dst = ngx_palloc(pool, src->len); if (dst == NULL) { return NULL; } ngx_memcpy(dst, src->data, src->len); return dst;}/* * supported formats: * %[0][width][x][X]O off_t * %[0][width]T time_t * %[0][width][u][x|X]z ssize_t/size_t * %[0][width][u][x|X]d int/u_int * %[0][width][u][x|X]l long * %[0][width|m][u][x|X]i ngx_int_t/ngx_uint_t * %[0][width][u][x|X]D int32_t/uint32_t * %[0][width][u][x|X]L int64_t/uint64_t * %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t * %P ngx_pid_t * %M ngx_msec_t * %r rlim_t * %p void * * %V ngx_str_t * * %v ngx_variable_value_t * * %s null-terminated string * %*s length and string * %Z '\0' * %N '\n' * %c char * %% % * * reserved: * %t ptrdiff_t * %S null-teminated wchar string * %C wchar */u_char * ngx_cdeclngx_sprintf(u_char *buf, const char *fmt, ...){ u_char *p; va_list args; va_start(args, fmt); p = ngx_vsnprintf(buf, /* STUB */ 65536, fmt, args); va_end(args); return p;}u_char * ngx_cdeclngx_snprintf(u_char *buf, size_t max, const char *fmt, ...){ u_char *p; va_list args; va_start(args, fmt); p = ngx_vsnprintf(buf, max, fmt, args); va_end(args); return p;}u_char *ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args){ u_char *p, zero, *last, temp[NGX_INT64_LEN + 1]; /* * really we need temp[NGX_INT64_LEN] only, * but icc issues the warning */ int d; size_t len, slen; uint32_t ui32; int64_t i64; uint64_t ui64; ngx_msec_t ms; ngx_uint_t width, sign, hexadecimal, max_width; ngx_str_t *v; ngx_variable_value_t *vv; static u_char hex[] = "0123456789abcdef"; static u_char HEX[] = "0123456789ABCDEF"; if (max == 0) { return buf; } last = buf + max; while (*fmt && buf < last) { /* * "buf < last" means that we could copy at least one character: * the plain character, "%%", "%c", and minus without the checking */ if (*fmt == '%') { i64 = 0; ui64 = 0; zero = (u_char) ((*++fmt == '0') ? '0' : ' '); width = 0; sign = 1; hexadecimal = 0; max_width = 0; slen = (size_t) -1; p = temp + NGX_INT64_LEN; while (*fmt >= '0' && *fmt <= '9') { width = width * 10 + *fmt++ - '0'; } for ( ;; ) { switch (*fmt) { case 'u': sign = 0; fmt++; continue; case 'm': max_width = 1; fmt++; continue; case 'X': hexadecimal = 2; sign = 0; fmt++; continue; case 'x': hexadecimal = 1; sign = 0; fmt++; continue; case '*': slen = va_arg(args, size_t); fmt++; continue; default: break; } break; } switch (*fmt) { case 'V': v = va_arg(args, ngx_str_t *); len = v->len; len = (buf + len < last) ? len : (size_t) (last - buf); buf = ngx_cpymem(buf, v->data, len); fmt++; continue; case 'v': vv = va_arg(args, ngx_variable_value_t *); len = vv->len; len = (buf + len < last) ? len : (size_t) (last - buf); buf = ngx_cpymem(buf, vv->data, len); fmt++; continue; case 's': p = va_arg(args, u_char *); if (slen == (size_t) -1) { while (*p && buf < last) { *buf++ = *p++; } } else { len = (buf + slen < last) ? slen : (size_t) (last - buf); buf = ngx_cpymem(buf, p, len); } fmt++; continue; case 'O': i64 = (int64_t) va_arg(args, off_t); sign = 1; break; case 'P': i64 = (int64_t) va_arg(args, ngx_pid_t); sign = 1; break; case 'T': i64 = (int64_t) va_arg(args, time_t); sign = 1; break; case 'M': ms = (ngx_msec_t) va_arg(args, ngx_msec_t); if ((ngx_msec_int_t) ms == -1) { sign = 1; i64 = -1; } else { sign = 0; ui64 = (uint64_t) ms; } break; case 'z': if (sign) { i64 = (int64_t) va_arg(args, ssize_t); } else { ui64 = (uint64_t) va_arg(args, size_t); } break; case 'i': if (sign) { i64 = (int64_t) va_arg(args, ngx_int_t); } else { ui64 = (uint64_t) va_arg(args, ngx_uint_t); } if (max_width) { width = NGX_INT_T_LEN; } break; case 'd': if (sign) { i64 = (int64_t) va_arg(args, int); } else { ui64 = (uint64_t) va_arg(args, u_int); } break; case 'l': if (sign) { i64 = (int64_t) va_arg(args, long); } else { ui64 = (uint64_t) va_arg(args, u_long); } break; case 'D': if (sign) { i64 = (int64_t) va_arg(args, int32_t); } else { ui64 = (uint64_t) va_arg(args, uint32_t); } break; case 'L': if (sign) { i64 = va_arg(args, int64_t); } else { ui64 = va_arg(args, uint64_t); } break; case 'A': if (sign) { i64 = (int64_t) va_arg(args, ngx_atomic_int_t); } else { ui64 = (uint64_t) va_arg(args, ngx_atomic_uint_t); } if (max_width) { width = NGX_ATOMIC_T_LEN; } break;#if !(NGX_WIN32) case 'r': i64 = (int64_t) va_arg(args, rlim_t); sign = 1; break;#endif case 'p': ui64 = (uintptr_t) va_arg(args, void *); hexadecimal = 2; sign = 0; zero = '0'; width = NGX_PTR_SIZE * 2; break; case 'c': d = va_arg(args, int); *buf++ = (u_char) (d & 0xff); fmt++; continue; case 'Z': *buf++ = '\0'; fmt++; continue; case 'N':#if (NGX_WIN32) *buf++ = CR;#endif *buf++ = LF; fmt++; continue; case '%': *buf++ = '%'; fmt++; continue; default: *buf++ = *fmt++; continue; } if (sign) { if (i64 < 0) { *buf++ = '-'; ui64 = (uint64_t) -i64; } else { ui64 = (uint64_t) i64; } } if (hexadecimal == 1) { do { /* the "(uint32_t)" cast disables the BCC's warning */ *--p = hex[(uint32_t) (ui64 & 0xf)]; } while (ui64 >>= 4); } else if (hexadecimal == 2) { do { /* the "(uint32_t)" cast disables the BCC's warning */ *--p = HEX[(uint32_t) (ui64 & 0xf)]; } while (ui64 >>= 4); } else if (ui64 <= NGX_MAX_UINT32_VALUE) { /* * To divide 64-bit number and to find the remainder * on the x86 platform gcc and icc call the libc functions * [u]divdi3() and [u]moddi3(), they call another function * in its turn. On FreeBSD it is the qdivrem() function, * its source code is about 170 lines of the code. * The glibc counterpart is about 150 lines of the code. * * For 32-bit numbers and some divisors gcc and icc use * the inlined multiplication and shifts. For example, * unsigned "i32 / 10" is compiled to * * (i32 * 0xCCCCCCCD) >> 35 */ ui32 = (uint32_t) ui64; do { *--p = (u_char) (ui32 % 10 + '0'); } while (ui32 /= 10); } else { do { *--p = (u_char) (ui64 % 10 + '0'); } while (ui64 /= 10); } len = (temp + NGX_INT64_LEN) - p; while (len++ < width && buf < last) { *buf++ = zero; } len = (temp + NGX_INT64_LEN) - p; if (buf + len > last) { len = last - buf; } buf = ngx_cpymem(buf, p, len); fmt++; } else { *buf++ = *fmt++; } } return buf;}/* * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only, * and implement our own ngx_strcasecmp()/ngx_strncasecmp() * to avoid libc locale overhead. Besides, we use the ngx_uint_t's * instead of the u_char's, because they are slightly faster. */ngx_int_tngx_strcasecmp(u_char *s1, u_char *s2){ ngx_uint_t c1, c2; for ( ;; ) { c1 = (ngx_uint_t) *s1++; c2 = (ngx_uint_t) *s2++; c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1; c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2; if (c1 == c2) { if (c1) { continue; } return 0; } return c1 - c2; }}ngx_int_t
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -