Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This code is made available to you under your choice of the following sets
4 : * of licensing terms:
5 : */
6 : /* This Source Code Form is subject to the terms of the Mozilla Public
7 : * License, v. 2.0. If a copy of the MPL was not distributed with this
8 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 : */
10 : /* Copyright 2014 Mozilla Contributors
11 : *
12 : * Licensed under the Apache License, Version 2.0 (the "License");
13 : * you may not use this file except in compliance with the License.
14 : * You may obtain a copy of the License at
15 : *
16 : * http://www.apache.org/licenses/LICENSE-2.0
17 : *
18 : * Unless required by applicable law or agreed to in writing, software
19 : * distributed under the License is distributed on an "AS IS" BASIS,
20 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 : * See the License for the specific language governing permissions and
22 : * limitations under the License.
23 : */
24 :
25 : #ifndef mozilla_pkix_Time_h
26 : #define mozilla_pkix_Time_h
27 :
28 : #include <ctime>
29 : #include <limits>
30 : #include <stdint.h>
31 :
32 : #include "pkix/Result.h"
33 :
34 : namespace mozilla { namespace pkix {
35 :
36 : // Time with a range from the first second of year 0 (AD) through at least the
37 : // last second of year 9999, which is the range of legal times in X.509 and
38 : // OCSP. This type has second-level precision. The time zone is always UTC.
39 : //
40 : // Pass by value, not by reference.
41 : class Time final
42 : {
43 : public:
44 : // Construct an uninitialized instance.
45 : //
46 : // This will fail to compile because there is no default constructor:
47 : // Time x;
48 : //
49 : // This will succeed, leaving the time uninitialized:
50 : // Time x(Time::uninitialized);
51 : enum Uninitialized { uninitialized };
52 0 : explicit Time(Uninitialized) { }
53 :
54 : bool operator==(const Time& other) const
55 : {
56 : return elapsedSecondsAD == other.elapsedSecondsAD;
57 : }
58 0 : bool operator>(const Time& other) const
59 : {
60 0 : return elapsedSecondsAD > other.elapsedSecondsAD;
61 : }
62 0 : bool operator>=(const Time& other) const
63 : {
64 0 : return elapsedSecondsAD >= other.elapsedSecondsAD;
65 : }
66 0 : bool operator<(const Time& other) const
67 : {
68 0 : return elapsedSecondsAD < other.elapsedSecondsAD;
69 : }
70 0 : bool operator<=(const Time& other) const
71 : {
72 0 : return elapsedSecondsAD <= other.elapsedSecondsAD;
73 : }
74 :
75 0 : Result AddSeconds(uint64_t seconds)
76 : {
77 0 : if (std::numeric_limits<uint64_t>::max() - elapsedSecondsAD
78 : < seconds) {
79 0 : return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow
80 : }
81 0 : elapsedSecondsAD += seconds;
82 0 : return Success;
83 : }
84 :
85 : Result SubtractSeconds(uint64_t seconds)
86 : {
87 : if (seconds > elapsedSecondsAD) {
88 : return Result::FATAL_ERROR_INVALID_ARGS; // integer overflow
89 : }
90 : elapsedSecondsAD -= seconds;
91 : return Success;
92 : }
93 :
94 : static const uint64_t ONE_DAY_IN_SECONDS
95 : = UINT64_C(24) * UINT64_C(60) * UINT64_C(60);
96 :
97 : private:
98 : // This constructor is hidden to prevent accidents like this:
99 : //
100 : // Time foo(time_t t)
101 : // {
102 : // // WRONG! 1970-01-01-00:00:00 == time_t(0), but not Time(0)!
103 : // return Time(t);
104 : // }
105 0 : explicit Time(uint64_t elapsedSecondsAD)
106 0 : : elapsedSecondsAD(elapsedSecondsAD)
107 : {
108 0 : }
109 : friend Time TimeFromElapsedSecondsAD(uint64_t);
110 : friend class Duration;
111 :
112 : uint64_t elapsedSecondsAD;
113 : };
114 :
115 0 : inline Time TimeFromElapsedSecondsAD(uint64_t elapsedSecondsAD)
116 : {
117 0 : return Time(elapsedSecondsAD);
118 : }
119 :
120 : Time Now();
121 :
122 : // Note the epoch is the unix epoch (ie 00:00:00 UTC, 1 January 1970)
123 : Time TimeFromEpochInSeconds(uint64_t secondsSinceEpoch);
124 :
125 : class Duration final
126 : {
127 : public:
128 0 : Duration(Time timeA, Time timeB)
129 0 : : durationInSeconds(timeA < timeB
130 0 : ? timeB.elapsedSecondsAD - timeA.elapsedSecondsAD
131 0 : : timeA.elapsedSecondsAD - timeB.elapsedSecondsAD)
132 : {
133 0 : }
134 :
135 0 : explicit Duration(uint64_t durationInSeconds)
136 0 : : durationInSeconds(durationInSeconds)
137 : {
138 0 : }
139 :
140 0 : bool operator>(const Duration& other) const
141 : {
142 0 : return durationInSeconds > other.durationInSeconds;
143 : }
144 0 : bool operator<(const Duration& other) const
145 : {
146 0 : return durationInSeconds < other.durationInSeconds;
147 : }
148 :
149 : private:
150 : uint64_t durationInSeconds;
151 : };
152 :
153 : } } // namespace mozilla::pkix
154 :
155 : #endif // mozilla_pkix_Time_h
|