AceTime  1.9.0
Date and time classes for Arduino that support timezones from the TZ Database.
ExtendedBrokers.h
Go to the documentation of this file.
1 /*
2  * MIT License
3  * Copyright (c) 2019 Brian T. Park
4  */
5 
6 #ifndef ACE_TIME_EXTENDED_BROKERS_H
7 #define ACE_TIME_EXTENDED_BROKERS_H
8 
38 #include <stdint.h> // uintptr_t
39 #include "../common/compat.h"
40 #include "BrokerCommon.h"
41 #include "ZoneInfo.h"
42 #include "LinkEntry.h"
43 
44 class __FlashStringHelper;
45 
46 namespace ace_time {
47 namespace extended {
48 
57 inline int16_t toDeltaMinutes(int8_t deltaCode) {
58  return ((int8_t)((uint8_t)deltaCode & 0x0f) - 4) * 15;
59 }
60 
66 inline int16_t toOffsetMinutes(int8_t offsetCode, int8_t deltaCode) {
67  return (offsetCode * 15) + (((uint8_t)deltaCode & 0xf0) >> 4);
68 }
69 
70 //-----------------------------------------------------------------------------
71 
74  public:
75  explicit ZoneRuleBroker(const ZoneRule* zoneRule = nullptr):
76  mZoneRule(zoneRule) {}
77 
78  // use the default copy constructor
79  ZoneRuleBroker(const ZoneRuleBroker&) = default;
80 
81  // use the default assignment operator
82  ZoneRuleBroker& operator=(const ZoneRuleBroker&) = default;
83 
84  bool isNull() const { return mZoneRule == nullptr; }
85 
86  #if ACE_TIME_USE_PROGMEM
87 
88  int8_t fromYearTiny() const {
89  return pgm_read_byte(&mZoneRule->fromYearTiny);
90  }
91 
92  int8_t toYearTiny() const {
93  return pgm_read_byte(&mZoneRule->toYearTiny);
94  }
95 
96  uint8_t inMonth() const {
97  return pgm_read_byte(&mZoneRule->inMonth);
98  }
99 
100  uint8_t onDayOfWeek() const {
101  return pgm_read_byte(&mZoneRule->onDayOfWeek);
102  }
103 
104  int8_t onDayOfMonth() const {
105  return pgm_read_byte(&mZoneRule->onDayOfMonth);
106  }
107 
108  uint16_t atTimeMinutes() const {
109  return internal::timeCodeToMinutes(
110  pgm_read_byte(&mZoneRule->atTimeCode),
111  pgm_read_byte(&mZoneRule->atTimeModifier));
112  }
113 
114  uint8_t atTimeSuffix() const {
115  return internal::toSuffix(pgm_read_byte(&mZoneRule->atTimeModifier));
116  }
117 
118  int16_t deltaMinutes() const {
119  return toDeltaMinutes(pgm_read_byte(&mZoneRule->deltaCode));
120  }
121 
122  uint8_t letter() const {
123  return pgm_read_byte(&mZoneRule->letter);
124  }
125 
126  #else
127 
128  int8_t fromYearTiny() const { return mZoneRule->fromYearTiny; }
129 
130  int8_t toYearTiny() const { return mZoneRule->toYearTiny; }
131 
132  uint8_t inMonth() const { return mZoneRule->inMonth; }
133 
134  int8_t onDayOfWeek() const { return mZoneRule->onDayOfWeek; }
135 
136  int8_t onDayOfMonth() const { return mZoneRule->onDayOfMonth; }
137 
138  uint16_t atTimeMinutes() const {
139  return internal::timeCodeToMinutes(
140  mZoneRule->atTimeCode, mZoneRule->atTimeModifier);
141  }
142 
143  uint8_t atTimeSuffix() const {
144  return internal::toSuffix(mZoneRule->atTimeModifier);
145  }
146 
147  int16_t deltaMinutes() const {
148  return toDeltaMinutes(mZoneRule->deltaCode);
149  }
150 
151  uint8_t letter() const { return mZoneRule->letter; }
152 
153  #endif
154 
155  private:
156  const ZoneRule* mZoneRule;
157 };
158 
161  public:
162  explicit ZonePolicyBroker(const ZonePolicy* zonePolicy):
163  mZonePolicy(zonePolicy) {}
164 
165  // use default copy constructor
166  ZonePolicyBroker(const ZonePolicyBroker&) = default;
167 
168  // use default assignment operator
169  ZonePolicyBroker& operator=(const ZonePolicyBroker&) = default;
170 
171  bool isNull() const { return mZonePolicy == nullptr; }
172 
173  #if ACE_TIME_USE_PROGMEM
174 
175  uint8_t numRules() const {
176  return pgm_read_byte(&mZonePolicy->numRules);
177  }
178 
179  const ZoneRuleBroker rule(uint8_t i) const {
180  const ZoneRule* rules =
181  (const ZoneRule*) pgm_read_ptr(&mZonePolicy->rules);
182  return ZoneRuleBroker(&rules[i]);
183  }
184 
185  uint8_t numLetters() const {
186  return pgm_read_byte(&mZonePolicy->numLetters);
187  }
188 
189  const char* letter(uint8_t i) const {
190  const char* const* letters = (const char* const*)
191  pgm_read_ptr(&mZonePolicy->letters);
192  return (const char*) pgm_read_ptr(&letters[i]);
193  }
194 
195  #else
196 
197  uint8_t numRules() const { return mZonePolicy->numRules; }
198 
199  const ZoneRuleBroker rule(uint8_t i) const {
200  return ZoneRuleBroker(&mZonePolicy->rules[i]);
201  }
202 
203  uint8_t numLetters() const { return mZonePolicy->numLetters; }
204 
205  const char* letter(uint8_t i) const {
206  return mZonePolicy->letters[i];
207  }
208 
209  #endif
210 
211  private:
212  const ZonePolicy* mZonePolicy;
213 };
214 
215 //-----------------------------------------------------------------------------
216 
219  public:
220  explicit ZoneEraBroker(const ZoneEra* zoneEra = nullptr):
221  mZoneEra(zoneEra) {}
222 
223  // use default copy constructor
224  ZoneEraBroker(const ZoneEraBroker&) = default;
225 
226  // use default assignment operator
227  ZoneEraBroker& operator=(const ZoneEraBroker&) = default;
228 
229  bool isNull() const { return mZoneEra == nullptr; }
230 
231  // Does not seem to be used, but defined here for symmetry with
232  // basic::ZoneEraBroker::equals().
233  bool equals(const ZoneEraBroker& other) const {
234  return mZoneEra == other.mZoneEra;
235  }
236 
237  #if ACE_TIME_USE_PROGMEM
238 
239  const ZonePolicyBroker zonePolicy() const {
240  return ZonePolicyBroker(
241  (const ZonePolicy*) pgm_read_ptr(&mZoneEra->zonePolicy));
242  }
243 
244  int16_t offsetMinutes() const {
245  return toOffsetMinutes(
246  pgm_read_byte(&mZoneEra->offsetCode),
247  pgm_read_byte(&mZoneEra->deltaCode));
248  }
249 
250  int16_t deltaMinutes() const {
251  return toDeltaMinutes(pgm_read_byte(&mZoneEra->deltaCode));
252  }
253 
254  const char* format() const {
255  return (const char*) pgm_read_ptr(&mZoneEra->format);
256  }
257 
258  int8_t untilYearTiny() const {
259  return pgm_read_byte(&mZoneEra->untilYearTiny);
260  }
261 
262  uint8_t untilMonth() const {
263  return pgm_read_byte(&mZoneEra->untilMonth);
264  }
265 
266  uint8_t untilDay() const {
267  return pgm_read_byte(&mZoneEra->untilDay);
268  }
269 
270  uint16_t untilTimeMinutes() const {
271  return internal::timeCodeToMinutes(
272  pgm_read_byte(&mZoneEra->untilTimeCode),
273  pgm_read_byte(&mZoneEra->untilTimeModifier));
274  }
275 
276  uint8_t untilTimeSuffix() const {
277  return internal::toSuffix(pgm_read_byte(&mZoneEra->untilTimeModifier));
278  }
279 
280  #else
281 
282  const ZonePolicyBroker zonePolicy() const {
283  return ZonePolicyBroker(mZoneEra->zonePolicy);
284  }
285 
286  int16_t offsetMinutes() const {
287  return toOffsetMinutes(mZoneEra->offsetCode, mZoneEra->deltaCode);
288  }
289 
290  int16_t deltaMinutes() const {
291  return toDeltaMinutes(mZoneEra->deltaCode);
292  }
293 
294  const char* format() const { return mZoneEra->format; }
295 
296  int8_t untilYearTiny() const { return mZoneEra->untilYearTiny; }
297 
298  uint8_t untilMonth() const { return mZoneEra->untilMonth; }
299 
300  uint8_t untilDay() const { return mZoneEra->untilDay; }
301 
302  uint16_t untilTimeMinutes() const {
303  return internal::timeCodeToMinutes(
304  mZoneEra->untilTimeCode, mZoneEra->untilTimeModifier);
305  }
306 
307  uint8_t untilTimeSuffix() const {
308  return internal::toSuffix(mZoneEra->untilTimeModifier);
309  }
310 
311  #endif
312 
313  private:
314  const ZoneEra* mZoneEra;
315 };
316 
319  public:
320  explicit ZoneInfoBroker(const ZoneInfo* zoneInfo = nullptr):
321  mZoneInfo(zoneInfo) {}
322 
323  // use default copy constructor
324  ZoneInfoBroker(const ZoneInfoBroker&) = default;
325 
326  // use default assignment operator
327  ZoneInfoBroker& operator=(const ZoneInfoBroker&) = default;
328 
329  bool equals(uintptr_t zoneInfo) const {
330  return mZoneInfo == (const ZoneInfo*) zoneInfo;
331  }
332 
333  bool equals(const ZoneInfoBroker& zoneInfoBroker) const {
334  return mZoneInfo == zoneInfoBroker.mZoneInfo;
335  }
336 
337  bool isNull() const { return mZoneInfo == nullptr; }
338 
339  #if ACE_TIME_USE_PROGMEM
340 
341  const internal::ZoneContext* zoneContext() const {
342  return (const internal::ZoneContext*)
343  pgm_read_ptr(&mZoneInfo->zoneContext);
344  }
345 
346  const __FlashStringHelper* name() const {
347  return FPSTR(pgm_read_ptr(&mZoneInfo->name));
348  }
349 
350  uint32_t zoneId() const {
351  return pgm_read_dword(&mZoneInfo->zoneId);
352  }
353 
354  uint8_t numEras() const {
355  return pgm_read_byte(&mZoneInfo->numEras);
356  }
357 
358  const ZoneEraBroker era(uint8_t i) const {
359  const ZoneEra* eras = (const ZoneEra*) pgm_read_ptr(&mZoneInfo->eras);
360  return ZoneEraBroker(&eras[i]);
361  }
362 
363  #else
364 
365  const internal::ZoneContext* zoneContext() const {
366  return mZoneInfo->zoneContext;
367  }
368 
369  const char* name() const { return mZoneInfo->name; }
370 
371  uint32_t zoneId() const { return mZoneInfo->zoneId; }
372 
373  uint8_t numEras() const { return mZoneInfo->numEras; }
374 
375  const ZoneEraBroker era(uint8_t i) const {
376  return ZoneEraBroker(&mZoneInfo->eras[i]);
377  }
378 
379  #endif
380 
382  void printNameTo(Print& printer) const;
383 
385  void printShortNameTo(Print& printer) const;
386 
387  private:
388  const ZoneInfo* mZoneInfo;
389 };
390 
396  public:
397  ZoneRegistryBroker(const ZoneInfo* const* zoneRegistry):
398  mZoneRegistry(zoneRegistry) {}
399 
400  // use default copy constructor
401  ZoneRegistryBroker(const ZoneRegistryBroker&) = default;
402 
403  // use default assignment operator
404  ZoneRegistryBroker& operator=(const ZoneRegistryBroker&) = default;
405 
406  #if ACE_TIME_USE_PROGMEM
407 
408  const ZoneInfo* zoneInfo(uint16_t i) const {
409  return (const ZoneInfo*) pgm_read_ptr(&mZoneRegistry[i]);
410  }
411 
412  #else
413 
414  const ZoneInfo* zoneInfo(uint16_t i) const {
415  return mZoneRegistry[i];
416  }
417 
418  #endif
419 
420  private:
421  const ZoneInfo* const* mZoneRegistry;
422 };
423 
424 //-----------------------------------------------------------------------------
425 
428  public:
429  explicit LinkEntryBroker(const LinkEntry* linkEntry = nullptr):
430  mLinkEntry(linkEntry) {}
431 
432  // use default copy constructor
433  LinkEntryBroker(const LinkEntryBroker&) = default;
434 
435  // use default assignment operator
436  LinkEntryBroker& operator=(const LinkEntryBroker&) = default;
437 
438  #if ACE_TIME_USE_PROGMEM
439  uint32_t zoneId() const { return pgm_read_dword(&mLinkEntry->zoneId); }
440  uint32_t linkId() const { return pgm_read_dword(&mLinkEntry->linkId); }
441 
442  #else
443  uint32_t zoneId() const { return mLinkEntry->zoneId; }
444  uint32_t linkId() const { return mLinkEntry->linkId; }
445 
446  #endif
447 
448  private:
449  const LinkEntry* mLinkEntry;
450 };
451 
456  public:
457  LinkRegistryBroker(const LinkEntry zoneRegistry[]):
458  mLinkRegistry(zoneRegistry) {}
459 
460  // use default copy constructor
461  LinkRegistryBroker(const LinkRegistryBroker&) = default;
462 
463  // use default assignment operator
464  LinkRegistryBroker& operator=(const LinkRegistryBroker&) = default;
465 
466  // Same code can be used whether or not ACE_TIME_USE_PROGMEM is active
467  // because mLinkRegistry stores the actual LinkEntry, instead of a pointer
468  // to LinkEntry.
469  const LinkEntry* linkEntry(uint16_t i) const {
470  return &mLinkRegistry[i];
471  }
472 
473  private:
474  const LinkEntry* mLinkRegistry;
475 };
476 
477 //-----------------------------------------------------------------------------
478 
481  public:
482  ZoneInfoBroker createZoneInfoBroker(uintptr_t zoneKey) const {
483  return ZoneInfoBroker((const ZoneInfo*) zoneKey);
484  }
485 };
486 
487 } // extended
488 } // ace_time
489 
490 #endif
ace_time::extended::ZoneInfoBroker::printNameTo
void printNameTo(Print &printer) const
Print a human-readable identifier (e.g.
Definition: ExtendedBrokers.cpp:19
BrokerCommon.h
ace_time::extended::ZoneRuleBroker
Data broker for accessing ZoneRule.
Definition: ExtendedBrokers.h:73
ace_time::internal::ZoneContext
Metadata about the zone database.
Definition: ZoneContext.h:16
ace_time::extended::LinkEntryBroker
Data broker for accessing a LinkEntry.
Definition: ExtendedBrokers.h:427
ace_time::extended::ZoneRegistryBroker
Data broker for accessing the ZoneRegistry.
Definition: ExtendedBrokers.h:395
ace_time::extended::ZonePolicyBroker
Data broker for accessing ZonePolicy.
Definition: ExtendedBrokers.h:160
ace_time::extended::ZoneInfoBroker
Data broker for accessing ZoneInfo.
Definition: ExtendedBrokers.h:318
ace_time::extended::BrokerFactory
A factory that creates a basic::ZoneInfoBroker.
Definition: ExtendedBrokers.h:480
ace_time::extended::ZoneEraBroker
Data broker for accessing ZoneEra.
Definition: ExtendedBrokers.h:218
ace_time::extended::toOffsetMinutes
int16_t toOffsetMinutes(int8_t offsetCode, int8_t deltaCode)
Convert the offsetCode and deltaCode into a signed 8-bit integer.
Definition: ExtendedBrokers.h:66
ace_time::extended::ZoneInfoBroker::printShortNameTo
void printShortNameTo(Print &printer) const
Print a short human-readable identifier (e.g.
Definition: ExtendedBrokers.cpp:25
ace_time::extended::LinkRegistryBroker
Data broker for a LinkRegistry composed of LinkEntry records.
Definition: ExtendedBrokers.h:455
ace_time::extended::toDeltaMinutes
int16_t toDeltaMinutes(int8_t deltaCode)
Convert the deltaCode in the ZoneInfo struct to the actual deltaMinutes.
Definition: ExtendedBrokers.h:57