Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_parse.c
Go to the documentation of this file.
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #include <ngx_config.h>
9 #include <ngx_core.h>
10 
11 
12 ssize_t
14 {
15  u_char unit;
16  size_t len;
17  ssize_t size;
18  ngx_int_t scale;
19 
20  len = line->len;
21  unit = line->data[len - 1];
22 
23  switch (unit) {
24  case 'K':
25  case 'k':
26  len--;
27  scale = 1024;
28  break;
29 
30  case 'M':
31  case 'm':
32  len--;
33  scale = 1024 * 1024;
34  break;
35 
36  default:
37  scale = 1;
38  }
39 
40  size = ngx_atosz(line->data, len);
41  if (size == NGX_ERROR) {
42  return NGX_ERROR;
43  }
44 
45  size *= scale;
46 
47  return size;
48 }
49 
50 
51 off_t
53 {
54  u_char unit;
55  off_t offset;
56  size_t len;
57  ngx_int_t scale;
58 
59  len = line->len;
60  unit = line->data[len - 1];
61 
62  switch (unit) {
63  case 'K':
64  case 'k':
65  len--;
66  scale = 1024;
67  break;
68 
69  case 'M':
70  case 'm':
71  len--;
72  scale = 1024 * 1024;
73  break;
74 
75  case 'G':
76  case 'g':
77  len--;
78  scale = 1024 * 1024 * 1024;
79  break;
80 
81  default:
82  scale = 1;
83  }
84 
85  offset = ngx_atoof(line->data, len);
86  if (offset == NGX_ERROR) {
87  return NGX_ERROR;
88  }
89 
90  offset *= scale;
91 
92  return offset;
93 }
94 
95 
98 {
99  u_char *p, *last;
100  ngx_int_t value, total, scale;
101  ngx_uint_t max, valid;
102  enum {
103  st_start = 0,
104  st_year,
105  st_month,
106  st_week,
107  st_day,
108  st_hour,
109  st_min,
110  st_sec,
111  st_msec,
112  st_last
113  } step;
114 
115  valid = 0;
116  value = 0;
117  total = 0;
118  step = is_sec ? st_start : st_month;
119  scale = is_sec ? 1 : 1000;
120 
121  p = line->data;
122  last = p + line->len;
123 
124  while (p < last) {
125 
126  if (*p >= '0' && *p <= '9') {
127  value = value * 10 + (*p++ - '0');
128  valid = 1;
129  continue;
130  }
131 
132  switch (*p++) {
133 
134  case 'y':
135  if (step > st_start) {
136  return NGX_ERROR;
137  }
138  step = st_year;
139  max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365);
140  scale = 60 * 60 * 24 * 365;
141  break;
142 
143  case 'M':
144  if (step >= st_month) {
145  return NGX_ERROR;
146  }
147  step = st_month;
148  max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30);
149  scale = 60 * 60 * 24 * 30;
150  break;
151 
152  case 'w':
153  if (step >= st_week) {
154  return NGX_ERROR;
155  }
156  step = st_week;
157  max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7);
158  scale = 60 * 60 * 24 * 7;
159  break;
160 
161  case 'd':
162  if (step >= st_day) {
163  return NGX_ERROR;
164  }
165  step = st_day;
166  max = NGX_MAX_INT32_VALUE / (60 * 60 * 24);
167  scale = 60 * 60 * 24;
168  break;
169 
170  case 'h':
171  if (step >= st_hour) {
172  return NGX_ERROR;
173  }
174  step = st_hour;
175  max = NGX_MAX_INT32_VALUE / (60 * 60);
176  scale = 60 * 60;
177  break;
178 
179  case 'm':
180  if (*p == 's') {
181  if (is_sec || step >= st_msec) {
182  return NGX_ERROR;
183  }
184  p++;
185  step = st_msec;
186  max = NGX_MAX_INT32_VALUE;
187  scale = 1;
188  break;
189  }
190 
191  if (step >= st_min) {
192  return NGX_ERROR;
193  }
194  step = st_min;
195  max = NGX_MAX_INT32_VALUE / 60;
196  scale = 60;
197  break;
198 
199  case 's':
200  if (step >= st_sec) {
201  return NGX_ERROR;
202  }
203  step = st_sec;
204  max = NGX_MAX_INT32_VALUE;
205  scale = 1;
206  break;
207 
208  case ' ':
209  if (step >= st_sec) {
210  return NGX_ERROR;
211  }
212  step = st_last;
213  max = NGX_MAX_INT32_VALUE;
214  scale = 1;
215  break;
216 
217  default:
218  return NGX_ERROR;
219  }
220 
221  if (step != st_msec && !is_sec) {
222  scale *= 1000;
223  max /= 1000;
224  }
225 
226  if ((ngx_uint_t) value > max) {
227  return NGX_ERROR;
228  }
229 
230  total += value * scale;
231 
232  if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) {
233  return NGX_ERROR;
234  }
235 
236  value = 0;
237  scale = is_sec ? 1 : 1000;
238 
239  while (p < last && *p == ' ') {
240  p++;
241  }
242  }
243 
244  if (valid) {
245  return total + value * scale;
246  }
247 
248  return NGX_ERROR;
249 }