src: Always use our own faster simpler timegm, use it to calculate gmtoff

This commit is contained in:
Tatsuhiro Tsujikawa 2015-06-29 23:14:54 +09:00
parent 515c313073
commit 51ef646678
6 changed files with 41 additions and 54 deletions

View File

@ -152,6 +152,10 @@ int main(int argc, char *argv[]) {
shrpx::test_util_format_duration) ||
!CU_add_test(pSuite, "util_starts_with", shrpx::test_util_starts_with) ||
!CU_add_test(pSuite, "util_ends_with", shrpx::test_util_ends_with) ||
!CU_add_test(pSuite, "util_parse_http_date",
shrpx::test_util_parse_http_date) ||
!CU_add_test(pSuite, "util_localtime_date",
shrpx::test_util_localtime_date) ||
!CU_add_test(pSuite, "gzip_inflate", test_nghttp2_gzip_inflate) ||
!CU_add_test(pSuite, "buffer_write", nghttp2::test_buffer_write) ||
!CU_add_test(pSuite, "pool_recycle", nghttp2::test_pool_recycle) ||

View File

@ -24,8 +24,6 @@
*/
#include "timegm.h"
#ifndef HAVE_TIMEGM
#include <inttypes.h>
/* Counter the number of leap year in the range [0, y). The |y| is the
@ -35,15 +33,6 @@ static int count_leap_year(int y) {
return y / 4 - y / 100 + y / 400;
}
/* Returns nonzero if the |y| is the leap year. The |y| is the year,
including century (e.g., 2012) */
static int is_leap_year(int y) {
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
}
/* The number of days before ith month begins */
static int daysum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
/* Based on the algorithm of Python 2.7 calendar.timegm. */
time_t timegm(struct tm *tm) {
int days;
@ -53,11 +42,7 @@ time_t timegm(struct tm *tm) {
return -1;
}
num_leap_year = count_leap_year(tm->tm_year + 1900) - count_leap_year(1970);
days = (tm->tm_year - 70) * 365 + num_leap_year + daysum[tm->tm_mon] +
tm->tm_mday - 1;
if (tm->tm_mon >= 2 && is_leap_year(tm->tm_year + 1900)) {
++days;
}
days = (tm->tm_year - 70) * 365 + num_leap_year + tm->tm_yday;
t = ((int64_t)days * 24 + tm->tm_hour) * 3600 + tm->tm_min * 60 + tm->tm_sec;
if (sizeof(time_t) == 4) {
if (t < INT32_MIN || t > INT32_MAX) {
@ -66,5 +51,3 @@ time_t timegm(struct tm *tm) {
}
return (time_t)t;
}
#endif /* !HAVE_TIMEGM */

View File

@ -37,12 +37,8 @@ extern "C" {
#include <time.h>
#endif // HAVE_TIME_H
#ifndef HAVE_TIMEGM
time_t timegm(struct tm *tm);
#endif /* HAVE_TIMEGM */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -254,7 +254,6 @@ std::string common_log_date(time_t t) {
return "";
}
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
// Format data like this:
// 03/Jul/2014:00:19:38 +0900
std::string res;
@ -276,7 +275,11 @@ std::string common_log_date(time_t t) {
p = cpydig(p, tms.tm_sec, 2);
*p++ = ' ';
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = tms.tm_gmtoff;
#else // !HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = timegm(&tms) - t;
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
if (gmtoff >= 0) {
*p++ = '+';
} else {
@ -288,13 +291,6 @@ std::string common_log_date(time_t t) {
p = cpydig(p, (gmtoff % 3600) / 60, 2);
return res;
#else // !HAVE_STRUCT_TM_TM_GMTOFF
char buf[32];
strftime(buf, sizeof(buf), "%d/%b/%Y:%T %z", &tms);
return buf;
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
}
std::string iso8601_date(int64_t ms) {
@ -305,7 +301,6 @@ std::string iso8601_date(int64_t ms) {
return "";
}
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
// Format data like this:
// 2014-11-15T12:58:24.741Z
// 2014-11-15T12:58:24.741+09:00
@ -328,7 +323,11 @@ std::string iso8601_date(int64_t ms) {
*p++ = '.';
p = cpydig(p, ms % 1000, 3);
#ifdef HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = tms.tm_gmtoff;
#else // !HAVE_STRUCT_TM_TM_GMTOFF
auto gmtoff = timegm(&tms) - sec;
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
if (gmtoff == 0) {
*p++ = 'Z';
} else {
@ -346,29 +345,6 @@ std::string iso8601_date(int64_t ms) {
res.resize(p - std::begin(res));
return res;
#else // !HAVE_STRUCT_TM_TM_GMTOFF
char buf[128];
auto nwrite = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tms);
nwrite += snprintf(&buf[nwrite], sizeof(buf) - nwrite, ".%03d",
static_cast<int>(ms % 1000));
auto nzone = strftime(&buf[nwrite], sizeof(buf) - nwrite, "%z", &tms);
// %z of strftime writes +hhmm or -hhmm not Z, +hh:mm or -hh:mm. Do
// %nothing if nzone is not 5. we don't know how to cope with this.
if (nzone == 5) {
if (memcmp(&buf[nwrite], "+0000", 5) == 0) {
// 0000 should be Z
memcpy(&buf[nwrite], "Z", 2);
} else {
// Move mm part to right by 1 including terminal \0
memmove(&buf[nwrite + 4], &buf[nwrite + 3], 3);
// Insert ':' between hh and mm
buf[nwrite + 3] = ':';
}
}
return buf;
#endif // !HAVE_STRUCT_TM_TM_GMTOFF
}
time_t parse_http_date(const std::string &s) {

View File

@ -367,4 +367,30 @@ void test_util_ends_with(void) {
CU_ASSERT(!util::iendsWith("ofoo", "fo"));
}
void test_util_parse_http_date(void) {
CU_ASSERT(1001939696 ==
util::parse_http_date("Mon, 1 Oct 2001 12:34:56 GMT"));
}
void test_util_localtime_date(void) {
auto tz = getenv("TZ");
if (tz) {
tz = strdup(tz);
}
setenv("TZ", ":Pacific/Auckland", 1);
tzset();
CU_ASSERT_STRING_EQUAL("02/Oct/2001:00:34:56 +1200",
util::common_log_date(1001939696).c_str());
CU_ASSERT_STRING_EQUAL("2001-10-02T00:34:56.123+12:00",
util::iso8601_date(1001939696000LL + 123).c_str());
if (tz) {
setenv("TZ", tz, 1);
} else {
unsetenv("TZ");
}
tzset();
}
} // namespace shrpx

View File

@ -53,6 +53,8 @@ void test_util_duration_str(void);
void test_util_format_duration(void);
void test_util_starts_with(void);
void test_util_ends_with(void);
void test_util_parse_http_date(void);
void test_util_localtime_date(void);
} // namespace shrpx