mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	Added a TIME_UNIT enumeration, and a function that converts a string to one of the enumerated values. Also, added functions that create and initialize a timeval object using a specified value, and unit type. Change-Id: Ic31a1c3262a44f77a5ef78bfc85dcf69a8d47392
		
			
				
	
	
		
			146 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Asterisk -- An open source telephony toolkit.
 | |
|  *
 | |
|  * Copyright (C) 2021, Sangoma Technologies Corporation
 | |
|  *
 | |
|  * See http://www.asterisk.org for more information about
 | |
|  * the Asterisk project. Please do not directly contact
 | |
|  * any of the maintainers of this project for assistance;
 | |
|  * the project provides a web site, mailing lists and IRC
 | |
|  * channels for your use.
 | |
|  *
 | |
|  * This program is free software, distributed under the terms of
 | |
|  * the GNU General Public License Version 2. See the LICENSE file
 | |
|  * at the top of the source tree.
 | |
|  */
 | |
| 
 | |
| /*! \file
 | |
|  *
 | |
|  * \brief Date/Time utility functions
 | |
|  */
 | |
| 
 | |
| /*** MODULEINFO
 | |
| 	<support_level>core</support_level>
 | |
|  ***/
 | |
| 
 | |
| #include <inttypes.h>
 | |
| #include <string.h>
 | |
| #include <time.h>
 | |
| 
 | |
| #include "asterisk/time.h"
 | |
| 
 | |
| const char *nanosecond_labels[] = {"ns", "nsec", "nanosecond"};
 | |
| const char *microsecond_labels[] = {"us", "usec", "microsecond"};
 | |
| const char *millisecond_labels[] = {"ms", "msec", "millisecond"};
 | |
| const char *second_labels[] = {"s", "sec", "second"};
 | |
| const char *minute_labels[] = {"m", "min", "minute"};
 | |
| const char *hour_labels[] = {"h", "hr", "hour"};
 | |
| const char *day_labels[] = {"d", "", "day"};
 | |
| const char *week_labels[] = {"w", "wk", "week"};
 | |
| const char *month_labels[] = {"mo", "mth", "month"};
 | |
| const char *year_labels[] = {"y", "yr", "year"};
 | |
| 
 | |
| #define MAX_UNIT_LABELS 3
 | |
| 
 | |
| struct time_unit_labels {
 | |
| 	enum TIME_UNIT unit;
 | |
| 	const char **values;
 | |
| };
 | |
| 
 | |
| static struct time_unit_labels unit_labels[] = {
 | |
| 	{ TIME_UNIT_NANOSECOND, nanosecond_labels },
 | |
| 	{ TIME_UNIT_MICROSECOND, microsecond_labels },
 | |
| 	{ TIME_UNIT_MILLISECOND, millisecond_labels },
 | |
| 	{ TIME_UNIT_MONTH, month_labels }, /* Here so "mo" matches before "m" */
 | |
| 	{ TIME_UNIT_SECOND, second_labels },
 | |
| 	{ TIME_UNIT_MINUTE, minute_labels },
 | |
| 	{ TIME_UNIT_HOUR, hour_labels },
 | |
| 	{ TIME_UNIT_DAY, day_labels },
 | |
| 	{ TIME_UNIT_WEEK, week_labels },
 | |
| 	{ TIME_UNIT_YEAR, year_labels },
 | |
| };
 | |
| 
 | |
| const unsigned int unit_labels_size = sizeof(unit_labels) / sizeof(0[unit_labels]);
 | |
| 
 | |
| enum TIME_UNIT ast_time_str_to_unit(const char *unit)
 | |
| {
 | |
| 	size_t i, j;
 | |
| 
 | |
| 	if (!unit) {
 | |
| 		return TIME_UNIT_ERROR;
 | |
| 	}
 | |
| 
 | |
| 	for (i = 0; i < unit_labels_size; ++i) {
 | |
| 		for (j = 0; j < MAX_UNIT_LABELS; ++j) {
 | |
| 			/*
 | |
| 			 * A lazy pluralization check. If the given unit string at least starts
 | |
| 			 * with a label assume a match.
 | |
| 			 */
 | |
| 			if (*unit_labels[i].values[j] && !strncasecmp(unit, unit_labels[i].values[j],
 | |
| 					strlen(unit_labels[i].values[j]))) {
 | |
| 				return unit_labels[i].unit;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return TIME_UNIT_ERROR;
 | |
| }
 | |
| 
 | |
| ast_suseconds_t ast_time_tv_to_usec(const struct timeval *tv)
 | |
| {
 | |
| 	return tv->tv_sec * 1000000 + tv->tv_usec;
 | |
| }
 | |
| 
 | |
| struct timeval ast_time_create(ast_time_t sec, ast_suseconds_t usec)
 | |
| {
 | |
| 	return ast_tv(sec, usec);
 | |
| }
 | |
| 
 | |
| /*!
 | |
|  * \brief Create a timeval first onverting the given microsecond value
 | |
|  *        into seconds and microseconds
 | |
|  *
 | |
|  * \param usec microsecond value
 | |
|  *
 | |
|  * \return A timeval structure
 | |
|  */
 | |
| static struct timeval normalize_and_create(unsigned long usec)
 | |
| {
 | |
| 	return ast_time_create(usec / 1000000, usec % 1000000);
 | |
| }
 | |
| 
 | |
| struct timeval ast_time_create_by_unit(unsigned long val, enum TIME_UNIT unit)
 | |
| {
 | |
| 	switch (unit) {
 | |
| 	case TIME_UNIT_NANOSECOND:
 | |
| 		return normalize_and_create(val / 1000);
 | |
| 	case TIME_UNIT_MICROSECOND:
 | |
| 		return normalize_and_create(val);
 | |
| 	case TIME_UNIT_MILLISECOND:
 | |
| 		return normalize_and_create(val * 1000);
 | |
| 	case TIME_UNIT_SECOND:
 | |
| 		return ast_time_create(val, 0);
 | |
| 	case TIME_UNIT_MINUTE:
 | |
| 		return ast_time_create(val * 60, 0);
 | |
| 	case TIME_UNIT_HOUR:
 | |
| 		return ast_time_create(val * 3600, 0);
 | |
| 	case TIME_UNIT_DAY:
 | |
| 		return ast_time_create(val * 86400, 0);
 | |
| 	case TIME_UNIT_WEEK:
 | |
| 		return ast_time_create(val * 604800, 0);
 | |
| 	case TIME_UNIT_MONTH:
 | |
| 		/* Using Gregorian mean month - 30.436875 * 86400 */
 | |
| 		return ast_time_create(val * 2629746, 0);
 | |
| 	case TIME_UNIT_YEAR:
 | |
| 		/* Using Gregorian year - 365.2425 * 86400 */
 | |
| 		return ast_time_create(val * 31556952, 0);
 | |
| 	default:
 | |
| 		return ast_time_create(0, 0);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| struct timeval ast_time_create_by_unit_str(unsigned long val, const char *unit)
 | |
| {
 | |
| 	return ast_time_create_by_unit(val, ast_time_str_to_unit(unit));
 | |
| }
 |