1 /*
2  * Copyright (C) 2013-2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _LIBS_LOG_LOG_READ_H
18 #define _LIBS_LOG_LOG_READ_H
19 
20 #include <stdint.h>
21 #include <time.h>
22 
23 /* struct log_time is a wire-format variant of struct timespec */
24 #define NS_PER_SEC 1000000000ULL
25 
26 #ifdef __cplusplus
27 
28 // NB: do NOT define a copy constructor. This will result in structure
29 // no longer being compatible with pass-by-value which is desired
30 // efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
31 struct log_time {
32 public:
33     uint32_t tv_sec; // good to Feb 5 2106
34     uint32_t tv_nsec;
35 
36     static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
37     static const uint32_t tv_nsec_max = 999999999UL;
38 
log_timelog_time39     log_time(const timespec &T)
40     {
41         tv_sec = T.tv_sec;
42         tv_nsec = T.tv_nsec;
43     }
log_timelog_time44     log_time(uint32_t sec, uint32_t nsec)
45     {
46         tv_sec = sec;
47         tv_nsec = nsec;
48     }
49     static const timespec EPOCH;
log_timelog_time50     log_time()
51     {
52     }
log_timelog_time53     log_time(clockid_t id)
54     {
55         timespec T;
56         clock_gettime(id, &T);
57         tv_sec = T.tv_sec;
58         tv_nsec = T.tv_nsec;
59     }
log_timelog_time60     log_time(const char *T)
61     {
62         const uint8_t *c = (const uint8_t *) T;
63         tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
64         tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24);
65     }
66 
67     // timespec
68     bool operator== (const timespec &T) const
69     {
70         return (tv_sec == static_cast<uint32_t>(T.tv_sec))
71             && (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
72     }
73     bool operator!= (const timespec &T) const
74     {
75         return !(*this == T);
76     }
77     bool operator< (const timespec &T) const
78     {
79         return (tv_sec < static_cast<uint32_t>(T.tv_sec))
80             || ((tv_sec == static_cast<uint32_t>(T.tv_sec))
81                 && (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
82     }
83     bool operator>= (const timespec &T) const
84     {
85         return !(*this < T);
86     }
87     bool operator> (const timespec &T) const
88     {
89         return (tv_sec > static_cast<uint32_t>(T.tv_sec))
90             || ((tv_sec == static_cast<uint32_t>(T.tv_sec))
91                 && (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
92     }
93     bool operator<= (const timespec &T) const
94     {
95         return !(*this > T);
96     }
97     log_time operator-= (const timespec &T);
98     log_time operator- (const timespec &T) const
99     {
100         log_time local(*this);
101         return local -= T;
102     }
103     log_time operator+= (const timespec &T);
104     log_time operator+ (const timespec &T) const
105     {
106         log_time local(*this);
107         return local += T;
108     }
109 
110     // log_time
111     bool operator== (const log_time &T) const
112     {
113         return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
114     }
115     bool operator!= (const log_time &T) const
116     {
117         return !(*this == T);
118     }
119     bool operator< (const log_time &T) const
120     {
121         return (tv_sec < T.tv_sec)
122             || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
123     }
124     bool operator>= (const log_time &T) const
125     {
126         return !(*this < T);
127     }
128     bool operator> (const log_time &T) const
129     {
130         return (tv_sec > T.tv_sec)
131             || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
132     }
133     bool operator<= (const log_time &T) const
134     {
135         return !(*this > T);
136     }
137     log_time operator-= (const log_time &T);
138     log_time operator- (const log_time &T) const
139     {
140         log_time local(*this);
141         return local -= T;
142     }
143     log_time operator+= (const log_time &T);
144     log_time operator+ (const log_time &T) const
145     {
146         log_time local(*this);
147         return local += T;
148     }
149 
nseclog_time150     uint64_t nsec() const
151     {
152         return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
153     }
154 
155     static const char default_format[];
156 
157     // Add %#q for the fraction of a second to the standard library functions
158     char *strptime(const char *s, const char *format = default_format);
159 } __attribute__((__packed__));
160 
161 #else
162 
163 typedef struct log_time {
164     uint32_t tv_sec;
165     uint32_t tv_nsec;
166 } __attribute__((__packed__)) log_time;
167 
168 #endif
169 
170 #endif /* define _LIBS_LOG_LOG_READ_H */
171