aboutsummaryrefslogtreecommitdiff
path: root/project/dclib/dclib-numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'project/dclib/dclib-numeric.c')
-rw-r--r--project/dclib/dclib-numeric.c395
1 files changed, 303 insertions, 92 deletions
diff --git a/project/dclib/dclib-numeric.c b/project/dclib/dclib-numeric.c
index 8be5cf6..138053d 100644
--- a/project/dclib/dclib-numeric.c
+++ b/project/dclib/dclib-numeric.c
@@ -1950,6 +1950,7 @@ mem_t EncodeByModeMem
s64 timezone_adjust_sec = -1;
s64 timezone_adjust_usec = -1;
+s64 timezone_adjust_nsec = -1;
int timezone_adjust_isdst = -1;
///////////////////////////////////////////////////////////////////////////////
@@ -1959,10 +1960,11 @@ void SetupTimezone ( bool force )
if ( force || timezone_adjust_sec == -1 )
{
timezone_adjust_sec = GetTimezoneAdjust(GetTimeSec(false));
- timezone_adjust_usec = 1000000ll * timezone_adjust_sec;
- TRACE("TZ: %s,%s, %ld, %d => %lld %lld\n",
+ timezone_adjust_usec = USEC_PER_SEC * timezone_adjust_sec;
+ timezone_adjust_nsec = NSEC_PER_SEC * timezone_adjust_sec;
+ TRACE("TZ: %s,%s, %ld, %d => %lld %lld %lld\n",
tzname[0], tzname[1], timezone, daylight,
- timezone_adjust_sec, timezone_adjust_usec );
+ timezone_adjust_sec, timezone_adjust_usec, timezone_adjust_nsec );
}
}
@@ -1993,41 +1995,76 @@ int GetTimezoneAdjust ( time_t tim )
///////////////////////////////////////////////////////////////////////////////
-struct timeval GetTimeOfDay ( bool localtime )
+static u_sec_t AdjustLocalTime ( u_sec_t sec )
{
static uint last_hour = 0;
+ const uint hour = sec / 3600;
+ if ( last_hour != hour )
+ {
+ last_hour = hour;
+ SetupTimezone(true);
+ }
+ return sec - timezone_adjust_sec;
+}
+
+//-----------------------------------------------------------------------------
+
+struct timeval GetTimeOfDay ( bool localtime )
+{
struct timeval tval;
gettimeofday(&tval,NULL);
if (localtime)
+ tval.tv_sec = AdjustLocalTime(tval.tv_sec);
+ return tval;
+}
+
+//-----------------------------------------------------------------------------
+
+struct timespec GetClockTime ( bool localtime )
+{
+ struct timespec ts;
+
+ #if HAVE_CLOCK_GETTIME
+ if (!clock_gettime(CLOCK_REALTIME,&ts))
{
- const uint hour = tval.tv_sec / 3600;
- if ( last_hour != hour )
- {
- last_hour = hour;
- SetupTimezone(true);
- }
- tval.tv_sec -= timezone_adjust_sec;
+ if (localtime)
+ ts.tv_sec = AdjustLocalTime(ts.tv_sec);
+ return ts;
}
- return tval;
+ #endif
+
+ // fall back
+ struct timeval tval = GetTimeOfDay(localtime);
+ ts.tv_sec = tval.tv_sec;
+ ts.tv_nsec = tval.tv_usec * NSEC_PER_USEC;
+ return ts;
}
///////////////////////////////////////////////////////////////////////////////
DayTime_t GetDayTime ( bool localtime )
{
- struct timeval tval = GetTimeOfDay(localtime);
div_t d;
-
DayTime_t dt;
- dt.time = tval.tv_sec;
- d = div(tval.tv_sec,86400);
+
+ #if HAVE_CLOCK_GETTIME
+ struct timespec tim = GetClockTime(localtime);
+ dt.usec = tim.tv_nsec / NSEC_PER_USEC;
+ dt.nsec = tim.tv_nsec;
+ #else
+ struct timeval tim = GetTimeOfDay(localtime);
+ dt.usec = tim.tv_usec;
+ dt.nsec = tim.tv_usec * NSEC_PER_USEC;
+ #endif
+
+ dt.time = tim.tv_sec;
+ d = div(tim.tv_sec,86400);
dt.day = d.quot;
d = div(d.rem,3600);
dt.hour = d.quot;
d = div(d.rem,60);
dt.min = d.quot;
dt.sec = d.rem;
- dt.usec = tval.tv_usec;
return dt;
}
@@ -2045,7 +2082,7 @@ u_sec_t GetTimeSec ( bool localtime )
u_msec_t GetTimeMSec ( bool localtime )
{
struct timeval tval = GetTimeOfDay(localtime);
- return (u64)(tval.tv_sec) * 1000ll + tval.tv_usec/1000;
+ return (u_msec_t)(tval.tv_sec) * MSEC_PER_SEC + tval.tv_usec/USEC_PER_MSEC;
}
///////////////////////////////////////////////////////////////////////////////
@@ -2053,7 +2090,15 @@ u_msec_t GetTimeMSec ( bool localtime )
u_usec_t GetTimeUSec ( bool localtime )
{
struct timeval tval = GetTimeOfDay(localtime);
- return (u64)(tval.tv_sec) * 1000000ll + tval.tv_usec;
+ return (u_usec_t)(tval.tv_sec) * USEC_PER_SEC + tval.tv_usec;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+u_nsec_t GetTimeNSec ( bool localtime )
+{
+ struct timespec ts = GetClockTime(localtime);
+ return (u_nsec_t)(ts.tv_sec) * NSEC_PER_SEC + ts.tv_nsec;
}
//
@@ -2067,24 +2112,36 @@ static time_t time_base = 0;
u_msec_t GetTimerMSec()
{
- struct timeval tval;
- gettimeofday(&tval,NULL);
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
if (!time_base)
- time_base = tval.tv_sec;
+ time_base = tv.tv_sec;
- return (u_msec_t)( tval.tv_sec - time_base ) * 1000 + tval.tv_usec/1000;
+ return (u_msec_t)( tv.tv_sec - time_base ) * MSEC_PER_SEC
+ + tv.tv_usec/USEC_PER_MSEC;
}
///////////////////////////////////////////////////////////////////////////////
u_usec_t GetTimerUSec()
{
- struct timeval tval;
- gettimeofday(&tval,NULL);
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
if (!time_base)
- time_base = tval.tv_sec;
+ time_base = tv.tv_sec;
- return (u_usec_t)( tval.tv_sec - time_base ) * 1000000 + tval.tv_usec;
+ return (u_usec_t)( tv.tv_sec - time_base ) * USEC_PER_SEC + tv.tv_usec;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+u_usec_t GetTimerNSec()
+{
+ struct timespec ts = GetClockTime(false);
+ if (!time_base)
+ time_base = ts.tv_sec;
+
+ return (u_usec_t)( ts.tv_sec - time_base ) * NSEC_PER_SEC + ts.tv_nsec;
}
///////////////////////////////////////////////////////////////////////////////
@@ -2128,14 +2185,14 @@ ccp PrintTimeByFormatUTC
///////////////////////////////////////////////////////////////////////////////
-ccp PrintUsecByFormat
+ccp PrintNSecByFormat
(
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- // 1-6 '@' in row replaced by digits of 'usec'
+ // 1-9 '@' in row replaced by digits of 'nsec'
time_t tim, // seconds since epoch
- uint usec // micro second of second
+ uint nsec // nanosecond of second
)
{
char buf[100];
@@ -2144,9 +2201,9 @@ ccp PrintUsecByFormat
char *at = strchr(buf,'@');
if (at)
{
- char ubuf[8];
- snprintf(ubuf,sizeof(ubuf),"%06u",usec);
- ccp src = ubuf;
+ char nbuf[10];
+ snprintf(nbuf,sizeof(nbuf),"%09u",nsec);
+ ccp src = nbuf;
while ( *at == '@' && *src )
*at++ = *src++;
}
@@ -2156,14 +2213,14 @@ ccp PrintUsecByFormat
//-----------------------------------------------------------------------------
-ccp PrintUsecByFormatUTC
+ccp PrintNSecByFormatUTC
(
// returns temporary buffer by GetCircBuf();
ccp format, // format string for strftime()
- // 1-6 '@' in row replaced by digits of 'usec'
+ // 1-9 '@' in row replaced by digits of 'nsec'
time_t tim, // seconds since epoch
- uint usec // micro second of second
+ uint nsec // nanosecond of second
)
{
char buf[100];
@@ -2172,9 +2229,9 @@ ccp PrintUsecByFormatUTC
char *at = strchr(buf,'@');
if (at)
{
- char ubuf[8];
- snprintf(ubuf,sizeof(ubuf),"%06u",usec);
- ccp src = ubuf;
+ char nbuf[10];
+ snprintf(nbuf,sizeof(nbuf),"%09u",nsec);
+ ccp src = nbuf;
while ( *at == '@' && *src )
*at++ = *src++;
}
@@ -2199,7 +2256,7 @@ ccp PrintTimevalByFormat
tv = &temp;
}
- return PrintUsecByFormat(format,tv->tv_sec,tv->tv_usec);
+ return PrintUSecByFormat(format,tv->tv_sec,tv->tv_usec);
}
//-----------------------------------------------------------------------------
@@ -2219,7 +2276,47 @@ ccp PrintTimevalByFormatUTC
tv = &temp;
}
- return PrintUsecByFormatUTC(format,tv->tv_sec,tv->tv_usec);
+ return PrintUSecByFormatUTC(format,tv->tv_sec,tv->tv_usec);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+ccp PrintTimespecByFormat
+(
+ // returns temporary buffer by GetCircBuf();
+
+ ccp format, // format string for strftime()
+ const struct timespec *ts // time to print, if NULL use GetClockTime(false)
+)
+{
+ struct timespec temp;
+ if (!ts)
+ {
+ temp = GetClockTime(true);
+ ts = &temp;
+ }
+
+ return PrintNSecByFormat(format,ts->tv_sec,ts->tv_nsec);
+}
+
+//-----------------------------------------------------------------------------
+
+ccp PrintTimespecByFormatUTC
+(
+ // returns temporary buffer by GetCircBuf();
+
+ ccp format, // format string for strftime()
+ const struct timespec *ts // time to print, if NULL use GetClockTime(false)
+)
+{
+ struct timespec temp;
+ if (!ts)
+ {
+ temp = GetClockTime(false);
+ ts = &temp;
+ }
+
+ return PrintNSecByFormatUTC(format,ts->tv_sec,ts->tv_nsec);
}
///////////////////////////////////////////////////////////////////////////////
@@ -2256,13 +2353,13 @@ ccp PrintTimeMSec
if (!buf)
buf = GetCircBuf( buf_size = 24 );
- time_t time = msec / 1000;
+ time_t time = msec / MSEC_PER_SEC;
struct tm *tm = localtime(&time);
uint len = strftime(buf,buf_size,"%F %T",tm);
if ( fraction && len + 4 < buf_size )
{
- len += snprintf(buf+len, buf_size-len, ".%03llu", msec % 1000 );
+ len += snprintf(buf+len, buf_size-len, ".%03llu", msec % MSEC_PER_SEC );
const uint pos = len - 3 + ( fraction < 3 ? fraction : 3 );
if ( pos < buf_size )
buf[pos] = 0;
@@ -2285,13 +2382,13 @@ ccp PrintTimeUSec
if (!buf)
buf = GetCircBuf( buf_size = 28 );
- time_t time = usec / 1000000;
+ time_t time = usec / USEC_PER_SEC;
struct tm *tm = localtime(&time);
uint len = strftime(buf,buf_size,"%F %T",tm);
if ( fraction && len + 7 < buf_size )
{
- len += snprintf(buf+len, buf_size-len, ".%06llu", usec % 1000000 );
+ len += snprintf(buf+len, buf_size-len, ".%06llu", usec % USEC_PER_SEC );
const uint pos = len - 6 + ( fraction < 6 ? fraction : 6 );
if ( pos < buf_size )
buf[pos] = 0;
@@ -2301,6 +2398,35 @@ ccp PrintTimeUSec
}
///////////////////////////////////////////////////////////////////////////////
+
+ccp PrintTimeNSec
+(
+ char * buf, // result buffer (>26 bytes are good)
+ // If NULL, a local circulary static buffer is used
+ size_t buf_size, // size of 'buf', ignored if buf==NULL
+ u_nsec_t nsec, // nanoseconds to print
+ uint fraction // number of digits (0-9) to print as fraction
+)
+{
+ if (!buf)
+ buf = GetCircBuf( buf_size = 32 );
+
+ time_t time = nsec / NSEC_PER_SEC;
+ struct tm *tm = localtime(&time);
+ uint len = strftime(buf,buf_size,"%F %T",tm);
+
+ if ( fraction && len + 10 < buf_size )
+ {
+ len += snprintf(buf+len, buf_size-len, ".%09llu", nsec % NSEC_PER_SEC );
+ const uint pos = len - 9 + ( fraction < 9 ? fraction : 9 );
+ if ( pos < buf_size )
+ buf[pos] = 0;
+ }
+
+ return buf;
+}
+
+///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ccp PrintTimerMSec
@@ -2345,7 +2471,7 @@ ccp PrintTimerUSec
// If NULL, a local circulary static buffer is used
size_t buf_size, // size of 'buf', ignored if buf==NULL
s_usec_t usec, // microseconds to print
- uint fraction // number of digits (0-3) to print as fraction
+ uint fraction // number of digits (0-6) to print as fraction
)
{
if ( !buf || buf_size < 4 )
@@ -2355,12 +2481,12 @@ ccp PrintTimerUSec
if (minus)
usec = -usec;
- u32 sec = (u64)usec / 1000000;
+ u32 sec = usec / USEC_PER_SEC;
if (fraction)
{
const uint len = snprintf(buf+1,buf_size-1,"%02d:%02d:%02d.%06lld",
- sec/3600, sec/60%60, sec%60, (u64)usec%1000000 );
+ sec/3600, sec/60%60, sec%60, (u64)usec%USEC_PER_SEC );
if ( len > 6 && fraction < 6 )
{
const uint pos = len - 6 + fraction;
@@ -2383,7 +2509,54 @@ ccp PrintTimerUSec
}
///////////////////////////////////////////////////////////////////////////////
+
+ccp PrintTimerNSec
+(
+ char * buf, // result buffer (>16 bytes are good)
+ // If NULL, a local circulary static buffer is used
+ size_t buf_size, // size of 'buf', ignored if buf==NULL
+ s_nsec_t nsec, // nanoseconds to print
+ uint fraction // number of digits (0-9) to print as fraction
+)
+{
+ if ( !buf || buf_size < 4 )
+ buf = GetCircBuf( buf_size = 24 );
+
+ const bool minus = nsec < 0;
+ if (minus)
+ nsec = -nsec;
+
+ u32 sec = nsec / NSEC_PER_SEC;
+
+ if (fraction)
+ {
+ const uint len = snprintf(buf+1,buf_size-1,"%02d:%02d:%02d.%09lld",
+ sec/3600, sec/60%60, sec%60, (u64)nsec%NSEC_PER_SEC );
+ if ( len > 9 && fraction < 9 )
+ {
+ const uint pos = len - 9 + fraction;
+ if ( pos < buf_size )
+ buf[pos] = 0;
+ }
+ }
+ else
+ snprintf(buf+1,buf_size-1,"%02d:%02d:%02d",
+ sec/3600, sec/60%60, sec%60 );
+
+ char *ptr = buf+1;
+ while ( *ptr == '0' || *ptr == ':' )
+ ptr++;
+ if ( *ptr == '.' )
+ ptr--;
+ if (minus)
+ *--ptr = '-';
+ return ptr;
+}
+
///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// [[nsec]] -> PrintTimer3U(), PrintTimer3N()
ccp PrintTimer3
(
@@ -2440,6 +2613,8 @@ ccp PrintTimer3
///////////////////////////////////////////////////////////////////////////////
+// [[nsec]] -> PrintTimer4U(), PrintTimer4N()
+
ccp PrintTimer4
(
char * buf, // result buffer (>4 bytes)
@@ -2495,6 +2670,8 @@ ccp PrintTimer4
///////////////////////////////////////////////////////////////////////////////
+// [[nsec]] -> PrintTimer6U(), PrintTimer6N()
+
ccp PrintTimer6
(
char * buf, // result buffer (>6 bytes)
@@ -2635,6 +2812,8 @@ ccp PrintTimer6
///////////////////////////////////////////////////////////////////////////////
+// [[nsec]] -> PrintTimer4Us(), PrintTimer4Ns()
+
ccp PrintTimerUSec4s
(
char * buf, // result buffer (>4 bytes)
@@ -2673,6 +2852,8 @@ ccp PrintTimerUSec4s
///////////////////////////////////////////////////////////////////////////////
+// [[nsec]] -> PrintTimer7Us(), PrintTimer7Ns()
+
ccp PrintTimerUSec7s
(
char * buf, // result buffer (>7 bytes)
@@ -2709,45 +2890,18 @@ ccp PrintTimerUSec7s
return buf;
}
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-
-#if 0
-u64 GetXTime ( xtime_t * xtime )
-{
- struct timeval tval;
- gettimeofday(&tval,0);
- if (!time_base)
- time_base = tval.tv_sec;
- if (!rel_usec_base)
- rel_usec_base = (u64)( tval.tv_sec - time_base ) * 1000000 + tval.tv_usec;
-
- const ull total_usec = 1000000ull * tval.tv_sec + tval.tv_usec;
-
- if (xtime)
- {
- xtime->time = tval.tv_sec;
- xtime->usec = tval.tv_usec;
- xtime->total_usec = total_usec;
- xtime->rel_usec = total_usec - rel_usec_base;
- }
- return total_usec;
-}
-#endif
-
//
///////////////////////////////////////////////////////////////////////////////
/////////////// scan date & time ///////////////
///////////////////////////////////////////////////////////////////////////////
-char * ScanInterval
+char * ScanIntervalTS
(
- time_t *res_time, // not NULL: store seconds
- u32 *res_usec, // not NULL: store micro seconds of second
+ struct timespec *res_ts, // not NULL: store result here
ccp source // source text
)
{
- uint days = 0, sec = 0, usec = 0;
+ uint days = 0, sec = 0, nsec = 0;
bool day_possible = true;
uint colon_count = 0;
char *src = source ? (char*)source : "";
@@ -2757,7 +2911,7 @@ char * ScanInterval
for(;;)
{
- if ( *src < '0' || *src >='9' )
+ if ( *src < '0' || *src >= '9' )
break;
ulong num = strtoul(src,&src,10);
if ( *src == 'd' && day_possible )
@@ -2779,11 +2933,11 @@ char * ScanInterval
{
src++;
uint i;
- for ( i = 0; i < 6; i++ )
+ for ( i = 0; i < 9; i++ )
{
- usec *= 10;
+ nsec *= 10;
if ( *src >= '0' && *src <= '9' )
- usec += *src++ - '0';
+ nsec += *src++ - '0';
}
while ( *src >= '0' && *src <= '9' )
src++;
@@ -2793,32 +2947,87 @@ char * ScanInterval
}
}
+ if (res_ts)
+ {
+ res_ts->tv_sec = days * SEC_PER_DAY + sec;
+ res_ts->tv_nsec = nsec;
+ }
+
+ return src;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+char * ScanIntervalUSec
+(
+ u_usec_t *res_usec, // not NULL: store total microseconds
+ ccp source // source text
+)
+{
+ struct timespec ts;
+ char *res = ScanIntervalTS(&ts,source);
+
+ if (res_usec)
+ *res_usec = ts.tv_sec * USEC_PER_SEC + ts.tv_nsec / NSEC_PER_USEC;
+ return res;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+char * ScanIntervalNSec
+(
+ u_nsec_t *res_nsec, // not NULL: store total nanoseconds
+ ccp source // source text
+)
+{
+ struct timespec ts;
+ char *res = ScanIntervalTS(&ts,source);
+
+ if (res_nsec)
+ *res_nsec = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
+ return res;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+char * ScanInterval
+(
+ time_t *res_time, // not NULL: store seconds
+ u32 *res_usec, // not NULL: store microseconds of second
+ ccp source // source text
+)
+{
+ struct timespec ts;
+ char *res = ScanIntervalTS(&ts,source);
+
if (res_time)
- *res_time = days * 86400 + sec;
+ *res_time = ts.tv_sec;
if (res_usec)
- *res_usec = usec;
- return src;
+ *res_usec = ts.tv_nsec / NSEC_PER_USEC;
+
+ return res;
}
///////////////////////////////////////////////////////////////////////////////
char * ScanInterval64
(
- u64 *res_usec, // not NULL: store total micro seconds
+ u64 *res_usec, // not NULL: store total microseconds
ccp source // source text
)
{
- time_t time;
- u32 usec;
- char *src = ScanInterval(&time,&usec,source);
+ u_usec_t usec;
+ char *res = ScanIntervalUSec(&usec,source);
if (res_usec)
- *res_usec = time * 1000000ull + usec;
- return src;
+ *res_usec = usec;
+ return res;
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+// [[nsec]]
+
char * ScanDateTime
(
time_t *res_time, // not NULL: store seconds here
@@ -2938,9 +3147,11 @@ char * ScanDateTime
///////////////////////////////////////////////////////////////////////////////
+// [[nsec]]
+
char * ScanDateTime64
(
- u64 *res_usec, // not NULL: store total micro seconds
+ u64 *res_usec, // not NULL: store total microseconds
ccp source, // source text
bool allow_delta // true: allow +|- interval
)