123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908 |
- /**
- * cs_str.c
- * Copyright (c) 2007-2018 ls
- **/
- #include "../inc/cs.h"
- #include "../inc/cs_str.h"
- static const u_char _hex_char[] = "0123456789ABCDEF";
- /* everything except: ! ( ) * - . 0-9 A-Z _ a-z */
- static const u_char _uri_char[] = {
- /*
- 0 1 2 3 4 5 6 7 8 9 A B C D E F
- */
- /* 00 - 0F control chars */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */
- /* 20 - 2F space " # $ % & ' + , / */
- 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; < = > ? */
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F @ */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, /* 50 - 5F [ \ ] ^ */
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6F ` */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /* 70 - 7F { | } ~ DEL */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0 - AF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* B0 - BF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0 - CF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* D0 - DF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0 - EF */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* F0 - FF */
- };
- CS_API size_t cs_strerror(u_char *err, const char *fmt, ...) {
- size_t n;
- va_list ap;
-
- if (!err) {
- return (0);
- }
- va_start(ap, fmt);
- n = (size_t)vsnprintf((char *)err, CS_KB, fmt, ap);
- va_end(ap);
-
- return (n);
- }
- CS_API size_t cs_strlen(const u_char *s) {
- const u_char *str;
-
- for (str = s; *str; ++str);
-
- return (str - s);
- }
- CS_API u_char *cs_tolower(u_char *s) {
- u_char *c;
-
- for (c = s; *c; c++) {
- if (*c >= 'A' && *c <= 'Z') {
- *c |= 32;
- }
- }
-
- return (s);
- }
- CS_API u_char *cs_toupper(u_char *s) {
- u_char *c;
-
- for (c = s; *c; c++) {
- if (*c >= 'a' && *c <= 'z') {
- *c &= ~32;
- }
- }
-
- return (s);
- }
- CS_API u_char *cs_strcpy(u_char *d, const u_char *s) {
- u_char *save = d;
-
- for (; (*d = *s) != '\0'; ++s, ++d);
-
- return (save);
- }
- CS_API u_char *cs_strncpy(u_char *d, const u_char *s, size_t n) {
- if (n != 0) {
- u_char *to = d;
- const u_char *from = s;
-
- do {
- if ((*to++ = *from++) == 0) {
- /* NUL pad the remaining n-1 bytes */
- while (--n != 0)
- *to++ = 0;
- break;
- }
- } while (--n != 0);
- }
- return (d);
- }
- CS_API u_char *cs_strcat(u_char *d, const u_char *s) {
- u_char *save = d;
- for (; *d; ++d);
- while ((*d++ = *s++) != '\0');
- return (save);
- }
- CS_API u_char *cs_strncat(u_char *d, const u_char *s, size_t n) {
- u_char *dst = d;
- const u_char *str = s;
- if (n != 0) {
- while (*dst != 0) {
- dst++;
- }
- do {
- if ((*dst = *str++) == 0) {
- break;
- }
- dst++;
- } while (--n != 0);
- *dst = 0;
- }
- return (d);
- }
- CS_API int cs_strcmp(const u_char *s1, const u_char *s2) {
- while (*s1 == *s2++) {
- if (*s1++ == 0) {
- return (0);
- }
- }
- return (*s1 - *--s2);
- }
- CS_API int cs_strncmp(const u_char *s1, const u_char *s2, size_t n) {
- if (n == 0) {
- return (0);
- }
- do {
- if (*s1 != *s2++) {
- return (*s1 - *--s2);
- }
- if (*s1++ == 0) {
- break;
- }
- } while (--n != 0);
- return (0);
- }
- CS_API int cs_strcasecmp(u_char *s1, u_char *s2) {
- u_char c1, c2;
-
- for ( ; ; ) {
- c1 = *s1++;
- c2 = *s2++;
-
- c1 = (u_char)((c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1);
- c2 = (u_char)((c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2);
-
- if (c1 == c2) {
- if (c1) {
- continue;
- }
- return (0);
- }
- return (c1 - c2);
- }
- }
- CS_API int cs_strncasecmp(u_char *s1, u_char *s2, size_t n) {
- u_char c1, c2;
-
- while (n) {
- c1 = *s1++;
- c2 = *s2++;
-
- c1 = (u_char)((c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1);
- c2 = (u_char)((c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2);
-
- if (c1 == c2) {
- if (c1) {
- n--;
- continue;
- }
- return (0);
- }
- return (c1 - c2);
- }
-
- return (0);
- }
- CS_API u_char *cs_strchr(const u_char *s, u_char c) {
- const u_char *p = s;
-
- for ( ; ; ) {
- if (*p == c) {
- return ((u_char *)p);
- }
- if (!*p) {
- return (NULL);
- }
- p++;
- }
- }
- CS_API u_char *cs_strstr(const u_char *s, u_char *d) {
- register u_char *cp = (u_char *)s;
- register u_char *s1, *s2;
-
- if (!*d) {
- return ((u_char *)s);
- }
-
- while (*cp) {
- s1 = cp;
- s2 = (u_char *)d;
-
- while (*s1 && *s2 && !(*s1 - *s2)) {
- s1++, s2++;
- }
- if (!*s2) {
- return (cp);
- }
- cp++;
- }
-
- return (NULL);
- }
- CS_API u_char *cs_strrchr(const u_char *s, u_char c) {
- u_char *start = (u_char *)s;
-
- /* find end of string */
- while (*s++);
- /* search towards front */
- while (--s != start && *s != c);
-
- if (*s == c) { /* char found ? */
- return ((u_char *)s);
- }
-
- return (NULL);
- }
- CS_API size_t cs_strchrcpy(u_char *d, const u_char *s, u_char c) {
- register u_char *cp = (u_char *)s;
- while (*cp) {
- if (*cp == c) {
- break;
- }
- if (!*cp) {
- return (0);
- }
- *d++ = *cp;
- cp++;
- }
- return (cp - s);
- }
- CS_API u_char *cs_strdup(u_char *s, size_t n) {
- u_char *cp;
-
- cp = (u_char *)malloc(n + sizeof(u_char));
- if (cp) {
- cs_bcpy(cp, s, n);
- *(cp + n) = '\0';
- return (cp);
- }
- return (NULL);
- }
- CS_API cs_buf_t *cs_buf_init(u_char *p, size_t n) {
- cs_buf_t *buf = (cs_buf_t *)p;
- buf->buf = p + sizeof(cs_buf_t);
- buf->used = 0;
- buf->size = n - sizeof(cs_buf_t);
- return (buf);
- }
- CS_API cs_buf_t *cs_buf_new(size_t n) {
- cs_buf_t *buf = NULL;
- u_char *p = (u_char *)cs_malloc((sizeof(cs_buf_t) + n) * sizeof(u_char));
- if (p) {
- buf = (cs_buf_t *)p;
- buf->buf = p + sizeof(cs_buf_t);
- buf->size = n;
- buf->used = 0;
- }
- return (buf);
- }
- CS_API void cs_buf_free(cs_buf_t *buf) {
- if (buf) {
- cs_free(buf);
- }
- }
- CS_API size_t cs_buf_cat(cs_buf_t *d, cs_buf_t *s) {
- size_t n = d->used;
- if ((d->used + s->used) > d->size) {
- n = s->size - s->used;
- }
- cs_bcpy(d->buf + d->used, s->buf, n);
- d->used += n;
- return (n);
- }
- CS_API u_char *cs_buf_bcpy(cs_buf_t *buf, u_char *s, size_t n) {
- u_char *p = buf->buf;
- cs_bcpy(buf->buf + buf->used, s, n);
- buf->used = n;
- return (p);
- }
- CS_API u_char *cs_buf_bcat(cs_buf_t *buf, u_char *s, size_t n) {
- u_char *p = buf->buf;
- size_t len = n;
- if ((buf->used + n) > buf->size) {
- len = buf->size - buf->used;
- }
- cs_bcpy(buf->buf + buf->used, s, len);
- buf->used += len;
- return (p);
- }
- CS_API int cs_buf_cmp(cs_buf_t *d, cs_buf_t *s) {
- if (d->used == s->used) {
- return cs_bcmp(d->buf, s->buf, d->used);
- }
- return (int)(d->used - s->used);
- }
- CS_API cs_int_t cs_atoi(u_char *s, size_t n) {
- cs_int_t value, neg, c;
-
- if (n == 0) {
- return (0);
- }
-
- c = *s;
- if (c == '-') {
- neg = 1;
- s++;
- n--;
- } else {
- neg = 0;
- }
-
- for (value = 0; n--; s++) {
- if (*s < '0' || *s > '9') {
- return (0);
- }
- value = value * 10 + (*s - '0');
- }
-
- if (neg) {
- value = value * -1;
- }
-
- return (value);
- }
- CS_API cs_int64_t cs_atoi64(u_char *s, size_t n) {
- cs_int64_t value;
- cs_int_t neg, c;
-
- if (n == 0) {
- return (0);
- }
- c = *s;
- if (c == '-') {
- neg = 1;
- s++;
- n--;
- } else {
- neg = 0;
- }
- for (value = 0; n--; s++) {
- if (*s < '0' || *s > '9') {
- return (0);
- }
-
- value = value * 10 + (*s - '0');
- }
- if (neg) {
- value = value * -1;
- }
-
- return (value);
- }
- CS_API cs_uint_t cs_atou(u_char *s, size_t n) {
- cs_uint_t value;
-
- if (n == 0) {
- return (0);
- }
-
- for (value = 0; n--; s++) {
- if (*s < '0' || *s > '9') {
- return (0);
- }
-
- value = value * 10 + (*s - '0');
- }
-
- return (value);
- }
- CS_API cs_int_t cs_htoi(u_char *s, size_t n) {
- u_char c, ch;
- cs_int_t value;
- for (value = 0; n--; s++){
- ch = *s;
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- continue;
- }
-
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- continue;
- }
- }
- return (value);
- }
- CS_API cs_uint_t cs_htou(u_char *s, size_t n) {
- u_char c, ch;
- cs_uint_t value;
-
- for (value = 0; n--; s++){
- ch = *s;
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- continue;
- }
-
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- continue;
- }
- }
-
- return (value);
- }
- CS_API cs_int_t cs_btoi(u_char *s, size_t n) {
- u_char c, ch;
- cs_int_t value;
-
- for (value = 0; n--; s++) {
- ch = _hex_char[(*s) >> 4];
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- } else {
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- }
- }
-
- ch = _hex_char[(*s) & 0x0f];
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- } else {
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- }
- }
- }
-
- return (value);
- }
- CS_API cs_int_t cs_btou(u_char *s, size_t n) {
- u_char c, ch;
- cs_uint_t value;
-
- for (value = 0; n--; s++) {
- ch = _hex_char[(*s) >> 4];
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- } else {
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- }
- }
-
- ch = _hex_char[(*s) & 0x0f];
- if (ch >= '0' && ch <= '9') {
- value = value * 16 + (ch - '0');
- } else {
- c = (u_char) (ch | 0x20);
-
- if (c >= 'a' && c <= 'f') {
- value = value * 16 + (c - 'a' + 10);
- }
- }
- }
-
- return (value);
- }
- CS_API size_t cs_uri_escape(u_char *d, const u_char *s) {
- u_char *cp = d;
- size_t n;
- if (d == NULL) {
- n = 0;
- while (*s) {
- if (_uri_char[*s]) {
- n++;
- }
- s++;
- }
- return (n);
- }
-
- while (*s) {
- if (_uri_char[*s]) {
- *d++ = '%';
- *d++ = _hex_char[(*s) >> 4];
- *d++ = _hex_char[(*s) & 0x0f];
- s++;
- } else {
- *d++ = *s++;
- }
- }
-
- return (d - cp);
- }
- CS_API size_t cs_uri_unescape(u_char *d, const u_char *s) {
- register unsigned char high, low;
- u_char *cp = d;
- while ((*s) != '\0') {
- if (*s == '%') {
- X2C(*(s + 1), high);
- if (high < 0x10) {
- X2C(*(s + 2), low);
- if (low < 0x10) {
- high = (u_char)((high << 4) | low);
- *d = high;
- s += 2;
- }
- }
- } else if (*s == '+') {
- *d = ' ';
- } else {
- *d = *s;
- }
- d++;
- s++;
- }
-
- return (d - cp);
- }
- /* from ngx_string.c */
- CS_API size_t cs_json_escape(u_char *d, u_char *s, size_t n) {
- u_char ch, *cp = d;
- size_t len;
- if (d == NULL) {
- len = 0;
- while (n) {
- ch = *s++;
- if (ch == '\\' || ch == '"') {
- len++;
- } else if (ch <= 0x1f) {
- len += sizeof("\\u001F") - 2;
- }
- n--;
- }
- return (len);
- }
- while (n) {
- ch = *s++;
- if (ch > 0x1f) {
- if (ch == '\\' || ch == '"') {
- *d++ = '\\';
- }
- *d++ = ch;
- } else {
- *d++ = '\\'; *d++ = 'u'; *d++ = '0'; *d++ = '0';
- *d++ = '0' + (ch >> 4);
- ch &= 0xf;
- *d++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10);
- }
- n--;
- }
- return (d - cp);
- }
- CS_API size_t cs_hex_dump(u_char *d, u_char *s, size_t n) {
- u_char *cp = d;
-
- while (n--) {
- *d++ = _hex_char[*s >> 4];
- *d++ = _hex_char[*s++ & 0xf];
- }
-
- return (d - cp);
- }
- CS_API size_t cs_hex_undump(u_char *d, const u_char *s, size_t n) {
- size_t i = 0;
- register u_char ch, digit;
- u_char *cp = d;
-
- for (i = 0; i < n; i++) {
- X2C(*(s + i) ,ch);
- ch = ch << 4;
- i++;
- X2C(*(s + i), digit);
- ch += digit;
- *d++ = ch;
- }
-
- return (d - cp);
- }
- /* from ngx_string.c */
- static void _cs_base64_encode_internal(
- cs_buf_t *dst, cs_buf_t *src, const u_char *basis, cs_uint_t padding) {
- u_char *d, *s;
- size_t len;
- len = src->used;
- s = src->buf;
- d = dst->buf;
- while (len > 2) {
- *d++ = basis[(s[0] >> 2) & 0x3f];
- *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
- *d++ = basis[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
- *d++ = basis[s[2] & 0x3f];
- s += 3;
- len -= 3;
- }
- if (len) {
- *d++ = basis[(s[0] >> 2) & 0x3f];
- if (len == 1) {
- *d++ = basis[(s[0] & 3) << 4];
- if (padding) {
- *d++ = '=';
- }
- } else {
- *d++ = basis[((s[0] & 3) << 4) | (s[1] >> 4)];
- *d++ = basis[(s[1] & 0x0f) << 2];
- }
- if (padding) {
- *d++ = '=';
- }
- }
- dst->used = d - dst->buf;
- }
- /* from ngx_string.c */
- CS_API void cs_base64_encode(cs_buf_t *d, cs_buf_t *s) {
- static u_char basis64[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- _cs_base64_encode_internal(d, s, basis64, 1);
- }
- /* from ngx_string.c */
- static cs_int_t _cs_base64_decode_internal(
- cs_buf_t *dst, cs_buf_t *src, const u_char *basis) {
- size_t len;
- u_char *d, *s;
- for (len = 0; len < src->used; len++) {
- if (src->buf[len] == '=') {
- break;
- }
- if (basis[src->buf[len]] == 77) {
- return (CS_ERR);
- }
- }
- if (len % 4 == 1) {
- return (CS_ERR);
- }
- s = src->buf;
- d = dst->buf;
- while (len > 3) {
- *d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);
- *d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);
- *d++ = (u_char) (basis[s[2]] << 6 | basis[s[3]]);
- s += 4;
- len -= 4;
- }
- if (len > 1) {
- *d++ = (u_char) (basis[s[0]] << 2 | basis[s[1]] >> 4);
- }
- if (len > 2) {
- *d++ = (u_char) (basis[s[1]] << 4 | basis[s[2]] >> 2);
- }
- dst->used = d - dst->buf;
- return (CS_OK);
- }
- /* from ngx_string.c */
- CS_API cs_int_t cs_base64_decode(cs_buf_t *d, cs_buf_t *s) {
- static u_char basis64[] = {
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
- 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
- 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
- 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
- };
- return _cs_base64_decode_internal(d, s, basis64);
- }
- /* from ngx_string.c */
- CS_API cs_uint_t cs_utf8_decode(u_char **s, size_t n) {
- size_t len;
- cs_uint_t u, i, valid;
-
- u = **s;
-
- if(u > 0xf0){
- u &= 0x07;
- valid = 0xffff;
- len = 3;
- } else if (u > 0xe0) {
- u &= 0x0f;
- valid = 0x7ff;
- len = 2;
- } else if (u > 0xc0) {
- u &= 0x1f;
- valid = 0x7f;
- len = 1;
- } else{
- (*s)++;
- return (0xffffffff);
- }
-
- if (n - 1 < len) {
- return (0xfffffffe);
- }
-
- (*s)++;
-
- while (len) {
- i = *(*s)++;
-
- if (i < 0x80) {
- return (0xffffffff);
- }
-
- u = (u << 6) | (i & 0x3f);
- len--;
- }
-
- if (u > valid) {
- return (u);
- }
-
- return (0xffffffff);
- }
- /* from ngx_string.c */
- CS_API size_t cs_utf8_length(u_char *s, size_t n) {
- u_char c, *last;
- size_t len;
-
- last = s + n;
- for (len = 0; s < last; len++) {
- c = *s;
- if (c < 0x80) {
- s++;
- continue;
- }
-
- if (cs_utf8_decode(&s, n) > 0x10ffff) {
- /* invalid UTF-8 */
- return n;
- }
- }
- return (len);
- }
- /*
- djb2
- this algorithm (k=33) was first reported by dan bernstein many years ago
- in comp.lang.c.
- another version of this algorithm (now favored by bernstein) uses xor:
- hash(i) = hash(i - 1) * 33 ^ str[i];
- the magic of number 33 (why it works better than many other constants,
- prime or not)
- has never been adequately explained.
- */
- CS_API cs_uint_t cs_hash_djb2(const u_char *s) {
- const u_char *cp = s;
- cs_uint_t hash = 5381;
- while (*cp) {
- hash = ((hash << 5) + hash) + *cp; /* hash = hash * 33 + c */
- cp++;
- }
- return (hash);
- }
- CS_API cs_uint64_t cs_hash_djb2_64(const u_char *s) {
- const u_char *cp = s;
- cs_uint64_t hash = 5381;
-
- while (*cp) {
- hash = ((hash << 5) + hash) + *cp; /* hash = hash * 33 + c */
- cp++;
- }
-
- return (hash);
- }
|