Implement faster formatting for format_iso8601 and format_common_log
This commit is contained in:
parent
df401f57a2
commit
de2a855572
96
src/util.cc
96
src/util.cc
|
@ -167,7 +167,7 @@ std::string quote_string(const std::string& target)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
Iterator cpydig(Iterator d, int n, size_t len)
|
Iterator cpydig(Iterator d, uint32_t n, size_t len)
|
||||||
{
|
{
|
||||||
auto p = d + len - 1;
|
auto p = d + len - 1;
|
||||||
|
|
||||||
|
@ -223,6 +223,100 @@ std::string http_date(time_t t)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string common_log_date(time_t t)
|
||||||
|
{
|
||||||
|
struct tm tms;
|
||||||
|
|
||||||
|
if(localtime_r(&t, &tms) == nullptr) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format data like this:
|
||||||
|
// 03/Jul/2014:00:19:38 +0900
|
||||||
|
std::string res;
|
||||||
|
res.resize(26);
|
||||||
|
|
||||||
|
auto p = std::begin(res);
|
||||||
|
|
||||||
|
p = cpydig(p, tms.tm_mday, 2);
|
||||||
|
*p++ = '/';
|
||||||
|
auto s = MONTH[tms.tm_mon];
|
||||||
|
p = std::copy(s, s + 3, p);
|
||||||
|
*p++ = '/';
|
||||||
|
p = cpydig(p, tms.tm_year + 1900, 4);
|
||||||
|
*p++ = ':';
|
||||||
|
p = cpydig(p, tms.tm_hour, 2);
|
||||||
|
*p++ = ':';
|
||||||
|
p = cpydig(p, tms.tm_min, 2);
|
||||||
|
*p++ = ':';
|
||||||
|
p = cpydig(p, tms.tm_sec, 2);
|
||||||
|
*p++ = ' ';
|
||||||
|
|
||||||
|
auto gmtoff = tms.tm_gmtoff;
|
||||||
|
if(gmtoff >= 0) {
|
||||||
|
*p++ = '+';
|
||||||
|
} else {
|
||||||
|
*p++ = '-';
|
||||||
|
gmtoff = -gmtoff;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = cpydig(p, gmtoff / 3600, 2);
|
||||||
|
p = cpydig(p, (gmtoff % 3600) / 60, 2);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string iso8601_date(int64_t ms)
|
||||||
|
{
|
||||||
|
time_t sec = ms / 1000;
|
||||||
|
|
||||||
|
tm tms;
|
||||||
|
if(localtime_r(&sec, &tms) == nullptr) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format data like this:
|
||||||
|
// 2014-11-15T12:58:24.741Z
|
||||||
|
// 2014-11-15T12:58:24.741+09:00
|
||||||
|
std::string res;
|
||||||
|
res.resize(29);
|
||||||
|
|
||||||
|
auto p = std::begin(res);
|
||||||
|
|
||||||
|
p = cpydig(p, tms.tm_year + 1900, 4);
|
||||||
|
*p++ = '-';
|
||||||
|
p = cpydig(p, tms.tm_mon + 1, 2);
|
||||||
|
*p++ = '-';
|
||||||
|
p = cpydig(p, tms.tm_mday, 2);
|
||||||
|
*p++ = 'T';
|
||||||
|
p = cpydig(p, tms.tm_hour, 2);
|
||||||
|
*p++ = ':';
|
||||||
|
p = cpydig(p, tms.tm_min, 2);
|
||||||
|
*p++ = ':';
|
||||||
|
p = cpydig(p, tms.tm_sec, 2);
|
||||||
|
*p++ = '.';
|
||||||
|
p = cpydig(p, ms % 1000, 3);
|
||||||
|
|
||||||
|
auto gmtoff = tms.tm_gmtoff;
|
||||||
|
if(gmtoff == 0) {
|
||||||
|
*p++ = 'Z';
|
||||||
|
} else {
|
||||||
|
if(gmtoff > 0) {
|
||||||
|
*p++ = '+';
|
||||||
|
} else {
|
||||||
|
*p++ = '-';
|
||||||
|
gmtoff = -gmtoff;
|
||||||
|
}
|
||||||
|
p = cpydig(p, gmtoff / 3600, 2);
|
||||||
|
*p++ = ':';
|
||||||
|
p = cpydig(p, (gmtoff % 3600) / 60, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
res.resize(p - std::begin(res));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
time_t parse_http_date(const std::string& s)
|
time_t parse_http_date(const std::string& s)
|
||||||
{
|
{
|
||||||
tm tm;
|
tm tm;
|
||||||
|
|
39
src/util.h
39
src/util.h
|
@ -212,6 +212,14 @@ std::string format_hex(const unsigned char *s, size_t len);
|
||||||
|
|
||||||
std::string http_date(time_t t);
|
std::string http_date(time_t t);
|
||||||
|
|
||||||
|
// Returns given time |t| from epoch in Common Log format (e.g.,
|
||||||
|
// 03/Jul/2014:00:19:38 +0900)
|
||||||
|
std::string common_log_date(time_t t);
|
||||||
|
|
||||||
|
// Returns given millisecond |ms| from epoch in ISO 8601 format (e.g.,
|
||||||
|
// 2014-11-15T12:58:24.741Z)
|
||||||
|
std::string iso8601_date(int64_t ms);
|
||||||
|
|
||||||
time_t parse_http_date(const std::string& s);
|
time_t parse_http_date(const std::string& s);
|
||||||
|
|
||||||
template<typename InputIterator1, typename InputIterator2>
|
template<typename InputIterator1, typename InputIterator2>
|
||||||
|
@ -489,21 +497,11 @@ std::vector<unsigned char> get_default_alpn();
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string format_common_log(const T& tp)
|
std::string format_common_log(const T& tp)
|
||||||
{
|
{
|
||||||
auto t = std::chrono::duration_cast<std::chrono::milliseconds>
|
auto t = std::chrono::duration_cast<std::chrono::seconds>
|
||||||
(tp.time_since_epoch());
|
(tp.time_since_epoch());
|
||||||
time_t sec = t.count() / 1000;
|
return common_log_date(t.count());
|
||||||
|
|
||||||
tm tms;
|
|
||||||
if(localtime_r(&sec, &tms) == nullptr) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
char buf[32];
|
|
||||||
|
|
||||||
strftime(buf, sizeof(buf), "%d/%b/%Y:%T %z", &tms);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns given time |tp| in ISO 8601 format (e.g.,
|
// Returns given time |tp| in ISO 8601 format (e.g.,
|
||||||
// 2014-11-15T12:58:24.741Z)
|
// 2014-11-15T12:58:24.741Z)
|
||||||
// Expected type of |tp| is std::chrono::timepoint
|
// Expected type of |tp| is std::chrono::timepoint
|
||||||
|
@ -512,20 +510,7 @@ std::string format_iso8601(const T& tp)
|
||||||
{
|
{
|
||||||
auto t = std::chrono::duration_cast<std::chrono::milliseconds>
|
auto t = std::chrono::duration_cast<std::chrono::milliseconds>
|
||||||
(tp.time_since_epoch());
|
(tp.time_since_epoch());
|
||||||
time_t sec = t.count() / 1000;
|
return iso8601_date(t.count());
|
||||||
|
|
||||||
tm tms;
|
|
||||||
if(gmtime_r(&sec, &tms) == nullptr) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
char buf[128];
|
|
||||||
|
|
||||||
auto nwrite = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tms);
|
|
||||||
snprintf(&buf[nwrite], sizeof(buf) - nwrite, ".%03ldZ",
|
|
||||||
static_cast<int>(t.count() % 1000));
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the system precision of the template parameter |Clock| as
|
// Return the system precision of the template parameter |Clock| as
|
||||||
|
|
Loading…
Reference in New Issue