blob: 6c4640cf7c4c723dfe1a345088016806cd9a9067 [file] [log] [blame]
Igor Sysoev8556e6d2003-10-23 15:54:19 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Igor Sysoevd90282d2004-09-28 08:34:51 +00004 */
5
6
Igor Sysoev8556e6d2003-10-23 15:54:19 +00007#include <ngx_config.h>
8#include <ngx_core.h>
9
10
Igor Sysoevc2068d02005-10-19 12:33:58 +000011ssize_t
12ngx_parse_size(ngx_str_t *line)
Igor Sysoev8556e6d2003-10-23 15:54:19 +000013{
Igor Sysoev2e39e282008-04-16 19:33:23 +000014 u_char unit;
Igor Sysoev10a543a2004-03-16 07:10:12 +000015 size_t len;
Igor Sysoevc2068d02005-10-19 12:33:58 +000016 ssize_t size;
17 ngx_int_t scale;
Igor Sysoev8556e6d2003-10-23 15:54:19 +000018
19 len = line->len;
Igor Sysoev2e39e282008-04-16 19:33:23 +000020 unit = line->data[len - 1];
Igor Sysoev8556e6d2003-10-23 15:54:19 +000021
Igor Sysoev2e39e282008-04-16 19:33:23 +000022 switch (unit) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +000023 case 'K':
24 case 'k':
25 len--;
26 scale = 1024;
27 break;
28
29 case 'M':
30 case 'm':
31 len--;
32 scale = 1024 * 1024;
33 break;
34
35 default:
36 scale = 1;
37 }
38
Igor Sysoevc2068d02005-10-19 12:33:58 +000039 size = ngx_atosz(line->data, len);
Igor Sysoev8556e6d2003-10-23 15:54:19 +000040 if (size == NGX_ERROR) {
41 return NGX_ERROR;
42 }
43
44 size *= scale;
45
46 return size;
47}
48
49
Igor Sysoev1765f472006-07-07 16:33:19 +000050off_t
51ngx_parse_offset(ngx_str_t *line)
52{
Igor Sysoev2e39e282008-04-16 19:33:23 +000053 u_char unit;
Igor Sysoev1765f472006-07-07 16:33:19 +000054 off_t offset;
55 size_t len;
56 ngx_int_t scale;
57
58 len = line->len;
Igor Sysoev2e39e282008-04-16 19:33:23 +000059 unit = line->data[len - 1];
Igor Sysoev1765f472006-07-07 16:33:19 +000060
Igor Sysoev2e39e282008-04-16 19:33:23 +000061 switch (unit) {
Igor Sysoev1765f472006-07-07 16:33:19 +000062 case 'K':
63 case 'k':
64 len--;
65 scale = 1024;
66 break;
67
68 case 'M':
69 case 'm':
70 len--;
71 scale = 1024 * 1024;
72 break;
73
74 case 'G':
75 case 'g':
76 len--;
77 scale = 1024 * 1024 * 1024;
78 break;
79
80 default:
81 scale = 1;
82 }
83
84 offset = ngx_atoof(line->data, len);
85 if (offset == NGX_ERROR) {
86 return NGX_ERROR;
87 }
88
89 offset *= scale;
90
91 return offset;
92}
93
94
Igor Sysoevc2068d02005-10-19 12:33:58 +000095ngx_int_t
Igor Sysoevf57b24e2008-04-17 14:23:20 +000096ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
Igor Sysoev8556e6d2003-10-23 15:54:19 +000097{
Igor Sysoevf57b24e2008-04-17 14:23:20 +000098 u_char *p, *last;
Igor Sysoev6f134cc2006-05-23 14:54:58 +000099 ngx_int_t value, total, scale;
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000100 ngx_uint_t max, valid;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000101 enum {
102 st_start = 0,
103 st_year,
104 st_month,
105 st_week,
106 st_day,
107 st_hour,
108 st_min,
109 st_sec,
110 st_msec,
111 st_last
112 } step;
113
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000114 valid = 0;
115 value = 0;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000116 total = 0;
117 step = sec ? st_start : st_month;
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000118 scale = sec ? 1 : 1000;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000119
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000120 p = line->data;
121 last = p + line->len;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000122
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000123 while (p < last) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000124
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000125 if (*p >= '0' && *p <= '9') {
126 value = value * 10 + (*p++ - '0');
127 valid = 1;
128 continue;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000129 }
130
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000131 switch (*p++) {
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000132
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000133 case 'y':
134 if (step > st_start) {
135 return NGX_ERROR;
136 }
137 step = st_year;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000138 max = 68;
139 scale = 60 * 60 * 24 * 365;
140 break;
141
142 case 'M':
143 if (step > st_year) {
144 return NGX_ERROR;
145 }
146 step = st_month;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000147 max = 828;
148 scale = 60 * 60 * 24 * 30;
149 break;
150
151 case 'w':
152 if (step > st_month) {
153 return NGX_ERROR;
154 }
155 step = st_week;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000156 max = 3550;
157 scale = 60 * 60 * 24 * 7;
158 break;
159
160 case 'd':
161 if (step > st_week) {
162 return NGX_ERROR;
163 }
164 step = st_day;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000165 max = 24855;
166 scale = 60 * 60 * 24;
167 break;
168
169 case 'h':
170 if (step > st_day) {
171 return NGX_ERROR;
172 }
173 step = st_hour;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000174 max = 596523;
175 scale = 60 * 60;
176 break;
177
178 case 'm':
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000179 if (*p == 's') {
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000180 if (sec || step > st_sec) {
181 return NGX_ERROR;
182 }
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000183 p++;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000184 step = st_msec;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000185 max = 2147483647;
186 scale = 1;
187 break;
188 }
189
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000190 if (step > st_hour) {
191 return NGX_ERROR;
192 }
193 step = st_min;
194 max = 35791394;
195 scale = 60;
196 break;
197
198 case 's':
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000199 if (step > st_min) {
200 return NGX_ERROR;
201 }
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000202 step = st_sec;
203 max = 2147483647;
204 scale = 1;
205 break;
206
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000207 case ' ':
208 if (step > st_min) {
209 return NGX_ERROR;
210 }
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000211 step = st_last;
212 max = 2147483647;
213 scale = 1;
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000214 break;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000215
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000216 default:
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000217 return NGX_ERROR;
218 }
219
220 if (step != st_msec && !sec) {
221 scale *= 1000;
222 max /= 1000;
223 }
224
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000225 if ((ngx_uint_t) value > max) {
226 return NGX_ERROR;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000227 }
228
229 total += value * scale;
230
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000231 if ((ngx_uint_t) total > 2147483647) {
232 return NGX_ERROR;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000233 }
234
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000235 value = 0;
236 scale = sec ? 1 : 1000;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000237
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000238 while (p < last && *p == ' ') {
239 p++;
240 }
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000241 }
242
Igor Sysoevf57b24e2008-04-17 14:23:20 +0000243 if (valid) {
244 return total + value * scale;
245 }
246
247 return NGX_ERROR;
Igor Sysoev8556e6d2003-10-23 15:54:19 +0000248}