1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#ifndef _NGX_STRING_H_INCLUDED_
9e18a033bSKonstantin Ananyev#define _NGX_STRING_H_INCLUDED_
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyev#include <ngx_config.h>
13e18a033bSKonstantin Ananyev#include <ngx_core.h>
14e18a033bSKonstantin Ananyev
15e18a033bSKonstantin Ananyev
16e18a033bSKonstantin Ananyevtypedef struct {
17e18a033bSKonstantin Ananyev    size_t      len;
18e18a033bSKonstantin Ananyev    u_char     *data;
19e18a033bSKonstantin Ananyev} ngx_str_t;
20e18a033bSKonstantin Ananyev
21e18a033bSKonstantin Ananyev
22e18a033bSKonstantin Ananyevtypedef struct {
23e18a033bSKonstantin Ananyev    ngx_str_t   key;
24e18a033bSKonstantin Ananyev    ngx_str_t   value;
25e18a033bSKonstantin Ananyev} ngx_keyval_t;
26e18a033bSKonstantin Ananyev
27e18a033bSKonstantin Ananyev
28e18a033bSKonstantin Ananyevtypedef struct {
29e18a033bSKonstantin Ananyev    unsigned    len:28;
30e18a033bSKonstantin Ananyev
31e18a033bSKonstantin Ananyev    unsigned    valid:1;
32e18a033bSKonstantin Ananyev    unsigned    no_cacheable:1;
33e18a033bSKonstantin Ananyev    unsigned    not_found:1;
34e18a033bSKonstantin Ananyev    unsigned    escape:1;
35e18a033bSKonstantin Ananyev
36e18a033bSKonstantin Ananyev    u_char     *data;
37e18a033bSKonstantin Ananyev} ngx_variable_value_t;
38e18a033bSKonstantin Ananyev
39e18a033bSKonstantin Ananyev
40e18a033bSKonstantin Ananyev#define ngx_string(str)     { sizeof(str) - 1, (u_char *) str }
41e18a033bSKonstantin Ananyev#define ngx_null_string     { 0, NULL }
42e18a033bSKonstantin Ananyev#define ngx_str_set(str, text)                                               \
43e18a033bSKonstantin Ananyev    (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
44e18a033bSKonstantin Ananyev#define ngx_str_null(str)   (str)->len = 0; (str)->data = NULL
45e18a033bSKonstantin Ananyev
46e18a033bSKonstantin Ananyev
47e18a033bSKonstantin Ananyev#define ngx_tolower(c)      (u_char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
48e18a033bSKonstantin Ananyev#define ngx_toupper(c)      (u_char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)
49e18a033bSKonstantin Ananyev
50e18a033bSKonstantin Ananyevvoid ngx_strlow(u_char *dst, u_char *src, size_t n);
51e18a033bSKonstantin Ananyev
52e18a033bSKonstantin Ananyev
53e18a033bSKonstantin Ananyev#define ngx_strncmp(s1, s2, n)  strncmp((const char *) s1, (const char *) s2, n)
54e18a033bSKonstantin Ananyev
55e18a033bSKonstantin Ananyev
56e18a033bSKonstantin Ananyev/* msvc and icc7 compile strcmp() to inline loop */
57e18a033bSKonstantin Ananyev#define ngx_strcmp(s1, s2)  strcmp((const char *) s1, (const char *) s2)
58e18a033bSKonstantin Ananyev
59e18a033bSKonstantin Ananyev
60e18a033bSKonstantin Ananyev#define ngx_strstr(s1, s2)  strstr((const char *) s1, (const char *) s2)
61e18a033bSKonstantin Ananyev#define ngx_strlen(s)       strlen((const char *) s)
62e18a033bSKonstantin Ananyev
63e18a033bSKonstantin Ananyev#define ngx_strchr(s1, c)   strchr((const char *) s1, (int) c)
64e18a033bSKonstantin Ananyev
65e18a033bSKonstantin Ananyevstatic ngx_inline u_char *
66e18a033bSKonstantin Ananyevngx_strlchr(u_char *p, u_char *last, u_char c)
67e18a033bSKonstantin Ananyev{
68e18a033bSKonstantin Ananyev    while (p < last) {
69e18a033bSKonstantin Ananyev
70e18a033bSKonstantin Ananyev        if (*p == c) {
71e18a033bSKonstantin Ananyev            return p;
72e18a033bSKonstantin Ananyev        }
73e18a033bSKonstantin Ananyev
74e18a033bSKonstantin Ananyev        p++;
75e18a033bSKonstantin Ananyev    }
76e18a033bSKonstantin Ananyev
77e18a033bSKonstantin Ananyev    return NULL;
78e18a033bSKonstantin Ananyev}
79e18a033bSKonstantin Ananyev
80e18a033bSKonstantin Ananyev
81e18a033bSKonstantin Ananyev/*
82e18a033bSKonstantin Ananyev * msvc and icc7 compile memset() to the inline "rep stos"
83e18a033bSKonstantin Ananyev * while ZeroMemory() and bzero() are the calls.
84e18a033bSKonstantin Ananyev * icc7 may also inline several mov's of a zeroed register for small blocks.
85e18a033bSKonstantin Ananyev */
86e18a033bSKonstantin Ananyev#define ngx_memzero(buf, n)       (void) memset(buf, 0, n)
87e18a033bSKonstantin Ananyev#define ngx_memset(buf, c, n)     (void) memset(buf, c, n)
88e18a033bSKonstantin Ananyev
89e18a033bSKonstantin Ananyev
90e18a033bSKonstantin Ananyev#if (NGX_MEMCPY_LIMIT)
91e18a033bSKonstantin Ananyev
92e18a033bSKonstantin Ananyevvoid *ngx_memcpy(void *dst, const void *src, size_t n);
93e18a033bSKonstantin Ananyev#define ngx_cpymem(dst, src, n)   (((u_char *) ngx_memcpy(dst, src, n)) + (n))
94e18a033bSKonstantin Ananyev
95e18a033bSKonstantin Ananyev#else
96e18a033bSKonstantin Ananyev
97e18a033bSKonstantin Ananyev/*
98e18a033bSKonstantin Ananyev * gcc3, msvc, and icc7 compile memcpy() to the inline "rep movs".
99e18a033bSKonstantin Ananyev * gcc3 compiles memcpy(d, s, 4) to the inline "mov"es.
100e18a033bSKonstantin Ananyev * icc8 compile memcpy(d, s, 4) to the inline "mov"es or XMM moves.
101e18a033bSKonstantin Ananyev */
102e18a033bSKonstantin Ananyev#define ngx_memcpy(dst, src, n)   (void) memcpy(dst, src, n)
103e18a033bSKonstantin Ananyev#define ngx_cpymem(dst, src, n)   (((u_char *) memcpy(dst, src, n)) + (n))
104e18a033bSKonstantin Ananyev
105e18a033bSKonstantin Ananyev#endif
106e18a033bSKonstantin Ananyev
107e18a033bSKonstantin Ananyev
108e18a033bSKonstantin Ananyev#if ( __INTEL_COMPILER >= 800 )
109e18a033bSKonstantin Ananyev
110e18a033bSKonstantin Ananyev/*
111e18a033bSKonstantin Ananyev * the simple inline cycle copies the variable length strings up to 16
112e18a033bSKonstantin Ananyev * bytes faster than icc8 autodetecting _intel_fast_memcpy()
113e18a033bSKonstantin Ananyev */
114e18a033bSKonstantin Ananyev
115e18a033bSKonstantin Ananyevstatic ngx_inline u_char *
116e18a033bSKonstantin Ananyevngx_copy(u_char *dst, u_char *src, size_t len)
117e18a033bSKonstantin Ananyev{
118e18a033bSKonstantin Ananyev    if (len < 17) {
119e18a033bSKonstantin Ananyev
120e18a033bSKonstantin Ananyev        while (len) {
121e18a033bSKonstantin Ananyev            *dst++ = *src++;
122e18a033bSKonstantin Ananyev            len--;
123e18a033bSKonstantin Ananyev        }
124e18a033bSKonstantin Ananyev
125e18a033bSKonstantin Ananyev        return dst;
126e18a033bSKonstantin Ananyev
127e18a033bSKonstantin Ananyev    } else {
128e18a033bSKonstantin Ananyev        return ngx_cpymem(dst, src, len);
129e18a033bSKonstantin Ananyev    }
130e18a033bSKonstantin Ananyev}
131e18a033bSKonstantin Ananyev
132e18a033bSKonstantin Ananyev#else
133e18a033bSKonstantin Ananyev
134e18a033bSKonstantin Ananyev#define ngx_copy                  ngx_cpymem
135e18a033bSKonstantin Ananyev
136e18a033bSKonstantin Ananyev#endif
137e18a033bSKonstantin Ananyev
138e18a033bSKonstantin Ananyev
139e18a033bSKonstantin Ananyev#define ngx_memmove(dst, src, n)   (void) memmove(dst, src, n)
140e18a033bSKonstantin Ananyev#define ngx_movemem(dst, src, n)   (((u_char *) memmove(dst, src, n)) + (n))
141e18a033bSKonstantin Ananyev
142e18a033bSKonstantin Ananyev
143e18a033bSKonstantin Ananyev/* msvc and icc7 compile memcmp() to the inline loop */
144e18a033bSKonstantin Ananyev#define ngx_memcmp(s1, s2, n)  memcmp((const char *) s1, (const char *) s2, n)
145e18a033bSKonstantin Ananyev
146e18a033bSKonstantin Ananyev
147e18a033bSKonstantin Ananyevu_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n);
148e18a033bSKonstantin Ananyevu_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src);
149e18a033bSKonstantin Ananyevu_char * ngx_cdecl ngx_sprintf(u_char *buf, const char *fmt, ...);
150e18a033bSKonstantin Ananyevu_char * ngx_cdecl ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...);
151e18a033bSKonstantin Ananyevu_char * ngx_cdecl ngx_slprintf(u_char *buf, u_char *last, const char *fmt,
152e18a033bSKonstantin Ananyev    ...);
153e18a033bSKonstantin Ananyevu_char *ngx_vslprintf(u_char *buf, u_char *last, const char *fmt, va_list args);
154e18a033bSKonstantin Ananyev#define ngx_vsnprintf(buf, max, fmt, args)                                   \
155e18a033bSKonstantin Ananyev    ngx_vslprintf(buf, buf + (max), fmt, args)
156e18a033bSKonstantin Ananyev
157e18a033bSKonstantin Ananyevngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);
158e18a033bSKonstantin Ananyevngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n);
159e18a033bSKonstantin Ananyev
160e18a033bSKonstantin Ananyevu_char *ngx_strnstr(u_char *s1, char *s2, size_t n);
161e18a033bSKonstantin Ananyev
162e18a033bSKonstantin Ananyevu_char *ngx_strstrn(u_char *s1, char *s2, size_t n);
163e18a033bSKonstantin Ananyevu_char *ngx_strcasestrn(u_char *s1, char *s2, size_t n);
164e18a033bSKonstantin Ananyevu_char *ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n);
165e18a033bSKonstantin Ananyev
166e18a033bSKonstantin Ananyevngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n);
167e18a033bSKonstantin Ananyevngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n);
168e18a033bSKonstantin Ananyevngx_int_t ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2);
169e18a033bSKonstantin Ananyevngx_int_t ngx_dns_strcmp(u_char *s1, u_char *s2);
170e18a033bSKonstantin Ananyevngx_int_t ngx_filename_cmp(u_char *s1, u_char *s2, size_t n);
171e18a033bSKonstantin Ananyev
172e18a033bSKonstantin Ananyevngx_int_t ngx_atoi(u_char *line, size_t n);
173e18a033bSKonstantin Ananyevngx_int_t ngx_atofp(u_char *line, size_t n, size_t point);
174e18a033bSKonstantin Ananyevssize_t ngx_atosz(u_char *line, size_t n);
175e18a033bSKonstantin Ananyevoff_t ngx_atoof(u_char *line, size_t n);
176e18a033bSKonstantin Ananyevtime_t ngx_atotm(u_char *line, size_t n);
177e18a033bSKonstantin Ananyevngx_int_t ngx_hextoi(u_char *line, size_t n);
178e18a033bSKonstantin Ananyev
179e18a033bSKonstantin Ananyevu_char *ngx_hex_dump(u_char *dst, u_char *src, size_t len);
180e18a033bSKonstantin Ananyev
181e18a033bSKonstantin Ananyev
182e18a033bSKonstantin Ananyev#define ngx_base64_encoded_length(len)  (((len + 2) / 3) * 4)
183e18a033bSKonstantin Ananyev#define ngx_base64_decoded_length(len)  (((len + 3) / 4) * 3)
184e18a033bSKonstantin Ananyev
185e18a033bSKonstantin Ananyevvoid ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src);
186e18a033bSKonstantin Ananyevvoid ngx_encode_base64url(ngx_str_t *dst, ngx_str_t *src);
187e18a033bSKonstantin Ananyevngx_int_t ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src);
188e18a033bSKonstantin Ananyevngx_int_t ngx_decode_base64url(ngx_str_t *dst, ngx_str_t *src);
189e18a033bSKonstantin Ananyev
190e18a033bSKonstantin Ananyevuint32_t ngx_utf8_decode(u_char **p, size_t n);
191e18a033bSKonstantin Ananyevsize_t ngx_utf8_length(u_char *p, size_t n);
192e18a033bSKonstantin Ananyevu_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len);
193e18a033bSKonstantin Ananyev
194e18a033bSKonstantin Ananyev
195e18a033bSKonstantin Ananyev#define NGX_ESCAPE_URI            0
196e18a033bSKonstantin Ananyev#define NGX_ESCAPE_ARGS           1
197e18a033bSKonstantin Ananyev#define NGX_ESCAPE_URI_COMPONENT  2
198e18a033bSKonstantin Ananyev#define NGX_ESCAPE_HTML           3
199e18a033bSKonstantin Ananyev#define NGX_ESCAPE_REFRESH        4
200e18a033bSKonstantin Ananyev#define NGX_ESCAPE_MEMCACHED      5
201e18a033bSKonstantin Ananyev#define NGX_ESCAPE_MAIL_AUTH      6
202e18a033bSKonstantin Ananyev
203e18a033bSKonstantin Ananyev#define NGX_UNESCAPE_URI       1
204e18a033bSKonstantin Ananyev#define NGX_UNESCAPE_REDIRECT  2
205e18a033bSKonstantin Ananyev
206e18a033bSKonstantin Ananyevuintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
207e18a033bSKonstantin Ananyev    ngx_uint_t type);
208e18a033bSKonstantin Ananyevvoid ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
209e18a033bSKonstantin Ananyevuintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
210e18a033bSKonstantin Ananyevuintptr_t ngx_escape_json(u_char *dst, u_char *src, size_t size);
211e18a033bSKonstantin Ananyev
212e18a033bSKonstantin Ananyev
213e18a033bSKonstantin Ananyevtypedef struct {
214e18a033bSKonstantin Ananyev    ngx_rbtree_node_t         node;
215e18a033bSKonstantin Ananyev    ngx_str_t                 str;
216e18a033bSKonstantin Ananyev} ngx_str_node_t;
217e18a033bSKonstantin Ananyev
218e18a033bSKonstantin Ananyev
219e18a033bSKonstantin Ananyevvoid ngx_str_rbtree_insert_value(ngx_rbtree_node_t *temp,
220e18a033bSKonstantin Ananyev    ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
221e18a033bSKonstantin Ananyevngx_str_node_t *ngx_str_rbtree_lookup(ngx_rbtree_t *rbtree, ngx_str_t *name,
222e18a033bSKonstantin Ananyev    uint32_t hash);
223e18a033bSKonstantin Ananyev
224e18a033bSKonstantin Ananyev
225e18a033bSKonstantin Ananyevvoid ngx_sort(void *base, size_t n, size_t size,
226e18a033bSKonstantin Ananyev    ngx_int_t (*cmp)(const void *, const void *));
227e18a033bSKonstantin Ananyev#define ngx_qsort             qsort
228e18a033bSKonstantin Ananyev
229e18a033bSKonstantin Ananyev
230e18a033bSKonstantin Ananyev#define ngx_value_helper(n)   #n
231e18a033bSKonstantin Ananyev#define ngx_value(n)          ngx_value_helper(n)
232e18a033bSKonstantin Ananyev
233e18a033bSKonstantin Ananyev
234e18a033bSKonstantin Ananyev#endif /* _NGX_STRING_H_INCLUDED_ */
235