AceTime  1.8.0
Date and time classes for Arduino that support timezones from the TZ Database, and a system clock that can synchronize from an NTP server or an RTC chip.
ZoneManager.h
1 /*
2  * MIT License
3  * Copyright (c) 2019 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_ZONE_MANAGER_H
7 #define ACE_TIME_ZONE_MANAGER_H
8 
9 #include "internal/ZoneRegistrar.h"
10 #include "ZoneProcessorCache.h"
11 #include "TimeZoneData.h"
12 #include "TimeZone.h"
13 
14 namespace ace_time {
15 
24 class ZoneManager {
25  public:
27  static const uint16_t kInvalidIndex = 0xffff;
28 
32  virtual TimeZone createForZoneName(const char* name) = 0;
33 
35  virtual TimeZone createForZoneId(uint32_t id) = 0;
36 
41  virtual TimeZone createForZoneIndex(uint16_t index) = 0;
42 
47  virtual TimeZone createForTimeZoneData(const TimeZoneData& d) = 0;
48 
53  virtual uint16_t indexForZoneName(const char* name) const = 0;
54 
59  virtual uint16_t indexForZoneId(uint32_t id) const = 0;
60 
65  virtual uint16_t zoneRegistrySize() const = 0;
66 };
67 
78  public:
79 
80  TimeZone createForZoneName(const char* /*name*/) override {
81  return TimeZone::forError();
82  }
83 
84  TimeZone createForZoneId(uint32_t /*id*/) override {
85  return TimeZone::forError();
86  }
87 
88  TimeZone createForZoneIndex(uint16_t /*index*/) override {
89  return TimeZone::forError();
90  }
91 
93  switch (d.type) {
94  case TimeZoneData::kTypeError:
95  return TimeZone::forError();
96  case TimeZoneData::kTypeManual:
98  TimeOffset::forMinutes(d.stdOffsetMinutes),
99  TimeOffset::forMinutes(d.dstOffsetMinutes));
100  default:
101  return TimeZone::forError();
102  }
103  }
104 
105  uint16_t indexForZoneName(const char* /*name*/) const override {
106  return kInvalidIndex;
107  }
108 
109  uint16_t indexForZoneId(uint32_t /*id*/) const override {
110  return kInvalidIndex;
111  }
112 
113  uint16_t zoneRegistrySize() const override { return 0; }
114 };
115 
140 template<
141  typename ZI, typename ZRR,
142  typename ZP, typename ZPC
143 >
144 class ZoneManagerImpl : public ZoneManager {
145  public:
146  TimeZone createForZoneName(const char* name) override {
147  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForName(name);
148  return createForZoneInfo(zoneInfo);
149  }
150 
151  TimeZone createForZoneId(uint32_t id) override {
152  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForId(id);
153  return createForZoneInfo(zoneInfo);
154  }
155 
156  TimeZone createForZoneIndex(uint16_t index) override {
157  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForIndex(index);
158  return createForZoneInfo(zoneInfo);
159  }
160 
162  switch (d.type) {
163  case TimeZoneData::kTypeError:
164  return TimeZone::forError();
165  case TimeZoneData::kTypeManual:
167  TimeOffset::forMinutes(d.stdOffsetMinutes),
168  TimeOffset::forMinutes(d.dstOffsetMinutes));
169  case TimeZoneData::kTypeZoneId:
170  return createForZoneId(d.zoneId);
171  default:
172  // Maybe this should return TimeZone::forError()?
173  return TimeZone();
174  }
175  }
176 
177  uint16_t indexForZoneName(const char* name) const override {
178  return mZoneRegistrar.findIndexForName(name);
179  }
180 
181  uint16_t indexForZoneId(uint32_t id) const override {
182  return mZoneRegistrar.findIndexForId(id);
183  }
184 
185  uint16_t zoneRegistrySize() const override {
186  return mZoneRegistrar.zoneRegistrySize();
187  }
188 
196  TimeZone createForZoneInfo(const ZI* zoneInfo) {
197  if (! zoneInfo) return TimeZone::forError();
198  ZP* processor = mZoneProcessorCache.getZoneProcessor(
199  (uintptr_t) zoneInfo);
200  return TimeZone::forZoneInfo(zoneInfo, processor);
201  }
202 
203  protected:
211  uint16_t zoneRegistrySize,
212  const ZI* const* zoneRegistry
213  ):
214  mZoneRegistrar(zoneRegistrySize, zoneRegistry),
215  mZoneProcessorCache() {}
216 
217  // disable copy constructor and assignment operator
218  ZoneManagerImpl(const ZoneManagerImpl&) = delete;
219  ZoneManagerImpl& operator=(const ZoneManagerImpl&) = delete;
220 
221  const ZRR mZoneRegistrar;
222  ZPC mZoneProcessorCache;
223 };
224 
225 #if 1
226 
232 template<uint16_t SIZE>
234  basic::ZoneInfo,
235  basic::ZoneRegistrar,
236  BasicZoneProcessor,
237  BasicZoneProcessorCache<SIZE>
238 > {
239 
240  public:
242  uint16_t zoneRegistrySize,
243  const basic::ZoneInfo* const* zoneRegistry
244  ):
246  basic::ZoneInfo,
250  >(
252  zoneRegistry
253  )
254  {}
255 
261  const basic::ZoneInfo* zoneInfo =
262  this->mZoneRegistrar.getZoneInfoForName(name);
263  if (! zoneInfo) return nullptr;
264  return this->mZoneProcessorCache.getZoneProcessor((uintptr_t) zoneInfo);
265  }
266 };
267 
274 template<uint16_t SIZE>
276  extended::ZoneInfo,
277  extended::ZoneRegistrar,
278  ExtendedZoneProcessor,
279  ExtendedZoneProcessorCache<SIZE>
280 > {
281 
282  public:
284  uint16_t zoneRegistrySize,
285  const extended::ZoneInfo* const* zoneRegistry
286  ):
288  extended::ZoneInfo,
292  >(
294  zoneRegistry
295  )
296  {}
297 
303  const extended::ZoneInfo* zoneInfo =
304  this->mZoneRegistrar.getZoneInfoForName(name);
305  if (! zoneInfo) return nullptr;
306  return this->mZoneProcessorCache.getZoneProcessor((uintptr_t) zoneInfo);
307  }
308 };
309 
310 #else
311 
312 // NOTE: The following typedefs seem shorter and easier to maintain. The
313 // problem is that they make error messages basically impossible to decipher
314 // because the template class names are far too long for human comprehension.
315 // Fortunately, there seems to be no difference in code size between the above
316 // solution using subclasses and this solution using typedefs. The compiler
317 // seems to optimize away the vtables of the parent and child classes. So we'll
318 // use the above subclassing solution to get better error messages.
319 
320 template<uint8_t SIZE>
321 using BasicZoneManager = ZoneManagerImpl<
322  basic::ZoneInfo,
323  basic::ZoneRegistrar,
324  BasicZoneProcessor,
325  BasicZoneProcessorCache<SIZE>
326 >;
327 
328 template<uint8_t SIZE>
329 using ExtendedZoneManager = ZoneManagerImpl<
330  extended::ZoneInfo,
331  extended::ZoneRegistrar,
332  ExtendedZoneProcessor,
333  ExtendedZoneProcessorCache<SIZE>
334 >;
335 
336 #endif
337 
338 }
339 
340 #endif
ace_time::ExtendedZoneManager::getZoneProcessor
ExtendedZoneProcessor * getZoneProcessor(const char *name)
Return the ExtendedZoneProcessor for given zone name.
Definition: ZoneManager.h:302
ace_time::TimeZone::forZoneInfo
static TimeZone forZoneInfo(const basic::ZoneInfo *zoneInfo, BasicZoneProcessor *zoneProcessor)
Convenience factory method to create from a zoneInfo and an associated BasicZoneProcessor.
Definition: TimeZone.h:173
ace_time::ManualZoneManager::createForZoneId
TimeZone createForZoneId(uint32_t) override
Create a TimeZone for the given 32-bit zoneId.
Definition: ZoneManager.h:84
ace_time::BasicZoneProcessorCache
Definition: ZoneProcessorCache.h:81
ace_time::BasicZoneManager::getZoneProcessor
BasicZoneProcessor * getZoneProcessor(const char *name)
Return the BasicZoneProcessor for given zone name.
Definition: ZoneManager.h:260
ace_time::ManualZoneManager
A ZoneManager that implements only createForTimeZoneData() to create TimeZones of type kTypeManual,...
Definition: ZoneManager.h:77
ace_time::ManualZoneManager::indexForZoneName
uint16_t indexForZoneName(const char *) const override
Find the registry index for the given time zone name.
Definition: ZoneManager.h:105
ace_time::ZoneManagerImpl::createForZoneName
TimeZone createForZoneName(const char *name) override
Create a TimeZone for the given zone name (e.g.
Definition: ZoneManager.h:146
ace_time::ExtendedZoneProcessorCache
Definition: ZoneProcessorCache.h:86
ace_time::basic::ZoneRegistrar
Concrete template instantiation of ZoneRegistrarTemplate for basic::ZoneInfo, which can be used with ...
Definition: ZoneRegistrar.h:216
ace_time::TimeZone::forError
static TimeZone forError()
Return a TimeZone representing an error condition.
Definition: TimeZone.h:216
ace_time::ZoneManager::zoneRegistrySize
virtual uint16_t zoneRegistrySize() const =0
Return the number of elements in the Zone and Fat Link registry.
ace_time::ZoneManager::indexForZoneName
virtual uint16_t indexForZoneName(const char *name) const =0
Find the registry index for the given time zone name.
ace_time::ZoneManagerImpl::createForZoneId
TimeZone createForZoneId(uint32_t id) override
Create a TimeZone for the given 32-bit zoneId.
Definition: ZoneManager.h:151
ace_time::ZoneManagerImpl::ZoneManagerImpl
ZoneManagerImpl(uint16_t zoneRegistrySize, const ZI *const *zoneRegistry)
Constructor.
Definition: ZoneManager.h:210
ace_time::ZoneManagerImpl::createForZoneInfo
TimeZone createForZoneInfo(const ZI *zoneInfo)
Create a TimeZone from an explicit ZoneInfo reference.
Definition: ZoneManager.h:196
ace_time::ZoneManagerImpl::createForTimeZoneData
TimeZone createForTimeZoneData(const TimeZoneData &d) override
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
Definition: ZoneManager.h:161
ace_time::ExtendedZoneProcessor
A specific implementation of ExtendedZoneProcessorTemplate that uses ZoneXxxBrokers which read from z...
Definition: ExtendedZoneProcessor.h:1964
ace_time::ManualZoneManager::zoneRegistrySize
uint16_t zoneRegistrySize() const override
Return the number of elements in the Zone and Fat Link registry.
Definition: ZoneManager.h:113
ace_time::ZoneManager::createForZoneId
virtual TimeZone createForZoneId(uint32_t id)=0
Create a TimeZone for the given 32-bit zoneId.
ace_time::ZoneManagerImpl::zoneRegistrySize
uint16_t zoneRegistrySize() const override
Return the number of elements in the Zone and Fat Link registry.
Definition: ZoneManager.h:185
ace_time::extended::ZoneRegistrar
Concrete template instantiation of ZoneRegistrarTemplate for extended::ZoneInfo, which can be used wi...
Definition: ZoneRegistrar.h:260
ace_time::BasicZoneManager
An implementation of the ZoneManager which uses a registry of basic::ZoneInfo records.
Definition: ZoneManager.h:233
ace_time::ZoneManager::kInvalidIndex
static const uint16_t kInvalidIndex
Registry index which is not valid.
Definition: ZoneManager.h:27
ace_time::TimeOffset::forMinutes
static TimeOffset forMinutes(int16_t minutes)
Create TimeOffset from minutes from 00:00.
Definition: TimeOffset.h:83
ace_time::ZoneManager::indexForZoneId
virtual uint16_t indexForZoneId(uint32_t id) const =0
Find the registry index for the given time zone id.
ace_time::ZoneManager::createForZoneIndex
virtual TimeZone createForZoneIndex(uint16_t index)=0
Create a TimeZone for the given index in the ZoneInfo registry that was used to create this ZoneManag...
ace_time::ZoneManager
Common interface to the BasicZoneManager and ExtendedZoneManager so that a single interface can be pa...
Definition: ZoneManager.h:24
ace_time::internal::ZoneRegistrarTemplate::getZoneInfoForName
const ZI * getZoneInfoForName(const char *name) const
Return the ZoneInfo corresponding to the given zone name.
Definition: ZoneRegistrar.h:73
ace_time::TimeZoneData
Data structure that captures the internal state of a TimeZone object with enough information so that ...
Definition: TimeZoneData.h:38
ace_time::ManualZoneManager::createForZoneIndex
TimeZone createForZoneIndex(uint16_t) override
Create a TimeZone for the given index in the ZoneInfo registry that was used to create this ZoneManag...
Definition: ZoneManager.h:88
ace_time::ManualZoneManager::createForTimeZoneData
TimeZone createForTimeZoneData(const TimeZoneData &d) override
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
Definition: ZoneManager.h:92
ace_time::ExtendedZoneManager
An implementation of the ZoneManager which uses a registry of extended::ZoneInfo records.
Definition: ZoneManager.h:275
ace_time::ZoneManagerImpl::createForZoneIndex
TimeZone createForZoneIndex(uint16_t index) override
Create a TimeZone for the given index in the ZoneInfo registry that was used to create this ZoneManag...
Definition: ZoneManager.h:156
ace_time::ZoneManagerImpl::indexForZoneId
uint16_t indexForZoneId(uint32_t id) const override
Find the registry index for the given time zone id.
Definition: ZoneManager.h:181
ace_time::ZoneManagerImpl
A templatized implementation of ZoneManager that binds the ZoneRegistrar with the corresponding (Basi...
Definition: ZoneManager.h:144
ace_time::TimeZone
Class that describes a time zone.
Definition: TimeZone.h:85
ace_time::TimeZone::forTimeOffset
static TimeZone forTimeOffset(TimeOffset stdOffset, TimeOffset dstOffset=TimeOffset())
Factory method to create from a UTC offset and an optional DST offset.
Definition: TimeZone.h:114
ace_time::BasicZoneProcessor
A specific implementation of BasicZoneProcessorTemplate that uses ZoneXxxBrokers which read from zone...
Definition: BasicZoneProcessor.h:993
ace_time::ZoneManagerImpl::indexForZoneName
uint16_t indexForZoneName(const char *name) const override
Find the registry index for the given time zone name.
Definition: ZoneManager.h:177
ace_time::TimeZoneData::zoneId
uint32_t zoneId
Both TimeZone::kTypeBasic and TimeZone::kTypeExtended are mapped to a TimeZoneData::kTypeZoneId.
Definition: TimeZoneData.h:78
ace_time::ZoneManager::createForTimeZoneData
virtual TimeZone createForTimeZoneData(const TimeZoneData &d)=0
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
ace_time::ManualZoneManager::indexForZoneId
uint16_t indexForZoneId(uint32_t) const override
Find the registry index for the given time zone id.
Definition: ZoneManager.h:109
ace_time::ZoneManager::createForZoneName
virtual TimeZone createForZoneName(const char *name)=0
Create a TimeZone for the given zone name (e.g.
ace_time::ManualZoneManager::createForZoneName
TimeZone createForZoneName(const char *) override
Create a TimeZone for the given zone name (e.g.
Definition: ZoneManager.h:80