/src/znc/third_party/cctz/src/time_zone_info.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2016 Google Inc. All Rights Reserved. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef CCTZ_TIME_ZONE_INFO_H_ |
16 | | #define CCTZ_TIME_ZONE_INFO_H_ |
17 | | |
18 | | #include <atomic> |
19 | | #include <cstddef> |
20 | | #include <cstdint> |
21 | | #include <string> |
22 | | #include <vector> |
23 | | |
24 | | #include "cctz/civil_time.h" |
25 | | #include "cctz/time_zone.h" |
26 | | #include "cctz/zone_info_source.h" |
27 | | #include "time_zone_if.h" |
28 | | #include "tzfile.h" |
29 | | |
30 | | namespace cctz { |
31 | | |
32 | | // A transition to a new UTC offset. |
33 | | struct Transition { |
34 | | std::int_least64_t unix_time; // the instant of this transition |
35 | | std::uint_least8_t type_index; // index of the transition type |
36 | | civil_second civil_sec; // local civil time of transition |
37 | | civil_second prev_civil_sec; // local civil time one second earlier |
38 | | |
39 | | struct ByUnixTime { |
40 | 0 | inline bool operator()(const Transition& lhs, const Transition& rhs) const { |
41 | 0 | return lhs.unix_time < rhs.unix_time; |
42 | 0 | } |
43 | | }; |
44 | | struct ByCivilTime { |
45 | 0 | inline bool operator()(const Transition& lhs, const Transition& rhs) const { |
46 | 0 | return lhs.civil_sec < rhs.civil_sec; |
47 | 0 | } |
48 | | }; |
49 | | }; |
50 | | |
51 | | // The characteristics of a particular transition. |
52 | | struct TransitionType { |
53 | | std::int_least32_t utc_offset; // the new prevailing UTC offset |
54 | | civil_second civil_max; // max convertible civil time for offset |
55 | | civil_second civil_min; // min convertible civil time for offset |
56 | | bool is_dst; // did we move into daylight-saving time |
57 | | std::uint_least8_t abbr_index; // index of the new abbreviation |
58 | | }; |
59 | | |
60 | | // A time zone backed by the IANA Time Zone Database (zoneinfo). |
61 | | class TimeZoneInfo : public TimeZoneIf { |
62 | | public: |
63 | 0 | TimeZoneInfo() = default; |
64 | | TimeZoneInfo(const TimeZoneInfo&) = delete; |
65 | | TimeZoneInfo& operator=(const TimeZoneInfo&) = delete; |
66 | | |
67 | | // Loads the zoneinfo for the given name, returning true if successful. |
68 | | bool Load(const std::string& name); |
69 | | |
70 | | // TimeZoneIf implementations. |
71 | | time_zone::absolute_lookup BreakTime( |
72 | | const time_point<seconds>& tp) const override; |
73 | | time_zone::civil_lookup MakeTime( |
74 | | const civil_second& cs) const override; |
75 | | bool NextTransition(const time_point<seconds>& tp, |
76 | | time_zone::civil_transition* trans) const override; |
77 | | bool PrevTransition(const time_point<seconds>& tp, |
78 | | time_zone::civil_transition* trans) const override; |
79 | | std::string Version() const override; |
80 | | std::string Description() const override; |
81 | | |
82 | | private: |
83 | | struct Header { // counts of: |
84 | | std::size_t timecnt; // transition times |
85 | | std::size_t typecnt; // transition types |
86 | | std::size_t charcnt; // zone abbreviation characters |
87 | | std::size_t leapcnt; // leap seconds (we expect none) |
88 | | std::size_t ttisstdcnt; // UTC/local indicators (unused) |
89 | | std::size_t ttisutcnt; // standard/wall indicators (unused) |
90 | | |
91 | | bool Build(const tzhead& tzh); |
92 | | std::size_t DataLength(std::size_t time_len) const; |
93 | | }; |
94 | | |
95 | | bool GetTransitionType(std::int_fast32_t utc_offset, bool is_dst, |
96 | | const std::string& abbr, std::uint_least8_t* index); |
97 | | bool EquivTransitions(std::uint_fast8_t tt1_index, |
98 | | std::uint_fast8_t tt2_index) const; |
99 | | bool ExtendTransitions(); |
100 | | |
101 | | bool ResetToBuiltinUTC(const seconds& offset); |
102 | | bool Load(ZoneInfoSource* zip); |
103 | | |
104 | | // Helpers for BreakTime() and MakeTime(). |
105 | | time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, |
106 | | const TransitionType& tt) const; |
107 | | time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, |
108 | | const Transition& tr) const; |
109 | | time_zone::civil_lookup TimeLocal(const civil_second& cs, |
110 | | year_t c4_shift) const; |
111 | | |
112 | | std::vector<Transition> transitions_; // ordered by unix_time and civil_sec |
113 | | std::vector<TransitionType> transition_types_; // distinct transition types |
114 | | std::uint_fast8_t default_transition_type_; // for before first transition |
115 | | std::string abbreviations_; // all the NUL-terminated abbreviations |
116 | | |
117 | | std::string version_; // the tzdata version if available |
118 | | std::string future_spec_; // for after the last zic transition |
119 | | bool extended_; // future_spec_ was used to generate transitions |
120 | | year_t last_year_; // the final year of the generated transitions |
121 | | |
122 | | // We remember the transitions found during the last BreakTime() and |
123 | | // MakeTime() calls. If the next request is for the same transition we |
124 | | // will avoid re-searching. |
125 | | mutable std::atomic<std::size_t> local_time_hint_ = {}; // BreakTime() hint |
126 | | mutable std::atomic<std::size_t> time_local_hint_ = {}; // MakeTime() hint |
127 | | }; |
128 | | |
129 | | } // namespace cctz |
130 | | |
131 | | #endif // CCTZ_TIME_ZONE_INFO_H_ |