| /* | |
| * Copyright (C) Igor Sysoev | |
| */ | |
| #include <ngx_config.h> | |
| #include <ngx_core.h> | |
| ngx_int_t ngx_parse_size(ngx_str_t *line) | |
| { | |
| u_char last; | |
| size_t len; | |
| ngx_int_t scale, size; | |
| len = line->len; | |
| last = line->data[len - 1]; | |
| switch (last) { | |
| case 'K': | |
| case 'k': | |
| len--; | |
| scale = 1024; | |
| break; | |
| case 'M': | |
| case 'm': | |
| len--; | |
| scale = 1024 * 1024; | |
| break; | |
| default: | |
| scale = 1; | |
| } | |
| size = ngx_atoi(line->data, len); | |
| if (size == NGX_ERROR) { | |
| return NGX_ERROR; | |
| } | |
| size *= scale; | |
| return size; | |
| } | |
| ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_int_t sec) | |
| { | |
| size_t len; | |
| u_char *start, last; | |
| ngx_int_t value, total, scale; | |
| ngx_uint_t max, i; | |
| enum { | |
| st_start = 0, | |
| st_year, | |
| st_month, | |
| st_week, | |
| st_day, | |
| st_hour, | |
| st_min, | |
| st_sec, | |
| st_msec, | |
| st_last | |
| } step; | |
| start = line->data; | |
| len = 0; | |
| total = 0; | |
| step = sec ? st_start : st_month; | |
| for (i = 0; /* void */ ; i++) { | |
| if (i < line->len) { | |
| if (line->data[i] != ' ') { | |
| len++; | |
| continue; | |
| } | |
| if (line->data[i] == ' ' && len == 0) { | |
| start = &line->data[i + 1]; | |
| continue; | |
| } | |
| } | |
| if (len == 0) { | |
| break; | |
| } | |
| last = line->data[i - 1]; | |
| switch (last) { | |
| case 'y': | |
| if (step > st_start) { | |
| return NGX_ERROR; | |
| } | |
| step = st_year; | |
| len--; | |
| max = 68; | |
| scale = 60 * 60 * 24 * 365; | |
| break; | |
| case 'M': | |
| if (step > st_year) { | |
| return NGX_ERROR; | |
| } | |
| step = st_month; | |
| len--; | |
| max = 828; | |
| scale = 60 * 60 * 24 * 30; | |
| break; | |
| case 'w': | |
| if (step > st_month) { | |
| return NGX_ERROR; | |
| } | |
| step = st_week; | |
| len--; | |
| max = 3550; | |
| scale = 60 * 60 * 24 * 7; | |
| break; | |
| case 'd': | |
| if (step > st_week) { | |
| return NGX_ERROR; | |
| } | |
| step = st_day; | |
| len--; | |
| max = 24855; | |
| scale = 60 * 60 * 24; | |
| break; | |
| case 'h': | |
| if (step > st_day) { | |
| return NGX_ERROR; | |
| } | |
| step = st_hour; | |
| len--; | |
| max = 596523; | |
| scale = 60 * 60; | |
| break; | |
| case 'm': | |
| if (step > st_hour) { | |
| return NGX_ERROR; | |
| } | |
| step = st_min; | |
| len--; | |
| max = 35791394; | |
| scale = 60; | |
| break; | |
| case 's': | |
| len--; | |
| if (line->data[i - 2] == 'm') { | |
| if (sec || step > st_sec) { | |
| return NGX_ERROR; | |
| } | |
| step = st_msec; | |
| len--; | |
| max = 2147483647; | |
| scale = 1; | |
| break; | |
| } | |
| if (step > st_min) { | |
| return NGX_ERROR; | |
| } | |
| step = st_sec; | |
| max = 2147483647; | |
| scale = 1; | |
| break; | |
| default: | |
| step = st_last; | |
| max = 2147483647; | |
| scale = 1; | |
| } | |
| value = ngx_atoi(start, len); | |
| if (value == NGX_ERROR) { | |
| return NGX_ERROR; | |
| } | |
| if (step != st_msec && !sec) { | |
| scale *= 1000; | |
| max /= 1000; | |
| } | |
| if ((u_int) value > max) { | |
| return NGX_PARSE_LARGE_TIME; | |
| } | |
| total += value * scale; | |
| if ((u_int) total > 2147483647) { | |
| return NGX_PARSE_LARGE_TIME; | |
| } | |
| if (i >= line->len) { | |
| break; | |
| } | |
| len = 0; | |
| start = &line->data[i + 1]; | |
| } | |
| return total; | |
| } |