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
22fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#include <log/log_read.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
316d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE char *log_time::strptime(const char *s, const char *format) {
32fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    time_t now;
33fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#ifdef __linux__
34fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    *this = log_time(CLOCK_REALTIME);
35fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    now = tv_sec;
36fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else
37fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    time(&now);
38fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    tv_sec = now;
39fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    tv_nsec = 0;
40fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif
41fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
42fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    struct tm *ptm;
438a98535bcb48dfd4bfe3dfddddc82925a2f1502bYabin Cui#if !defined(_WIN32)
44fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    struct tm tmBuf;
45fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    ptm = localtime_r(&now, &tmBuf);
46fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else
47fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    ptm = localtime(&now);
48fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif
49fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
50fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    char fmt[strlen(format) + 1];
51fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    strcpy(fmt, format);
52fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
53fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    char *ret = const_cast<char *> (s);
54fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    char *cp;
55fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    for (char *f = cp = fmt; ; ++cp) {
56fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        if (!*cp) {
57fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            if (f != cp) {
58fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                ret = ::strptime(ret, f, ptm);
59fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
60fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            break;
61fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        }
62fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        if (*cp != '%') {
63fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            continue;
64fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        }
65fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        char *e = cp;
66fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        ++e;
67fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#if (defined(__BIONIC__))
68fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        if (*e == 's') {
69fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            *cp = '\0';
70fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            if (*f) {
71fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                ret = ::strptime(ret, f, ptm);
72fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                if (!ret) {
73fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                    break;
74fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                }
75fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
76fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            tv_sec = 0;
77fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            while (isdigit(*ret)) {
78fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                tv_sec = tv_sec * 10 + *ret - '0';
79fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                ++ret;
80fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
81fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            now = tv_sec;
828a98535bcb48dfd4bfe3dfddddc82925a2f1502bYabin Cui#if !defined(_WIN32)
83fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            ptm = localtime_r(&now, &tmBuf);
84fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else
85fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            ptm = localtime(&now);
86fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif
87fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        } else
88fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif
89fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        {
90fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            unsigned num = 0;
91fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            while (isdigit(*e)) {
92fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                num = num * 10 + *e - '0';
93fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                ++e;
94fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
95fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            if (*e != 'q') {
96fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                continue;
97fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
98fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            *cp = '\0';
99fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            if (*f) {
100fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                ret = ::strptime(ret, f, ptm);
101fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                if (!ret) {
102fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                    break;
103fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                }
104fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
105fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            unsigned long mul = NS_PER_SEC;
106fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            if (num == 0) {
107fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                num = INT_MAX;
108fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
109fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            tv_nsec = 0;
110fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            while (isdigit(*ret) && num && (mul > 1)) {
111fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                --num;
112fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                mul /= 10;
113fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                tv_nsec = tv_nsec + (*ret - '0') * mul;
114fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn                ++ret;
115fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn            }
116fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        }
117fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        f = cp = e;
118fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        ++f;
119fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
120fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
121fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    if (ret) {
122fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        tv_sec = mktime(ptm);
123fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        return ret;
124fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
125fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
126fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    // Upon error, place a known value into the class, the current time.
127fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#ifdef __linux__
128fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    *this = log_time(CLOCK_REALTIME);
129fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#else
130fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    time(&now);
131fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    tv_sec = now;
132fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    tv_nsec = 0;
133fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn#endif
134fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    return ret;
135fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn}
136fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
1376d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator-= (const timespec &T) {
138fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    // No concept of negative time, clamp to EPOCH
139fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    if (*this <= T) {
140fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        return *this = EPOCH;
141fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
142fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
143fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    if (this->tv_nsec < (unsigned long int)T.tv_nsec) {
144fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        --this->tv_sec;
145fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
146fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    } else {
147fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        this->tv_nsec -= T.tv_nsec;
148fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
149fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    this->tv_sec -= T.tv_sec;
150fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
151fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    return *this;
152fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn}
153fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
1546d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator+= (const timespec &T) {
155decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    this->tv_nsec += (unsigned long int)T.tv_nsec;
156decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    if (this->tv_nsec >= NS_PER_SEC) {
157decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn        this->tv_nsec -= NS_PER_SEC;
158decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn        ++this->tv_sec;
159decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    }
160decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    this->tv_sec += T.tv_sec;
161decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn
162decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    return *this;
163decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn}
164decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn
1656d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator-= (const log_time &T) {
166fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    // No concept of negative time, clamp to EPOCH
167fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    if (*this <= T) {
168fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        return *this = EPOCH;
169fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
170fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
171fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    if (this->tv_nsec < T.tv_nsec) {
172fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        --this->tv_sec;
173fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
174fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    } else {
175fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn        this->tv_nsec -= T.tv_nsec;
176fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    }
177fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    this->tv_sec -= T.tv_sec;
178fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn
179fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn    return *this;
180fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn}
181decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn
1826d753faaf8694792433eb78c5c3572efd74a3d54Mark SalyzynLIBLOG_ABI_PRIVATE log_time log_time::operator+= (const log_time &T) {
183decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    this->tv_nsec += T.tv_nsec;
184decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    if (this->tv_nsec >= NS_PER_SEC) {
185decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn        this->tv_nsec -= NS_PER_SEC;
186decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn        ++this->tv_sec;
187decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    }
188decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    this->tv_sec += T.tv_sec;
189decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn
190decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn    return *this;
191decd92945fa8692b384a99da786bd43f6bc1ef3eMark Salyzyn}
192