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