version 1.1.2.1, 2013/03/05 13:09:51
|
version 1.4, 2014/01/29 14:16:54
|
Line 1
|
Line 1
|
|
/************************************************************************* |
|
* (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org> |
|
* by Michael Pounov <misho@elwix.org> |
|
* |
|
* $Author$ |
|
* $Id$ |
|
* |
|
************************************************************************** |
|
The ELWIX and AITNET software is distributed under the following |
|
terms: |
|
|
|
All of the documentation and software included in the ELWIX and AITNET |
|
Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
|
|
|
Copyright 2004 - 2014 |
|
by Michael Pounov <misho@elwix.org>. 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. |
|
3. All advertising materials mentioning features or use of this software |
|
must display the following acknowledgement: |
|
This product includes software developed by Michael Pounov <misho@elwix.org> |
|
ELWIX - Embedded LightWeight unIX and its contributors. |
|
4. Neither the name of AITNET nor the names of its contributors |
|
may be used to endorse or promote products derived from this software |
|
without specific prior written permission. |
|
|
|
THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 "global.h" |
#include "global.h" |
|
|
|
|
|
struct stridx { |
|
char *str; |
|
int id; |
|
}; |
|
|
|
static struct stridx months[] = { |
|
{ "jan", 0 }, { "january", 0 }, |
|
{ "feb", 1 }, { "february", 1 }, |
|
{ "mar", 2 }, { "march", 2 }, |
|
{ "apr", 3 }, { "april", 3 }, |
|
{ "may", 4 }, |
|
{ "jun", 5 }, { "june", 5 }, |
|
{ "jul", 6 }, { "july", 6 }, |
|
{ "aug", 7 }, { "august", 7 }, |
|
{ "sep", 8 }, { "september", 8 }, |
|
{ "oct", 9 }, { "october", 9 }, |
|
{ "nov", 10 }, { "november", 10 }, |
|
{ "dec", 11 }, { "december", 11 }, |
|
}; |
|
|
|
static struct stridx wdays[] = { |
|
{ "sun", 0 }, { "sunday", 0 }, |
|
{ "mon", 1 }, { "monday", 1 }, |
|
{ "tue", 2 }, { "tuesday", 2 }, |
|
{ "wed", 3 }, { "wednesday", 3 }, |
|
{ "thu", 4 }, { "thursday", 4 }, |
|
{ "fri", 5 }, { "friday", 5 }, |
|
{ "sat", 6 }, { "saturday", 6 }, |
|
}; |
|
|
|
static int |
|
stridx_compare(struct stridx * __restrict a, struct stridx * __restrict b) |
|
{ |
|
return strcmp(a->str, b->str); |
|
} |
|
|
|
static int |
|
search4month(char * psMonth, int * __restrict id) |
|
{ |
|
static int sorted = 0; |
|
struct stridx *el, item = { psMonth, 0 }; |
|
|
|
if (!psMonth) |
|
return -1; |
|
|
|
if (!sorted) { |
|
qsort(months, sizeof(months) / sizeof(struct stridx), sizeof(struct stridx), |
|
(int (*)(const void*, const void*)) stridx_compare); |
|
sorted++; |
|
} |
|
|
|
str_Lower(psMonth); |
|
el = bsearch(&item, months, sizeof(months) / sizeof(struct stridx), sizeof(struct stridx), |
|
(int (*)(const void*, const void*)) stridx_compare); |
|
if (el && id) |
|
*id = el->id; |
|
|
|
return !!el; |
|
} |
|
|
|
static int |
|
search4wday(char * __restrict psWDay, int * __restrict id) |
|
{ |
|
static int sorted = 0; |
|
struct stridx *el, item = { psWDay, 0 }; |
|
|
|
if (!psWDay) |
|
return -1; |
|
|
|
if (!sorted) { |
|
qsort(wdays, sizeof(wdays) / sizeof(struct stridx), sizeof(struct stridx), |
|
(int (*)(const void*, const void*)) stridx_compare); |
|
sorted++; |
|
} |
|
|
|
str_Lower(psWDay); |
|
el = bsearch(&item, wdays, sizeof(wdays) / sizeof(struct stridx), sizeof(struct stridx), |
|
(int (*)(const void*, const void*)) stridx_compare); |
|
if (el && id) |
|
*id = el->id; |
|
|
|
return !!el; |
|
} |
|
|
|
|
|
/* |
|
* time_Parse() - Parse and make unix time from standart time strings ... |
|
* |
|
* @csTime = Time string |
|
* return: =-1 error or !=-1 converted time |
|
*/ |
|
time_t |
|
time_Parse(const char *csTime) |
|
{ |
|
struct tm tm; |
|
char *s; |
|
int tm_sec, tm_min, tm_hour, tm_mday, tm_year, tm_mon, tm_wday; |
|
char str_mon[512], str_wday[512]; |
|
time_t tim; |
|
|
|
memset(&tm, 0, sizeof tm); |
|
memset(&str_mon, 0, sizeof str_mon); |
|
memset(&str_wday, 0, sizeof str_wday); |
|
|
|
for (s = (char*) csTime; isspace(*s); s++); |
|
|
|
/* |
|
* And do the sscanfs. WARNING: you can add more formats here, |
|
* but be careful! You can easily screw up the parsing of existing |
|
* formats when you add new ones. The order is important. |
|
*/ |
|
|
|
/* DD-mth-YY HH:MM:SS GMT */ |
|
if (sscanf(s, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT", |
|
&tm_mday, str_mon, &tm_year, |
|
&tm_hour, &tm_min, &tm_sec) == 6 && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_mday = tm_mday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_year = tm_year; |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
} |
|
/* DD mth YY HH:MM:SS GMT */ |
|
else if (sscanf(s, "%d %400[a-zA-Z] %d %d:%d:%d GMT", |
|
&tm_mday, str_mon, &tm_year, |
|
&tm_hour, &tm_min, &tm_sec) == 6 && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_mday = tm_mday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_year = tm_year; |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
} |
|
/* HH:MM:SS GMT DD-mth-YY */ |
|
else if (sscanf(s, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d", |
|
&tm_hour, &tm_min, &tm_sec, |
|
&tm_mday, str_mon, &tm_year) == 6 && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
tm.tm_mday = tm_mday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_year = tm_year; |
|
} |
|
/* HH:MM:SS GMT DD mth YY */ |
|
else if (sscanf(s, "%d:%d:%d GMT %d %400[a-zA-Z] %d", |
|
&tm_hour, &tm_min, &tm_sec, |
|
&tm_mday, str_mon, &tm_year) == 6 && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
tm.tm_mday = tm_mday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_year = tm_year; |
|
} |
|
/* wdy, DD-mth-YY HH:MM:SS GMT */ |
|
else if (sscanf(s, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d GMT", |
|
str_wday, &tm_mday, str_mon, |
|
&tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && |
|
search4wday(str_wday, &tm_wday) && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_wday = tm_wday; |
|
tm.tm_mday = tm_mday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_year = tm_year; |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
} |
|
/* wdy, DD mth YY HH:MM:SS GMT */ |
|
else if (sscanf(s, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d GMT", |
|
str_wday, &tm_mday, str_mon, |
|
&tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && |
|
search4wday(str_wday, &tm_wday) && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_wday = tm_wday; |
|
tm.tm_mday = tm_mday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_year = tm_year; |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
} |
|
/* wdy mth DD HH:MM:SS GMT YY */ |
|
else if (sscanf(s, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d", |
|
str_wday, str_mon, &tm_mday, |
|
&tm_hour, &tm_min, &tm_sec, &tm_year) == 7 && |
|
search4wday(str_wday, &tm_wday) && |
|
search4month(str_mon, &tm_mon)) { |
|
tm.tm_wday = tm_wday; |
|
tm.tm_mon = tm_mon; |
|
tm.tm_mday = tm_mday; |
|
tm.tm_hour = tm_hour; |
|
tm.tm_min = tm_min; |
|
tm.tm_sec = tm_sec; |
|
tm.tm_year = tm_year; |
|
} else { |
|
elwix_SetErr(EINVAL, "Invalid date/time format"); |
|
return (time_t) -1; |
|
} |
|
|
|
if (tm.tm_year > 1900) |
|
tm.tm_year -= 1900; |
|
else if (tm.tm_year < 70) |
|
tm.tm_year += 100; |
|
|
|
if ((tim = timegm(&tm)) == (time_t) -1) |
|
elwix_SetErr(EINVAL, "Invalid date/time format"); |
|
return tim; |
|
} |
|
|
|
/* |
|
* time_rdtsc() - Get TSC timer value from CPU |
|
* |
|
* return: TSC in nanoseconds |
|
*/ |
|
uint64_t |
|
time_rdtsc(void) |
|
{ |
|
#if defined(i386) || defined(__i386__) |
|
/* i386 */ |
|
uint32_t hi, lo; |
|
|
|
asm volatile("rdtsc" : "=d" (hi), "=a" (lo)); |
|
return (((uint64_t) hi << 32) | (uint64_t) lo); |
|
#elif defined(amd64) || defined(__amd64__) || \ |
|
defined(x86_64) || defined(__x86_64__) |
|
/* amd64 */ |
|
uint64_t res; |
|
|
|
asm volatile("rdtsc" : "=a" (res)); |
|
return res; |
|
#else |
|
/* unsupported for this architecture, get time by ordinary way */ |
|
struct timespec ts = { 0, 0LL }; |
|
|
|
clock_gettime(CLOCK_UPTIME_PRECISE, &ts); |
|
return ((uint64_t) ts.tv_sec * 1000000000 + ts.tv_nsec); |
|
#endif |
|
} |