1fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn/* 2fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * Copyright (C) 2014 The Android Open Source Project 3fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * 4fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 5fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * you may not use this file except in compliance with the License. 6fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * You may obtain a copy of the License at 7fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * 8fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 9fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * 10fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 11fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 12fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * See the License for the specific language governing permissions and 14fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn * limitations under the License. 15fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn */ 16fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 17fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <ctype.h> 18fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <limits.h> 19fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <stdio.h> 20fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <string.h> 21fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 22aeaaf81c2cc8366ac4f66eb3d2fc85f9b8194982Mark Salyzyn#include <private/android_logger.h> 23fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 24facf94c74a2cc44f294c4789d36d5c7281c7bc3fMark Salyzyn#include "log_portability.h" 256d753faaf8694792433eb78c5c3572efd74a3d54Mark Salyzyn 266d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE const char log_time::default_format[] = "%m-%d %H:%M:%S.%q"; 276d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE const timespec log_time::EPOCH = { 0, 0 }; 28fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 29fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn// Add %#q for fractional seconds to standard strptime function 30fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 312ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE char* log_time::strptime(const char* s, const char* format) { 322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn time_t now; 33fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#ifdef __linux__ 342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *this = log_time(CLOCK_REALTIME); 352ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn now = tv_sec; 36fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else 372ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn time(&now); 382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_sec = now; 392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_nsec = 0; 40fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif 41fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct tm* ptm; 438a98535bcb48dfd4bfe3dfddddc82925a2f1502bYabin Cui#if !defined(_WIN32) 442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn struct tm tmBuf; 452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ptm = localtime_r(&now, &tmBuf); 46fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else 472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ptm = localtime(&now); 48fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif 49fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char fmt[strlen(format) + 1]; 512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn strcpy(fmt, format); 522ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 532ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* ret = const_cast<char*>(s); 542ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* cp; 552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn for (char* f = cp = fmt;; ++cp) { 562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!*cp) { 572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (f != cp) { 582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = ::strptime(ret, f, ptm); 592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 612ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*cp != '%') { 632ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn continue; 642ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 652ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn char* e = cp; 662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++e; 67fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#if (defined(__BIONIC__)) 682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*e == 's') { 692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *cp = '\0'; 702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*f) { 712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = ::strptime(ret, f, ptm); 722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!ret) { 732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_sec = 0; 772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (isdigit(*ret)) { 782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_sec = tv_sec * 10 + *ret - '0'; 792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++ret; 802ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 812ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn now = tv_sec; 828a98535bcb48dfd4bfe3dfddddc82925a2f1502bYabin Cui#if !defined(_WIN32) 832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ptm = localtime_r(&now, &tmBuf); 84fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else 852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ptm = localtime(&now); 86fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif 872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else 88fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif 892ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn { 902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned num = 0; 912ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (isdigit(*e)) { 922ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn num = num * 10 + *e - '0'; 932ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++e; 942ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 952ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*e != 'q') { 962ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn continue; 972ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 982ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *cp = '\0'; 992ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*f) { 1002ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ret = ::strptime(ret, f, ptm); 1012ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (!ret) { 1022ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn break; 103fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 1042ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1052ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn unsigned long mul = NS_PER_SEC; 1062ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (num == 0) { 1072ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn num = INT_MAX; 1082ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1092ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_nsec = 0; 1102ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn while (isdigit(*ret) && num && (mul > 1)) { 1112ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn --num; 1122ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn mul /= 10; 1132ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_nsec = tv_nsec + (*ret - '0') * mul; 1142ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++ret; 1152ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 116fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn } 1172ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn f = cp = e; 1182ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++f; 1192ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 120fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 1212ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (ret) { 1222ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_sec = mktime(ptm); 1232ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ret; 1242ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 125fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 1262ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn// Upon error, place a known value into the class, the current time. 127fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#ifdef __linux__ 1282ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn *this = log_time(CLOCK_REALTIME); 129fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else 1302ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn time(&now); 1312ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_sec = now; 1322ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn tv_nsec = 0; 133fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif 1342ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return ret; 135fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn} 136fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 1372ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator-=(const timespec& T) { 1382ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // No concept of negative time, clamp to EPOCH 1392ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*this <= T) { 1402ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return *this = EPOCH; 1412ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1422ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1432ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (this->tv_nsec < (unsigned long int)T.tv_nsec) { 1442ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn --this->tv_sec; 1452ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec; 1462ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 1472ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec -= T.tv_nsec; 1482ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1492ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_sec -= T.tv_sec; 1502ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1512ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return *this; 152fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn} 153fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn 1542ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator+=(const timespec& T) { 1552ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec += (unsigned long int)T.tv_nsec; 1562ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (this->tv_nsec >= NS_PER_SEC) { 1572ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec -= NS_PER_SEC; 1582ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++this->tv_sec; 1592ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1602ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_sec += T.tv_sec; 161decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn 1622ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return *this; 163decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn} 164decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn 1652ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator-=(const log_time& T) { 1662ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn // No concept of negative time, clamp to EPOCH 1672ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (*this <= T) { 1682ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return *this = EPOCH; 1692ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1702ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1712ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (this->tv_nsec < T.tv_nsec) { 1722ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn --this->tv_sec; 1732ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec; 1742ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } else { 1752ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec -= T.tv_nsec; 1762ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1772ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_sec -= T.tv_sec; 1782ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn 1792ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return *this; 180fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn} 181decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn 1822ed51d708eda64516ec79ac6397f690de38f0075Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator+=(const log_time& T) { 1832ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec += T.tv_nsec; 1842ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn if (this->tv_nsec >= NS_PER_SEC) { 1852ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_nsec -= NS_PER_SEC; 1862ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn ++this->tv_sec; 1872ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn } 1882ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn this->tv_sec += T.tv_sec; 189decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn 1902ed51d708eda64516ec79ac6397f690de38f0075Mark Salyzyn return *this; 191decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn} 192