Apache HTTPD
md_time.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18
19#include <apr_lib.h>
20#include <apr_strings.h>
21#include <apr_time.h>
22
23#include "md.h"
24#include "md_time.h"
25
27{
28 return (period->start < period->end)? (period->end - period->start) : 0;
29}
30
36
38{
39 return (time >= period->start);
40}
41
43{
44 return (time >= period->start) && (time <= period->end);
45}
46
53
63
64static const char *duration_print(apr_pool_t *p, int roughly, apr_interval_time_t duration)
65{
66 const char *s = "", *sep = "";
67 long days = (long)(apr_time_sec(duration) / MD_SECS_PER_DAY);
68 int rem = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
69
70 s = roughly? "~" : "";
71 if (days > 0) {
72 s = apr_psprintf(p, "%s%ld days", s, days);
73 if (roughly) return s;
74 sep = " ";
75 }
76 if (rem > 0) {
77 int hours = (rem / MD_SECS_PER_HOUR);
79 if (hours > 0) {
80 s = apr_psprintf(p, "%s%s%d hours", s, sep, hours);
81 if (roughly) return s;
82 sep = " ";
83 }
84 if (rem > 0) {
85 int minutes = (rem / 60);
86 rem = (rem % 60);
87 if (minutes > 0) {
88 s = apr_psprintf(p, "%s%s%d minutes", s, sep, minutes);
89 if (roughly) return s;
90 sep = " ";
91 }
92 if (rem > 0) {
93 s = apr_psprintf(p, "%s%s%d seconds", s, sep, rem);
94 if (roughly) return s;
95 sep = " ";
96 }
97 }
98 }
99 else if (days == 0) {
100 s = "0 seconds";
101 if (duration != 0) {
102 s = apr_psprintf(p, "%d ms", (int)apr_time_msec(duration));
103 }
104 }
105 return s;
106}
107
109{
110 return duration_print(p, 0, duration);
111}
112
114{
115 return duration_print(p, 1, duration);
116}
117
118static const char *duration_format(apr_pool_t *p, apr_interval_time_t duration)
119{
120 const char *s = "0";
121 int units = (int)(apr_time_sec(duration) / MD_SECS_PER_DAY);
122 int rem = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
123
124 if (rem == 0) {
125 s = apr_psprintf(p, "%dd", units);
126 }
127 else {
128 units = (int)(apr_time_sec(duration) / MD_SECS_PER_HOUR);
129 rem = (int)(apr_time_sec(duration) % MD_SECS_PER_HOUR);
130 if (rem == 0) {
131 s = apr_psprintf(p, "%dh", units);
132 }
133 else {
134 units = (int)(apr_time_sec(duration) / 60);
135 rem = (int)(apr_time_sec(duration) % 60);
136 if (rem == 0) {
137 s = apr_psprintf(p, "%dmi", units);
138 }
139 else {
140 units = (int)(apr_time_sec(duration));
141 rem = (int)(apr_time_msec(duration) % 1000);
142 if (rem == 0) {
143 s = apr_psprintf(p, "%ds", units);
144 }
145 else {
146 s = apr_psprintf(p, "%dms", (int)(apr_time_msec(duration)));
147 }
148 }
149 }
150 }
151 return s;
152}
153
155{
156 return duration_format(p, duration);
157}
158
160 const char *def_unit)
161{
162 char *endp;
164
165 n = apr_strtoi64(value, &endp, 10);
166 if (errno) {
167 return errno;
168 }
169 if (!endp || !*endp) {
170 if (!def_unit) def_unit = "s";
171 }
172 else if (endp == value) {
173 return APR_EINVAL;
174 }
175 else {
176 def_unit = endp;
177 }
178
179 switch (*def_unit) {
180 case 'D':
181 case 'd':
183 break;
184 case 's':
185 case 'S':
187 break;
188 case 'h':
189 case 'H':
190 /* Time is in hours */
192 break;
193 case 'm':
194 case 'M':
195 switch (*(++def_unit)) {
196 /* Time is in milliseconds */
197 case 's':
198 case 'S':
199 *ptimeout = (apr_interval_time_t) n * 1000;
200 break;
201 /* Time is in minutes */
202 case 'i':
203 case 'I':
205 break;
206 default:
207 return APR_EGENERAL;
208 }
209 break;
210 default:
211 return APR_EGENERAL;
212 }
213 return APR_SUCCESS;
214}
215
217{
218 char *endp;
220
221 n = apr_strtoi64(value, &endp, 10);
222 if (errno) {
223 return errno;
224 }
225 if (*endp == '%') {
226 if (n < 0) {
227 return APR_BADARG;
228 }
229 *ppercent = (int)n;
230 return APR_SUCCESS;
231 }
232 return APR_EINVAL;
233}
234
237{
238 md_timeslice_t *ts;
239
240 ts = apr_pcalloc(p, sizeof(*ts));
241 ts->norm = norm;
242 ts->len = len;
243 *pts = ts;
244 return APR_SUCCESS;
245}
246
248 const char *val, apr_interval_time_t norm)
249{
250 md_timeslice_t *ts;
251 int percent = 0;
252
253 *pts = NULL;
254 if (!val) {
255 return "cannot parse NULL value";
256 }
257
258 ts = apr_pcalloc(p, sizeof(*ts));
259 if (md_duration_parse(&ts->len, val, "d") == APR_SUCCESS) {
260 *pts = ts;
261 return NULL;
262 }
263 else {
264 switch (percentage_parse(val, &percent)) {
265 case APR_SUCCESS:
266 ts->norm = norm;
267 ts->len = apr_time_from_sec((apr_time_sec(norm) * percent / 100L));
268 *pts = ts;
269 return NULL;
270 case APR_BADARG:
271 return "percent must be less than 100";
272 }
273 }
274 return "has unrecognized format";
275}
276
278 if (ts->norm > 0) {
279 int percent = (int)(((long)apr_time_sec(ts->len)) * 100L
280 / ((long)apr_time_sec(ts->norm)));
281 return apr_psprintf(p, "%d%%", percent);
282 }
283 return duration_format(p, ts->len);
284}
285
287 const md_timeslice_t *ts)
288{
290 apr_time_t duration = ts->len;
291
292 if (ts->norm > 0) {
293 int percent = (int)(((long)apr_time_sec(ts->len)) * 100L
294 / ((long)apr_time_sec(ts->norm)));
296 if (apr_time_sec(plen) > 100) {
297 duration = apr_time_from_sec(apr_time_sec(plen) * percent / 100);
298 }
299 else {
300 duration = plen * percent / 100;
301 }
302 }
303 r.start = period->end - duration;
304 r.end = period->end;
305 return r;
306}
307
309{
310 if (ts1 == ts2) return 1;
311 if (!ts1 || !ts2) return 0;
312 return (ts1->norm == ts2->norm) && (ts1->len == ts2->len);
313}
314
316{
318
319 c.start = (a->start > b->start)? a->start : b->start;
320 c.end = (a->end < b->end)? a->end : b->end;
321 if (c.start > c.end) {
322 c.start = c.end = 0;
323 }
324 return c;
325}
int n
Definition ap_regex.h:278
const char apr_size_t len
Definition ap_regex.h:187
APR general purpose library routines.
APR Strings library.
APR Time Library.
request_rec * r
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_BADARG
Definition apr_errno.h:459
#define APR_EINVAL
Definition apr_errno.h:711
apr_file_t apr_off_t start
apr_bucket apr_bucket_brigade * a
apr_size_t size
apr_uint32_t val
Definition apr_atomic.h:66
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
apr_vformatter_buff_t * c
Definition apr_lib.h:175
apr_pool_t * b
Definition apr_pools.h:529
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
const char * sep
const char char ** end
const char * s
Definition apr_strings.h:95
#define apr_time_msec(time)
Definition apr_time.h:69
#define APR_RFC822_DATE_LEN
Definition apr_time.h:186
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
apr_int64_t apr_time_t
Definition apr_time.h:45
#define apr_time_sec(time)
Definition apr_time.h:63
#define apr_time_from_sec(sec)
Definition apr_time.h:78
apr_pool_t * p
Definition md_event.c:32
const char * md_duration_print(apr_pool_t *p, apr_interval_time_t duration)
Definition md_time.c:108
apr_interval_time_t md_timeperiod_remaining(const md_timeperiod_t *period, apr_time_t time)
Definition md_time.c:47
static const char * duration_format(apr_pool_t *p, apr_interval_time_t duration)
Definition md_time.c:118
static const char * duration_print(apr_pool_t *p, int roughly, apr_interval_time_t duration)
Definition md_time.c:64
apr_status_t md_duration_parse(apr_interval_time_t *ptimeout, const char *value, const char *def_unit)
Definition md_time.c:159
int md_timeperiod_has_started(const md_timeperiod_t *period, apr_time_t time)
Definition md_time.c:37
md_timeperiod_t md_timeperiod_common(const md_timeperiod_t *a, const md_timeperiod_t *b)
Definition md_time.c:315
const char * md_timeslice_format(const md_timeslice_t *ts, apr_pool_t *p)
Definition md_time.c:277
const char * md_duration_roughly(apr_pool_t *p, apr_interval_time_t duration)
Definition md_time.c:113
int md_timeperiod_has_ended(const md_timeperiod_t *period, apr_time_t time)
Definition md_time.c:42
static apr_status_t percentage_parse(const char *value, int *ppercent)
Definition md_time.c:216
const char * md_duration_format(apr_pool_t *p, apr_interval_time_t duration)
Definition md_time.c:154
int md_timeslice_eq(const md_timeslice_t *ts1, const md_timeslice_t *ts2)
Definition md_time.c:308
apr_status_t md_timeslice_create(md_timeslice_t **pts, apr_pool_t *p, apr_interval_time_t norm, apr_interval_time_t len)
Definition md_time.c:235
char * md_timeperiod_print(apr_pool_t *p, const md_timeperiod_t *period)
Definition md_time.c:54
const char * md_timeslice_parse(md_timeslice_t **pts, apr_pool_t *p, const char *val, apr_interval_time_t norm)
Definition md_time.c:247
apr_time_t md_timeperiod_length(const md_timeperiod_t *period)
Definition md_time.c:26
md_timeperiod_t md_timeperiod_slice_before_end(const md_timeperiod_t *period, const md_timeslice_t *ts)
Definition md_time.c:286
int md_timeperiod_contains(const md_timeperiod_t *period, apr_time_t time)
Definition md_time.c:31
#define MD_SECS_PER_HOUR
Definition md_time.h:22
#define MD_SECS_PER_DAY
Definition md_time.h:23
return NULL
Definition mod_so.c:359
apr_off_t start
apr_interval_time_t len
Definition md_time.h:62
apr_interval_time_t norm
Definition md_time.h:61
apr_status_t apr_rfc822_date(char *date_str, apr_time_t t)
Definition timestr.c:42
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray