00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00040 #include <ldns/config.h>
00041 #include <ldns/duration.h>
00042
00043 #include <stdio.h>
00044 #include <stdlib.h>
00045 #include <string.h>
00046 #include <time.h>
00047
00048
00053 ldns_duration_type*
00054 ldns_duration_create(void)
00055 {
00056 ldns_duration_type* duration;
00057
00058 duration = malloc(sizeof(ldns_duration_type));
00059 if (!duration) {
00060 return NULL;
00061 }
00062 duration->years = 0;
00063 duration->months = 0;
00064 duration->weeks = 0;
00065 duration->days = 0;
00066 duration->hours = 0;
00067 duration->minutes = 0;
00068 duration->seconds = 0;
00069 return duration;
00070 }
00071
00072
00077 int
00078 ldns_duration_compare(ldns_duration_type* d1, ldns_duration_type* d2)
00079 {
00080 if (!d1 && !d2) {
00081 return 0;
00082 }
00083 if (!d1 || !d2) {
00084 return d1?-1:1;
00085 }
00086
00087 if (d1->years != d2->years) {
00088 return (int) (d1->years - d2->years);
00089 }
00090 if (d1->months != d2->months) {
00091 return (int) (d1->months - d2->months);
00092 }
00093 if (d1->weeks != d2->weeks) {
00094 return (int) (d1->weeks - d2->weeks);
00095 }
00096 if (d1->days != d2->days) {
00097 return (int) (d1->days - d2->days);
00098 }
00099 if (d1->hours != d2->hours) {
00100 return (int) (d1->hours - d2->hours);
00101 }
00102 if (d1->minutes != d2->minutes) {
00103 return (int) (d1->minutes - d2->minutes);
00104 }
00105 if (d1->seconds != d2->seconds) {
00106 return (int) (d1->seconds - d2->seconds);
00107 }
00108
00109 return 0;
00110 }
00111
00112
00117 ldns_duration_type*
00118 ldns_duration_create_from_string(const char* str)
00119 {
00120 ldns_duration_type* duration = ldns_duration_create();
00121 char* P, *X, *T, *W;
00122 int not_weeks = 0;
00123
00124 if (!duration) {
00125 return NULL;
00126 }
00127 if (!str) {
00128 return duration;
00129 }
00130
00131 P = strchr(str, 'P');
00132 if (!P) {
00133 ldns_duration_cleanup(duration);
00134 return NULL;
00135 }
00136
00137 T = strchr(str, 'T');
00138 X = strchr(str, 'Y');
00139 if (X) {
00140 duration->years = (time_t) atoi(str+1);
00141 str = X;
00142 not_weeks = 1;
00143 }
00144 X = strchr(str, 'M');
00145 if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
00146 duration->months = (time_t) atoi(str+1);
00147 str = X;
00148 not_weeks = 1;
00149 }
00150 X = strchr(str, 'D');
00151 if (X) {
00152 duration->days = (time_t) atoi(str+1);
00153 str = X;
00154 not_weeks = 1;
00155 }
00156 if (T) {
00157 str = T;
00158 not_weeks = 1;
00159 }
00160 X = strchr(str, 'H');
00161 if (X && T) {
00162 duration->hours = (time_t) atoi(str+1);
00163 str = X;
00164 not_weeks = 1;
00165 }
00166 X = strrchr(str, 'M');
00167 if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
00168 duration->minutes = (time_t) atoi(str+1);
00169 str = X;
00170 not_weeks = 1;
00171 }
00172 X = strchr(str, 'S');
00173 if (X && T) {
00174 duration->seconds = (time_t) atoi(str+1);
00175 str = X;
00176 not_weeks = 1;
00177 }
00178
00179 W = strchr(str, 'W');
00180 if (W) {
00181 if (not_weeks) {
00182 ldns_duration_cleanup(duration);
00183 return NULL;
00184 } else {
00185 duration->weeks = (time_t) atoi(str+1);
00186 str = W;
00187 }
00188 }
00189 return duration;
00190 }
00191
00192
00197 static size_t
00198 digits_in_number(time_t duration)
00199 {
00200 uint32_t period = (uint32_t) duration;
00201 size_t count = 0;
00202
00203 while (period > 0) {
00204 count++;
00205 period /= 10;
00206 }
00207 return count;
00208 }
00209
00210
00215 char*
00216 ldns_duration2string(ldns_duration_type* duration)
00217 {
00218 char* str = NULL, *num = NULL;
00219 size_t count = 2;
00220 int T = 0;
00221
00222 if (!duration) {
00223 return NULL;
00224 }
00225
00226 if (duration->years > 0) {
00227 count = count + 1 + digits_in_number(duration->years);
00228 }
00229 if (duration->months > 0) {
00230 count = count + 1 + digits_in_number(duration->months);
00231 }
00232 if (duration->weeks > 0) {
00233 count = count + 1 + digits_in_number(duration->weeks);
00234 }
00235 if (duration->days > 0) {
00236 count = count + 1 + digits_in_number(duration->days);
00237 }
00238 if (duration->hours > 0) {
00239 count = count + 1 + digits_in_number(duration->hours);
00240 T = 1;
00241 }
00242 if (duration->minutes > 0) {
00243 count = count + 1 + digits_in_number(duration->minutes);
00244 T = 1;
00245 }
00246 if (duration->seconds > 0) {
00247 count = count + 1 + digits_in_number(duration->seconds);
00248 T = 1;
00249 }
00250 if (T) {
00251 count++;
00252 }
00253
00254 str = (char*) calloc(count, sizeof(char));
00255 str[0] = 'P';
00256 str[1] = '\0';
00257
00258 if (duration->years > 0) {
00259 count = digits_in_number(duration->years);
00260 num = (char*) calloc(count+2, sizeof(char));
00261 snprintf(num, count+2, "%uY", (unsigned int) duration->years);
00262 str = strncat(str, num, count+2);
00263 free((void*) num);
00264 }
00265 if (duration->months > 0) {
00266 count = digits_in_number(duration->months);
00267 num = (char*) calloc(count+2, sizeof(char));
00268 snprintf(num, count+2, "%uM", (unsigned int) duration->months);
00269 str = strncat(str, num, count+2);
00270 free((void*) num);
00271 }
00272 if (duration->weeks > 0) {
00273 count = digits_in_number(duration->weeks);
00274 num = (char*) calloc(count+2, sizeof(char));
00275 snprintf(num, count+2, "%uW", (unsigned int) duration->weeks);
00276 str = strncat(str, num, count+2);
00277 free((void*) num);
00278 }
00279 if (duration->days > 0) {
00280 count = digits_in_number(duration->days);
00281 num = (char*) calloc(count+2, sizeof(char));
00282 snprintf(num, count+2, "%uD", (unsigned int) duration->days);
00283 str = strncat(str, num, count+2);
00284 free((void*) num);
00285 }
00286 if (T) {
00287 str = strncat(str, "T", 1);
00288 }
00289 if (duration->hours > 0) {
00290 count = digits_in_number(duration->hours);
00291 num = (char*) calloc(count+2, sizeof(char));
00292 snprintf(num, count+2, "%uH", (unsigned int) duration->hours);
00293 str = strncat(str, num, count+2);
00294 free((void*) num);
00295 }
00296 if (duration->minutes > 0) {
00297 count = digits_in_number(duration->minutes);
00298 num = (char*) calloc(count+2, sizeof(char));
00299 snprintf(num, count+2, "%uM", (unsigned int) duration->minutes);
00300 str = strncat(str, num, count+2);
00301 free((void*) num);
00302 }
00303 if (duration->seconds > 0) {
00304 count = digits_in_number(duration->seconds);
00305 num = (char*) calloc(count+2, sizeof(char));
00306 snprintf(num, count+2, "%uS", (unsigned int) duration->seconds);
00307 str = strncat(str, num, count+2);
00308 free((void*) num);
00309 }
00310 return str;
00311 }
00312
00313
00318 time_t
00319 ldns_duration2time(ldns_duration_type* duration)
00320 {
00321 time_t period = 0;
00322
00323 if (duration) {
00324 period += (duration->seconds);
00325 period += (duration->minutes)*60;
00326 period += (duration->hours)*3600;
00327 period += (duration->days)*86400;
00328 period += (duration->weeks)*86400*7;
00329 period += (duration->months)*86400*31;
00330 period += (duration->years)*86400*365;
00331
00332
00333
00334
00335
00336
00337 }
00338 return period;
00339 }
00340
00341
00346 void
00347 ldns_duration_cleanup(ldns_duration_type* duration)
00348 {
00349 if (!duration) {
00350 return;
00351 }
00352 free(duration);
00353 return;
00354 }