/build/ldns-BsTNRO/ldns-1.9.2/duration.c
Go to the documentation of this file.
/*
* $Id: duration.c 4518 2011-02-24 15:39:09Z matthijs $
*
* Copyright (c) 2009 NLNet Labs. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <ldns/config.h>
#include <ldns/duration.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
ldns_duration_type*
ldns_duration_create(void)
{
ldns_duration_type* duration;
duration = malloc(sizeof(ldns_duration_type));
if (!duration) {
return NULL;
}
duration->years = 0;
duration->months = 0;
duration->weeks = 0;
duration->days = 0;
duration->hours = 0;
duration->minutes = 0;
duration->seconds = 0;
return duration;
}
int
ldns_duration_compare(const ldns_duration_type* d1, const ldns_duration_type* d2)
{
if (!d1 && !d2) {
return 0;
}
if (!d1 || !d2) {
return d1?-1:1;
}
if (d1->years != d2->years) {
return (int) (d1->years - d2->years);
}
if (d1->months != d2->months) {
return (int) (d1->months - d2->months);
}
if (d1->weeks != d2->weeks) {
return (int) (d1->weeks - d2->weeks);
}
if (d1->days != d2->days) {
return (int) (d1->days - d2->days);
}
if (d1->hours != d2->hours) {
return (int) (d1->hours - d2->hours);
}
if (d1->minutes != d2->minutes) {
return (int) (d1->minutes - d2->minutes);
}
if (d1->seconds != d2->seconds) {
return (int) (d1->seconds - d2->seconds);
}
return 0;
}
ldns_duration_type*
ldns_duration_create_from_string(const char* str)
{
ldns_duration_type* duration = ldns_duration_create();
char* P, *X, *T, *W;
int not_weeks = 0;
if (!duration) {
return NULL;
}
if (!str) {
return duration;
}
P = strchr(str, 'P');
if (!P) {
ldns_duration_cleanup(duration);
return NULL;
}
T = strchr(str, 'T');
X = strchr(str, 'Y');
if (X) {
duration->years = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strchr(str, 'M');
if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
duration->months = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strchr(str, 'D');
if (X) {
duration->days = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
if (T) {
str = T;
not_weeks = 1;
}
X = strchr(str, 'H');
if (X && T) {
duration->hours = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strrchr(str, 'M');
if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
duration->minutes = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
X = strchr(str, 'S');
if (X && T) {
duration->seconds = (time_t) atoi(str+1);
str = X;
not_weeks = 1;
}
W = strchr(str, 'W');
if (W) {
if (not_weeks) {
ldns_duration_cleanup(duration);
return NULL;
} else {
duration->weeks = (time_t) atoi(str+1);
}
}
return duration;
}
static inline int dur_scan_print(char **buf, char *eob, char c, time_t t)
{
if (t > 0) {
int r = snprintf(*buf, eob - *buf, "%u%c", (unsigned)t, c);
if (r < 0 || (*buf += r) >= eob)
return -1;
}
return 0;
}
char*
ldns_duration2string(const ldns_duration_type* d)
{
/* Max string size should be 7 * 40 + 3 on a 127 bits machine
* So 300 (< 273) is more than enough.
*/
char buf[300] = "P0D", *eob = buf + sizeof(buf), *p = buf + 1;
if (!d)
return NULL;
if (dur_scan_print(&p, eob, 'Y', d->years)
|| dur_scan_print(&p, eob, 'M', d->months)
|| dur_scan_print(&p, eob, 'W', d->weeks)
|| dur_scan_print(&p, eob, 'D', d->days))
return NULL;
if (d->hours || d->minutes || d->seconds) {
if (p > (eob - 2))
return NULL; /* Error; no space left on buf for 'T' */
*p++ = 'T'; *p = 0;
if (dur_scan_print(&p, eob, 'H', d->hours)
|| dur_scan_print(&p, eob, 'M', d->minutes)
|| dur_scan_print(&p, eob, 'S', d->seconds))
return NULL;
}
return strdup(buf);
}
time_t
ldns_duration2time(const ldns_duration_type* duration)
{
time_t period = 0;
if (duration) {
period += (duration->seconds);
period += (duration->minutes)*60;
period += (duration->hours)*3600;
period += (duration->days)*86400;
period += (duration->weeks)*86400*7;
period += (duration->months)*86400*31;
period += (duration->years)*86400*365;
/* [TODO] calculate correct number of days in this month/year */
/*
if (duration->months || duration->years) {
}
*/
}
return period;
}
void
ldns_duration_cleanup(ldns_duration_type* duration)
{
if (!duration) {
return;
}
free(duration);
return;
}
config.h
ldns_duration2time
time_t ldns_duration2time(const ldns_duration_type *duration)
Convert a duration to a time.
Definition duration.c:246
ldns_duration_cleanup
void ldns_duration_cleanup(ldns_duration_type *duration)
Clean up duration.
Definition duration.c:274
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
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_duration2string
char * ldns_duration2string(const ldns_duration_type *d)
Convert a duration to a string.
Definition duration.c:211
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_type
struct ldns_duration_struct ldns_duration_type
This file is copied from the OpenDNSSEC source repository and only slightly adapted to make it fit.
Definition duration.h:50
ldns_duration_struct::weeks
time_t weeks
Definition duration.h:55
ldns_duration_struct::seconds
time_t seconds
Definition duration.h:59
ldns_duration_struct::months
time_t months
Definition duration.h:54
ldns_duration_struct::years
time_t years
Definition duration.h:53
ldns_duration_struct::days
time_t days
Definition duration.h:56
ldns_duration_struct::hours
time_t hours
Definition duration.h:57
ldns_duration_struct::minutes
time_t minutes
Definition duration.h:58