ldns  1.7.0
duration.c
Go to the documentation of this file.
1 /*
2  * $Id: duration.c 4518 2011-02-24 15:39:09Z matthijs $
3  *
4  * Copyright (c) 2009 NLNet Labs. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
40 #include <ldns/config.h>
41 #include <ldns/duration.h>
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <time.h>
47 
48 
55 {
56  ldns_duration_type* duration;
57 
58  duration = malloc(sizeof(ldns_duration_type));
59  if (!duration) {
60  return NULL;
61  }
62  duration->years = 0;
63  duration->months = 0;
64  duration->weeks = 0;
65  duration->days = 0;
66  duration->hours = 0;
67  duration->minutes = 0;
68  duration->seconds = 0;
69  return duration;
70 }
71 
72 
77 int
79 {
80  if (!d1 && !d2) {
81  return 0;
82  }
83  if (!d1 || !d2) {
84  return d1?-1:1;
85  }
86 
87  if (d1->years != d2->years) {
88  return (int) (d1->years - d2->years);
89  }
90  if (d1->months != d2->months) {
91  return (int) (d1->months - d2->months);
92  }
93  if (d1->weeks != d2->weeks) {
94  return (int) (d1->weeks - d2->weeks);
95  }
96  if (d1->days != d2->days) {
97  return (int) (d1->days - d2->days);
98  }
99  if (d1->hours != d2->hours) {
100  return (int) (d1->hours - d2->hours);
101  }
102  if (d1->minutes != d2->minutes) {
103  return (int) (d1->minutes - d2->minutes);
104  }
105  if (d1->seconds != d2->seconds) {
106  return (int) (d1->seconds - d2->seconds);
107  }
108 
109  return 0;
110 }
111 
112 
119 {
121  char* P, *X, *T, *W;
122  int not_weeks = 0;
123 
124  if (!duration) {
125  return NULL;
126  }
127  if (!str) {
128  return duration;
129  }
130 
131  P = strchr(str, 'P');
132  if (!P) {
133  ldns_duration_cleanup(duration);
134  return NULL;
135  }
136 
137  T = strchr(str, 'T');
138  X = strchr(str, 'Y');
139  if (X) {
140  duration->years = (time_t) atoi(str+1);
141  str = X;
142  not_weeks = 1;
143  }
144  X = strchr(str, 'M');
145  if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
146  duration->months = (time_t) atoi(str+1);
147  str = X;
148  not_weeks = 1;
149  }
150  X = strchr(str, 'D');
151  if (X) {
152  duration->days = (time_t) atoi(str+1);
153  str = X;
154  not_weeks = 1;
155  }
156  if (T) {
157  str = T;
158  not_weeks = 1;
159  }
160  X = strchr(str, 'H');
161  if (X && T) {
162  duration->hours = (time_t) atoi(str+1);
163  str = X;
164  not_weeks = 1;
165  }
166  X = strrchr(str, 'M');
167  if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
168  duration->minutes = (time_t) atoi(str+1);
169  str = X;
170  not_weeks = 1;
171  }
172  X = strchr(str, 'S');
173  if (X && T) {
174  duration->seconds = (time_t) atoi(str+1);
175  str = X;
176  not_weeks = 1;
177  }
178 
179  W = strchr(str, 'W');
180  if (W) {
181  if (not_weeks) {
182  ldns_duration_cleanup(duration);
183  return NULL;
184  } else {
185  duration->weeks = (time_t) atoi(str+1);
186  str = W;
187  }
188  }
189  return duration;
190 }
191 
192 
197 static size_t
198 digits_in_number(time_t duration)
199 {
200  uint32_t period = (uint32_t) duration;
201  size_t count = 0;
202 
203  while (period > 0) {
204  count++;
205  period /= 10;
206  }
207  return count;
208 }
209 
210 
215 char*
217 {
218  char* str = NULL, *num = NULL;
219  size_t count = 2;
220  int T = 0;
221 
222  if (!duration) {
223  return NULL;
224  }
225 
226  if (duration->years > 0) {
227  count = count + 1 + digits_in_number(duration->years);
228  }
229  if (duration->months > 0) {
230  count = count + 1 + digits_in_number(duration->months);
231  }
232  if (duration->weeks > 0) {
233  count = count + 1 + digits_in_number(duration->weeks);
234  }
235  if (duration->days > 0) {
236  count = count + 1 + digits_in_number(duration->days);
237  }
238  if (duration->hours > 0) {
239  count = count + 1 + digits_in_number(duration->hours);
240  T = 1;
241  }
242  if (duration->minutes > 0) {
243  count = count + 1 + digits_in_number(duration->minutes);
244  T = 1;
245  }
246  if (duration->seconds > 0) {
247  count = count + 1 + digits_in_number(duration->seconds);
248  T = 1;
249  }
250  if (T) {
251  count++;
252  }
253 
254  str = (char*) calloc(count, sizeof(char));
255  str[0] = 'P';
256  str[1] = '\0';
257 
258  if (duration->years > 0) {
259  count = digits_in_number(duration->years);
260  num = (char*) calloc(count+2, sizeof(char));
261  snprintf(num, count+2, "%uY", (unsigned int) duration->years);
262  str = strncat(str, num, count+2);
263  free((void*) num);
264  }
265  if (duration->months > 0) {
266  count = digits_in_number(duration->months);
267  num = (char*) calloc(count+2, sizeof(char));
268  snprintf(num, count+2, "%uM", (unsigned int) duration->months);
269  str = strncat(str, num, count+2);
270  free((void*) num);
271  }
272  if (duration->weeks > 0) {
273  count = digits_in_number(duration->weeks);
274  num = (char*) calloc(count+2, sizeof(char));
275  snprintf(num, count+2, "%uW", (unsigned int) duration->weeks);
276  str = strncat(str, num, count+2);
277  free((void*) num);
278  }
279  if (duration->days > 0) {
280  count = digits_in_number(duration->days);
281  num = (char*) calloc(count+2, sizeof(char));
282  snprintf(num, count+2, "%uD", (unsigned int) duration->days);
283  str = strncat(str, num, count+2);
284  free((void*) num);
285  }
286  if (T) {
287  str = strncat(str, "T", 1);
288  }
289  if (duration->hours > 0) {
290  count = digits_in_number(duration->hours);
291  num = (char*) calloc(count+2, sizeof(char));
292  snprintf(num, count+2, "%uH", (unsigned int) duration->hours);
293  str = strncat(str, num, count+2);
294  free((void*) num);
295  }
296  if (duration->minutes > 0) {
297  count = digits_in_number(duration->minutes);
298  num = (char*) calloc(count+2, sizeof(char));
299  snprintf(num, count+2, "%uM", (unsigned int) duration->minutes);
300  str = strncat(str, num, count+2);
301  free((void*) num);
302  }
303  if (duration->seconds > 0) {
304  count = digits_in_number(duration->seconds);
305  num = (char*) calloc(count+2, sizeof(char));
306  snprintf(num, count+2, "%uS", (unsigned int) duration->seconds);
307  str = strncat(str, num, count+2);
308  free((void*) num);
309  }
310  return str;
311 }
312 
313 
318 time_t
320 {
321  time_t period = 0;
322 
323  if (duration) {
324  period += (duration->seconds);
325  period += (duration->minutes)*60;
326  period += (duration->hours)*3600;
327  period += (duration->days)*86400;
328  period += (duration->weeks)*86400*7;
329  period += (duration->months)*86400*31;
330  period += (duration->years)*86400*365;
331 
332  /* [TODO] calculate correct number of days in this month/year */
333  /*
334  if (duration->months || duration->years) {
335  }
336  */
337  }
338  return period;
339 }
340 
341 
346 void
348 {
349  if (!duration) {
350  return;
351  }
352  free(duration);
353  return;
354 }
ldns_duration_struct::months
time_t months
Definition: duration.h:54
ldns_duration_create
ldns_duration_type * ldns_duration_create(void)
This file is copied from the OpenDNSSEC source repository and only slightly adapted to make it fit.
Definition: duration.c:54
ldns_duration_struct::days
time_t days
Definition: duration.h:56
ldns_duration2string
char * ldns_duration2string(const ldns_duration_type *duration)
Convert a duration to a string.
Definition: duration.c:216
ldns_duration_struct::years
time_t years
Definition: duration.h:53
ldns_duration_struct::seconds
time_t seconds
Definition: duration.h:59
duration.h
ldns_duration2time
time_t ldns_duration2time(const ldns_duration_type *duration)
Convert a duration to a time.
Definition: duration.c:319
config.h
ldns_duration_struct
Definition: duration.h:51
ldns_duration_cleanup
void ldns_duration_cleanup(ldns_duration_type *duration)
Clean up duration.
Definition: duration.c:347
ldns_duration_struct::weeks
time_t weeks
Definition: duration.h:55
ldns_duration_struct::minutes
time_t minutes
Definition: duration.h:58
ldns_duration_compare
int ldns_duration_compare(const ldns_duration_type *d1, const ldns_duration_type *d2)
Compare durations.
Definition: duration.c:78
ldns_duration_struct::hours
time_t hours
Definition: duration.h:57
ldns_duration_create_from_string
ldns_duration_type * ldns_duration_create_from_string(const char *str)
Create a duration from string.
Definition: duration.c:118