AceTime  1.7.2
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 "internal/LinkRegistrar.h"
11 #include "ZoneProcessorCache.h"
12 #include "TimeZoneData.h"
13 #include "TimeZone.h"
14 
15 namespace ace_time {
16 
25 class ZoneManager {
26  public:
28  static const uint16_t kInvalidIndex = 0xffff;
29 
33  virtual TimeZone createForZoneName(const char* name) = 0;
34 
36  virtual TimeZone createForZoneId(uint32_t id) = 0;
37 
42  virtual TimeZone createForZoneIndex(uint16_t index) = 0;
43 
48  virtual TimeZone createForTimeZoneData(const TimeZoneData& d) = 0;
49 
54  virtual uint16_t indexForZoneName(const char* name) const = 0;
55 
60  virtual uint16_t indexForZoneId(uint32_t id) const = 0;
61 
66  virtual uint16_t zoneRegistrySize() const = 0;
67 
71  virtual uint16_t linkRegistrySize() const = 0;
72 };
73 
84  public:
85 
86  TimeZone createForZoneName(const char* /*name*/) override {
87  return TimeZone::forError();
88  }
89 
90  TimeZone createForZoneId(uint32_t /*id*/) override {
91  return TimeZone::forError();
92  }
93 
94  TimeZone createForZoneIndex(uint16_t /*index*/) override {
95  return TimeZone::forError();
96  }
97 
99  switch (d.type) {
100  case TimeZoneData::kTypeError:
101  return TimeZone::forError();
102  case TimeZoneData::kTypeManual:
104  TimeOffset::forMinutes(d.stdOffsetMinutes),
105  TimeOffset::forMinutes(d.dstOffsetMinutes));
106  default:
107  return TimeZone::forError();
108  }
109  }
110 
111  uint16_t indexForZoneName(const char* /*name*/) const override {
112  return kInvalidIndex;
113  }
114 
115  uint16_t indexForZoneId(uint32_t /*id*/) const override {
116  return kInvalidIndex;
117  }
118 
119  uint16_t zoneRegistrySize() const override { return 0; }
120 
121  uint16_t linkRegistrySize() const override { return 0; }
122 };
123 
152 template<
153  typename ZI, typename ZRR,
154  typename LE, typename LRR,
155  typename ZP, typename ZPC
156 >
157 class ZoneManagerImpl : public ZoneManager {
158  public:
159  TimeZone createForZoneName(const char* name) override {
160  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForName(name);
161  return createForZoneInfo(zoneInfo);
162  }
163 
164  TimeZone createForZoneId(uint32_t id) override {
165  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForId(id);
166 
167  // zone not found, so search for matching link
168  if (zoneInfo == nullptr) {
169  const LE* linkEntry = mLinkRegistrar.getLinkEntryForId(id);
170  if (linkEntry) {
171  uint32_t targetZoneId = linkEntry->zoneId;
172  zoneInfo = mZoneRegistrar.getZoneInfoForId(targetZoneId);
173  }
174  }
175  return createForZoneInfo(zoneInfo);
176  }
177 
178  TimeZone createForZoneIndex(uint16_t index) override {
179  const ZI* zoneInfo = mZoneRegistrar.getZoneInfoForIndex(index);
180  return createForZoneInfo(zoneInfo);
181  }
182 
184  switch (d.type) {
185  case TimeZoneData::kTypeError:
186  return TimeZone::forError();
187  case TimeZoneData::kTypeManual:
189  TimeOffset::forMinutes(d.stdOffsetMinutes),
190  TimeOffset::forMinutes(d.dstOffsetMinutes));
191  case TimeZoneData::kTypeZoneId:
192  return createForZoneId(d.zoneId);
193  default:
194  // Maybe this should return TimeZone::forError()?
195  return TimeZone();
196  }
197  }
198 
199  uint16_t indexForZoneName(const char* name) const override {
200  return mZoneRegistrar.findIndexForName(name);
201  }
202 
203  uint16_t indexForZoneId(uint32_t id) const override {
204  return mZoneRegistrar.findIndexForId(id);
205  }
206 
207  uint16_t zoneRegistrySize() const override {
208  return mZoneRegistrar.zoneRegistrySize();
209  }
210 
211  uint16_t linkRegistrySize() const override {
212  return mLinkRegistrar.linkRegistrySize();
213  }
214 
222  TimeZone createForZoneInfo(const ZI* zoneInfo) {
223  if (! zoneInfo) return TimeZone::forError();
224  ZP* processor = (ZP*) mZoneProcessorCache.getZoneProcessor(
225  (uintptr_t) zoneInfo);
226  return TimeZone::forZoneInfo(zoneInfo, processor);
227  }
228 
229  protected:
239  uint16_t zoneRegistrySize,
240  const ZI* const* zoneRegistry,
241  uint16_t linkRegistrySize,
242  const LE* linkRegistry
243  ):
244  mZoneRegistrar(zoneRegistrySize, zoneRegistry),
245  mLinkRegistrar(linkRegistrySize, linkRegistry),
246  mZoneProcessorCache() {}
247 
248  private:
249  // disable copy constructor and assignment operator
250  ZoneManagerImpl(const ZoneManagerImpl&) = delete;
251  ZoneManagerImpl& operator=(const ZoneManagerImpl&) = delete;
252 
253  const ZRR mZoneRegistrar;
254  const LRR mLinkRegistrar;
255  ZPC mZoneProcessorCache;
256 };
257 
258 #if 1
259 
265 template<uint16_t SIZE>
267  basic::ZoneInfo,
268  basic::ZoneRegistrar,
269  basic::LinkEntry,
270  basic::LinkRegistrar,
271  BasicZoneProcessor,
272  BasicZoneProcessorCache<SIZE>
273 > {
274 
275  public:
277  uint16_t zoneRegistrySize,
278  const basic::ZoneInfo* const* zoneRegistry,
279  uint16_t linkRegistrySize = 0,
280  const basic::LinkEntry* linkRegistry = nullptr
281  ):
283  basic::ZoneInfo,
285  basic::LinkEntry,
289  >(
291  zoneRegistry,
293  linkRegistry
294  )
295  {}
296 };
297 
304 template<uint16_t SIZE>
306  extended::ZoneInfo,
307  extended::ZoneRegistrar,
308  extended::LinkEntry,
309  extended::LinkRegistrar,
310  ExtendedZoneProcessor,
311  ExtendedZoneProcessorCache<SIZE>
312 > {
313 
314  public:
316  uint16_t zoneRegistrySize,
317  const extended::ZoneInfo* const* zoneRegistry,
318  uint16_t linkRegistrySize = 0,
319  const extended::LinkEntry* linkRegistry = nullptr
320  ):
322  extended::ZoneInfo,
324  extended::LinkEntry,
328  >(
330  zoneRegistry,
332  linkRegistry
333  )
334  {}
335 };
336 
337 #else
338 
339 // NOTE: The following typedefs seem shorter and easier to maintain. The
340 // problem is that they make error messages basically impossible to decipher
341 // because the template class names are far too long for human comprehension.
342 // Fortunatley, there seems to be no difference in code size between the above
343 // solution using subclasses and this solution using typedefs. The compiler
344 // seems to optimize away the vtables of the parent and child classes. So we'll
345 // use the above subclassing solution to get better error messages.
346 
347 template<uint8_t SIZE>
349  basic::ZoneInfo,
351  basic::LinkEntry,
355 >;
356 
357 template<uint8_t SIZE>
359  extended::ZoneInfo,
361  extended::LinkEntry,
365 >;
366 
367 #endif
368 
369 }
370 
371 #endif
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:90
ace_time::BasicZoneProcessorCache
Definition: ZoneProcessorCache.h:81
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:178
ace_time::ManualZoneManager
A ZoneManager that implements only createForTimeZoneData() to create TimeZones of type kTypeManual,...
Definition: ZoneManager.h:83
ace_time::ManualZoneManager::indexForZoneName
uint16_t indexForZoneName(const char *) const override
Find the registry index for the given time zone name.
Definition: ZoneManager.h:111
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::extended::LinkRegistrar
Concrete template instantiation of LinkRegistrarTemplate for extended::LinkEntry.
Definition: LinkRegistrar.h:212
ace_time::ZoneManagerImpl::createForZoneName
TimeZone createForZoneName(const char *name) override
Create a TimeZone for the given zone name (e.g.
Definition: ZoneManager.h:159
ace_time::ExtendedZoneProcessor
A specific implementation of ExtendedZoneProcessorTemplate that uses ZoneXxxBrokers which read from z...
Definition: ExtendedZoneProcessor.h:1712
ace_time::ManualZoneManager::zoneRegistrySize
uint16_t zoneRegistrySize() const override
Return the number of elements in the Zone (and fat Link) registry.
Definition: ZoneManager.h:119
ace_time::ZoneManagerImpl::linkRegistrySize
uint16_t linkRegistrySize() const override
Return the number of elements in the (thin) Link registry.
Definition: ZoneManager.h:211
ace_time::ZoneManager::createForZoneId
virtual TimeZone createForZoneId(uint32_t id)=0
Create a TimeZone for the given 32-bit zoneId.
ace_time::extended::ZoneRegistrar
Concrete template instantiation of ZoneRegistrarTemplate for extended::ZoneInfo, which can be used wi...
Definition: ZoneRegistrar.h:260
ace_time::ZoneManager::linkRegistrySize
virtual uint16_t linkRegistrySize() const =0
Return the number of elements in the (thin) Link registry.
ace_time::BasicZoneManager
An implementation of the ZoneManager which uses a registry of basic::ZoneInfo records.
Definition: ZoneManager.h:266
ace_time::ZoneManager::kInvalidIndex
static const uint16_t kInvalidIndex
Registry index which is not valid.
Definition: ZoneManager.h:28
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::ZoneManagerImpl::createForTimeZoneData
TimeZone createForTimeZoneData(const TimeZoneData &d) override
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
Definition: ZoneManager.h:183
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:25
ace_time::ZoneManagerImpl::createForZoneInfo
TimeZone createForZoneInfo(const ZI *zoneInfo)
Create a TimeZone from an explicit ZoneInfo reference.
Definition: ZoneManager.h:222
ace_time::ZoneManagerImpl::zoneRegistrySize
uint16_t zoneRegistrySize() const override
Return the number of elements in the Zone (and fat Link) registry.
Definition: ZoneManager.h:207
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:94
ace_time::ManualZoneManager::createForTimeZoneData
TimeZone createForTimeZoneData(const TimeZoneData &d) override
Create a TimeZone from the TimeZoneData created by TimeZone::toTimeZoneData().
Definition: ZoneManager.h:98
ace_time::ExtendedZoneManager
An implementation of the ZoneManager which uses a registry of extended::ZoneInfo records.
Definition: ZoneManager.h:305
ace_time::basic::LinkRegistrar
Concrete template instantiation of LinkRegistrarTemplate for basic::LinkEntry.
Definition: LinkRegistrar.h:170
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:199
ace_time::ZoneManagerImpl
A templatized implementation of ZoneManager that binds the ZoneRegistrar with the corresponding (Basi...
Definition: ZoneManager.h:157
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:991
ace_time::ZoneManagerImpl::ZoneManagerImpl
ZoneManagerImpl(uint16_t zoneRegistrySize, const ZI *const *zoneRegistry, uint16_t linkRegistrySize, const LE *linkRegistry)
Constructor.
Definition: ZoneManager.h:238
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::ZoneManagerImpl::indexForZoneId
uint16_t indexForZoneId(uint32_t id) const override
Find the registry index for the given time zone id.
Definition: ZoneManager.h:203
ace_time::ManualZoneManager::indexForZoneId
uint16_t indexForZoneId(uint32_t) const override
Find the registry index for the given time zone id.
Definition: ZoneManager.h:115
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:86
ace_time::ZoneManagerImpl::createForZoneId
TimeZone createForZoneId(uint32_t id) override
Create a TimeZone for the given 32-bit zoneId.
Definition: ZoneManager.h:164
ace_time::ManualZoneManager::linkRegistrySize
uint16_t linkRegistrySize() const override
Return the number of elements in the (thin) Link registry.
Definition: ZoneManager.h:121