blob: 381f02565c1a1af8bbee35bdde0bfce7d42270b5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <axutil_duration.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <axutil_error.h>
#include <axutil_utils.h>
struct axutil_duration
{
axis2_bool_t is_negative;
int years;
int months;
int days;
int hours;
int mins;
double secs;
};
AXIS2_EXTERN axutil_duration_t *AXIS2_CALL
axutil_duration_create(
axutil_env_t *env)
{
return axutil_duration_create_from_values(env, 0, 0, 0, 0, 0, 0, 0.0);
}
AXIS2_EXTERN axutil_duration_t *AXIS2_CALL
axutil_duration_create_from_values(
const axutil_env_t *env,
axis2_bool_t negative,
int years,
int months,
int days,
int hours,
int minutes,
double seconds)
{
axutil_duration_t *duration = NULL;
AXIS2_ENV_CHECK(env, NULL);
duration = (axutil_duration_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_duration_t));
if(!duration)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
return NULL;
}
duration->is_negative = negative;
if(years > -1)
{
duration->years = years;
}
else
{
duration->years = 0;
}
if(months > -1)
{
duration->months = months;
}
else
{
duration->months = 0;
}
if(days > -1)
{
duration->days = days;
}
else
{
duration->days = 0;
}
if(hours > -1)
{
duration->hours = hours;
}
else
{
duration->hours = 0;
}
if(minutes > -1)
{
duration->mins = minutes;
}
else
{
duration->mins = 0;
}
if(seconds >= 0)
{
duration->secs = seconds;
}
else
{
duration->secs = 0.0;
}
return duration;
}
AXIS2_EXTERN axutil_duration_t *AXIS2_CALL
axutil_duration_create_from_string(
const axutil_env_t *env,
const axis2_char_t *duration_str)
{
axutil_duration_t *duration = NULL;
duration = (axutil_duration_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_duration_t));
if(!duration)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory");
return NULL;
}
axutil_duration_deserialize_duration(duration, env, duration_str);
return duration;
}
/***************************Function implementation****************************/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_free(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(duration)
{
AXIS2_FREE(env->allocator, duration);
duration = NULL;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_deserialize_duration(
axutil_duration_t *duration,
const axutil_env_t *env,
const axis2_char_t *duration_str)
{
const axis2_char_t *cur = duration_str;
double num;
int num_type = 0;
unsigned int seq = 0;
const char desig[] = { 'Y', 'M', 'D', 'H', 'M', 'S' };
AXIS2_PARAM_CHECK(env->error, duration, AXIS2_FAILURE);
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
duration->secs = 0;
if(!duration_str)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
return AXIS2_FAILURE;
}
if(*cur == '-')
{
duration->is_negative = 1;
cur++;
}
if(*cur++ != 'P')
{
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
duration->secs = 0;
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
return AXIS2_FAILURE;
}
if(!*cur)
{
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
duration->secs = 0;
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
return AXIS2_FAILURE;
}
while(*cur)
{
if(seq >= sizeof(desig))
{
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours = duration->mins
= 0;
duration->secs = 0;
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
return AXIS2_FAILURE;
}
if(*cur == 'T')
{
if(!(seq > 3))
{
seq = 3;
cur++;
}
else
{
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours
= duration->mins = 0;
duration->secs = 0;
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
return AXIS2_FAILURE;
}
}
num = 0;
if((*cur < '0') || (*cur > '9'))
num_type = -1;
else
{
num_type = 0;
while((*cur >= '0') && (*cur <= '9'))
{
num = num * 10 + (*cur - '0');
cur++;
}
}
if(!num_type && (*cur == '.'))
{
double mult = 1;
cur++;
if((*cur < '0') || (*cur > '9'))
num_type = -1;
else
num_type = 1;
while((*cur >= '0') && (*cur <= '9'))
{
mult /= 10;
num += (*cur - '0') * mult;
cur++;
}
}
if((num_type == -1) || (*cur == 0))
{
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours = duration->mins
= 0;
duration->secs = 0;
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE, AXIS2_FAILURE);
return AXIS2_FAILURE;
}
while(seq < sizeof(desig))
{
if(*cur == desig[seq])
{
num_type = 0;
/*if (seq < (sizeof(desig) - 1))
{
duration->is_negative = AXIS2_FALSE;
duration->years = duration->months = duration->days = duration->hours = duration->mins = 0;
duration->secs = 0;
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NONE,
AXIS2_FAILURE);
return AXIS2_FAILURE;
}*/
switch(seq)
{
case 0:
duration->years = (int)num;
seq++;
break;
case 1:
duration->months = (int)num;
seq++;
break;
case 2:
duration->days = (int)num;
seq++;
break;
case 3:
duration->hours = (int)num;
seq++;
break;
case 4:
duration->mins = (int)num;
seq++;
break;
case 5:
duration->secs = num;
seq++;
break;
}
break;
}
if((++seq == 3) || (seq == 6))
return AXIS2_SUCCESS;
}
cur++;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN char *AXIS2_CALL
axutil_duration_serialize_duration(
axutil_duration_t *duration,
const axutil_env_t *env)
{
axis2_char_t *duration_str = NULL;
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
duration_str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 64);
if(duration->is_negative == 0)
sprintf(duration_str, "P%dY%dM%dDT%dH%dM%fS", duration->years, duration->months,
duration->days, duration->hours, duration->mins, duration->secs);
else
sprintf(duration_str, "-P%dY%dM%dDT%dH%dM%fS", duration->years, duration->months,
duration->days, duration->hours, duration->mins, duration->secs);
return duration_str;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_duration(
axutil_duration_t *duration,
const axutil_env_t *env,
axis2_bool_t negative,
int years,
int months,
int days,
int hours,
int mins,
double seconds)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(years > -1)
duration->years = years;
if(months > -1)
duration->months = months;
if(days > -1)
duration->days = days;
if(hours > -1)
duration->hours = hours;
if(mins > -1)
duration->mins = mins;
if(seconds >= 0)
duration->secs = seconds;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_years(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->years;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_years(
axutil_duration_t *duration,
const axutil_env_t *env,
int years)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(years > -1)
{
duration->years = years;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_months(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->months;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_months(
axutil_duration_t *duration,
const axutil_env_t *env,
int months)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(months > -1)
{
duration->months = months;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_days(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->days;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_days(
axutil_duration_t *duration,
const axutil_env_t *env,
int days)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(days > -1)
{
duration->days = days;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_hours(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->hours;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_hours(
axutil_duration_t *duration,
const axutil_env_t *env,
int hours)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(hours > -1)
{
duration->hours = hours;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN int AXIS2_CALL
axutil_duration_get_mins(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->mins;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_mins(
axutil_duration_t *duration,
const axutil_env_t *env,
int mins)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(mins > -1)
{
duration->mins = mins;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN double AXIS2_CALL
axutil_duration_get_seconds(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->secs;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_seconds(
axutil_duration_t *duration,
const axutil_env_t *env,
double seconds)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
if(seconds >= 0)
{
duration->secs = seconds;
}
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_duration_get_is_negative(
axutil_duration_t *duration,
const axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
return duration->is_negative;
}
AXIS2_EXTERN axis2_status_t AXIS2_CALL
axutil_duration_set_is_negative(
axutil_duration_t *duration,
const axutil_env_t *env,
axis2_bool_t is_negative)
{
AXIS2_ENV_CHECK(env, AXIS2_FAILURE);
duration->is_negative = is_negative;
return AXIS2_SUCCESS;
}
AXIS2_EXTERN axis2_bool_t AXIS2_CALL
axutil_duration_compare(
axutil_duration_t *duration_one,
axutil_duration_t *duration_two,
axutil_env_t *env)
{
AXIS2_ENV_CHECK(env, AXIS2_FALSE);
if(!duration_one || !duration_two)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE);
return AXIS2_FALSE;
}
if(duration_one->is_negative != duration_two->is_negative)
return AXIS2_FALSE;
if(duration_one->years != duration_two->years)
return AXIS2_FALSE;
if(duration_one->months != duration_two->months)
return AXIS2_FALSE;
if(duration_one->days != duration_two->days)
return AXIS2_FALSE;
if(duration_one->hours != duration_two->hours)
return AXIS2_FALSE;
if(duration_one->mins != duration_two->mins)
return AXIS2_FALSE;
if(duration_one->secs != duration_two->secs)
return AXIS2_FALSE;
return AXIS2_SUCCESS;
}