AceTime  2.2.0
Date and time classes for Arduino that support timezones from the TZ Database.
Brokers.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_BROKERS_H
7 #define ACE_TIME_BROKERS_H
8 
38 #include <stdint.h> // uintptr_t, uint32_t, etc
39 #include <AceCommon.h> // KString
40 #include "compat.h" // ACE_TIME_USE_PROGMEM
41 #include "BrokerCommon.h"
42 #include "ZoneContext.h"
43 #include "ZoneInfo.h"
44 
45 class __FlashStringHelper;
46 class Print;
47 
48 namespace ace_time {
49 namespace internal {
50 
56 template <typename ZR>
58  public:
59  explicit ZoneRuleBroker(
60  const internal::ZoneContext* zoneContext = nullptr,
61  const ZR* zoneRule = nullptr)
62  : mZoneContext(zoneContext)
63  , mZoneRule(zoneRule)
64  {}
65 
66  // use the default copy constructor
67  ZoneRuleBroker(const ZoneRuleBroker&) = default;
68 
69  // use the default assignment operator
70  ZoneRuleBroker& operator=(const ZoneRuleBroker&) = default;
71 
72  bool isNull() const { return mZoneRule == nullptr; }
73 
74  #if ACE_TIME_USE_PROGMEM
75 
76  int16_t fromYear() const {
77  return pgm_read_word(&mZoneRule->fromYear);
78  }
79 
80  int16_t toYear() const {
81  return pgm_read_word(&mZoneRule->toYear);
82  }
83 
84  uint8_t inMonth() const {
85  return pgm_read_byte(&mZoneRule->inMonth);
86  }
87 
88  uint8_t onDayOfWeek() const {
89  return pgm_read_byte(&mZoneRule->onDayOfWeek);
90  }
91 
92  int8_t onDayOfMonth() const {
93  return pgm_read_byte(&mZoneRule->onDayOfMonth);
94  }
95 
96  uint16_t atTimeMinutes() const {
97  return internal::timeCodeToMinutes(
98  pgm_read_byte(&mZoneRule->atTimeCode),
99  pgm_read_byte(&mZoneRule->atTimeModifier));
100  }
101 
102  uint8_t atTimeSuffix() const {
103  return internal::toSuffix(pgm_read_byte(&mZoneRule->atTimeModifier));
104  }
105 
106  int16_t deltaMinutes() const {
107  return internal::toDeltaMinutes(pgm_read_byte(&mZoneRule->deltaCode));
108  }
109 
110  const char* letter() const {
111  uint8_t index = pgm_read_byte(&mZoneRule->letterIndex);
112  return mZoneContext->letters[index];
113  }
114 
115  #else
116 
117  int16_t fromYear() const { return mZoneRule->fromYear; }
118 
119  int16_t toYear() const { return mZoneRule->toYear; }
120 
121  uint8_t inMonth() const { return mZoneRule->inMonth; }
122 
123  uint8_t onDayOfWeek() const { return mZoneRule->onDayOfWeek; }
124 
125  int8_t onDayOfMonth() const { return mZoneRule->onDayOfMonth; }
126 
127  uint16_t atTimeMinutes() const {
128  return internal::timeCodeToMinutes(
129  mZoneRule->atTimeCode, mZoneRule->atTimeModifier);
130  }
131 
132  uint8_t atTimeSuffix() const {
133  return internal::toSuffix(mZoneRule->atTimeModifier);
134  }
135 
136  int16_t deltaMinutes() const {
137  return internal::toDeltaMinutes(mZoneRule->deltaCode);
138  }
139 
140  const char* letter() const {
141  uint8_t index = mZoneRule->letterIndex;
142  return mZoneContext->letters[index];
143  }
144 
145  #endif
146 
147  private:
148  const internal::ZoneContext* mZoneContext;
149  const ZR* mZoneRule;
150 };
151 
158 template <typename ZP, typename ZR>
160  public:
161  explicit ZonePolicyBroker(
162  const internal::ZoneContext* zoneContext,
163  const ZP* zonePolicy)
164  : mZoneContext(zoneContext)
165  , mZonePolicy(zonePolicy)
166  {}
167 
168  // use default copy constructor
169  ZonePolicyBroker(const ZonePolicyBroker&) = default;
170 
171  // use default assignment operator
172  ZonePolicyBroker& operator=(const ZonePolicyBroker&) = default;
173 
174  bool isNull() const { return mZonePolicy == nullptr; }
175 
176  #if ACE_TIME_USE_PROGMEM
177 
178  uint8_t numRules() const {
179  return pgm_read_byte(&mZonePolicy->numRules);
180  }
181 
182  const ZoneRuleBroker<ZR> rule(uint8_t i) const {
183  const ZR* rules = (const ZR*) pgm_read_ptr(&mZonePolicy->rules);
184  return ZoneRuleBroker<ZR>(mZoneContext, &rules[i]);
185  }
186 
187  #else
188 
189  uint8_t numRules() const { return mZonePolicy->numRules; }
190 
191  const ZoneRuleBroker<ZR> rule(uint8_t i) const {
192  return ZoneRuleBroker<ZR>(mZoneContext, &mZonePolicy->rules[i]);
193  }
194 
195  #endif
196 
197  private:
198  const internal::ZoneContext* mZoneContext;
199  const ZP* mZonePolicy;
200 };
201 
202 //-----------------------------------------------------------------------------
203 
211 template <typename ZE, typename ZP, typename ZR>
213  public:
214  explicit ZoneEraBroker(
215  const internal::ZoneContext* zoneContext = nullptr,
216  const ZE* zoneEra = nullptr)
217  : mZoneContext(zoneContext)
218  , mZoneEra(zoneEra)
219  {}
220 
221  // use default copy constructor
222  ZoneEraBroker(const ZoneEraBroker&) = default;
223 
224  // use default assignment operator
225  ZoneEraBroker& operator=(const ZoneEraBroker&) = default;
226 
227  bool isNull() const { return mZoneEra == nullptr; }
228 
229  bool equals(const ZoneEraBroker& other) const {
230  return mZoneEra == other.mZoneEra;
231  }
232 
233  #if ACE_TIME_USE_PROGMEM
234 
235  const ZonePolicyBroker<ZP, ZR> zonePolicy() const {
237  mZoneContext,
238  (const ZP*) pgm_read_ptr(&mZoneEra->zonePolicy));
239  }
240 
241  int16_t offsetMinutes() const {
242  return internal::toOffsetMinutes(
243  pgm_read_byte(&mZoneEra->offsetCode),
244  pgm_read_byte(&mZoneEra->deltaCode));
245  }
246 
247  int16_t deltaMinutes() const {
248  return internal::toDeltaMinutes(pgm_read_byte(&mZoneEra->deltaCode));
249  }
250 
251  const char* format() const {
252  return (const char*) pgm_read_ptr(&mZoneEra->format);
253  }
254 
255  int16_t untilYear() const {
256  return pgm_read_word(&mZoneEra->untilYear);
257  }
258 
259  uint8_t untilMonth() const {
260  return pgm_read_byte(&mZoneEra->untilMonth);
261  }
262 
263  uint8_t untilDay() const {
264  return pgm_read_byte(&mZoneEra->untilDay);
265  }
266 
267  uint16_t untilTimeMinutes() const {
268  return internal::timeCodeToMinutes(
269  pgm_read_byte(&mZoneEra->untilTimeCode),
270  pgm_read_byte(&mZoneEra->untilTimeModifier));
271  }
272 
273  uint8_t untilTimeSuffix() const {
274  return internal::toSuffix(pgm_read_byte(&mZoneEra->untilTimeModifier));
275  }
276 
277  #else
278 
279  const ZonePolicyBroker<ZP> zonePolicy() const {
280  return ZonePolicyBroker<ZP>(mZoneContext, mZoneEra->zonePolicy);
281  }
282 
283  int16_t offsetMinutes() const {
284  return internal::toOffsetMinutes(
285  mZoneEra->offsetCode, mZoneEra->deltaCode);
286  }
287 
288  int16_t deltaMinutes() const {
289  return internal::toDeltaMinutes(mZoneEra->deltaCode);
290  }
291 
292  const char* format() const { return mZoneEra->format; }
293 
294  int16_t untilYear() const { return mZoneEra->untilYear; }
295 
296  uint8_t untilMonth() const { return mZoneEra->untilMonth; }
297 
298  uint8_t untilDay() const { return mZoneEra->untilDay; }
299 
300  uint16_t untilTimeMinutes() const {
301  return internal::timeCodeToMinutes(
302  mZoneEra->untilTimeCode, mZoneEra->untilTimeModifier);
303  }
304 
305  uint8_t untilTimeSuffix() const {
306  return internal::toSuffix(mZoneEra->untilTimeModifier);
307  }
308 
309  #endif
310 
311  private:
312  const internal::ZoneContext* mZoneContext;
313  const ZE* mZoneEra;
314 };
315 
324 template <typename ZI, typename ZE, typename ZP, typename ZR>
326  public:
327  explicit ZoneInfoBroker(const ZI* zoneInfo = nullptr):
328  mZoneInfo(zoneInfo) {}
329 
330  // use default copy constructor
331  ZoneInfoBroker(const ZoneInfoBroker&) = default;
332 
333  // use default assignment operator
334  ZoneInfoBroker& operator=(const ZoneInfoBroker&) = default;
335 
340  bool equals(uintptr_t zoneKey) const {
341  return mZoneInfo == (const ZI*) zoneKey;
342  }
343 
344  bool equals(const ZoneInfoBroker& zoneInfoBroker) const {
345  return mZoneInfo == zoneInfoBroker.mZoneInfo;
346  }
347 
348  bool isNull() const { return mZoneInfo == nullptr; }
349 
350  #if ACE_TIME_USE_PROGMEM
351 
352  const internal::ZoneContext* zoneContext() const {
353  return (const internal::ZoneContext*)
354  pgm_read_ptr(&mZoneInfo->zoneContext);
355  }
356 
357  const __FlashStringHelper* name() const {
358  return FPSTR(pgm_read_ptr(&mZoneInfo->name));
359  }
360 
361  uint32_t zoneId() const {
362  return pgm_read_dword(&mZoneInfo->zoneId);
363  }
364 
365  uint8_t numEras() const {
366  return pgm_read_byte(&mZoneInfo->numEras);
367  }
368 
369  const ZoneEraBroker<ZE, ZP, ZR> era(uint8_t i) const {
370  auto eras = (const ZE*) pgm_read_ptr(&mZoneInfo->eras);
371  return ZoneEraBroker<ZE, ZP, ZR>(zoneContext(), &eras[i]);
372  }
373 
374  bool isLink() const {
375  return mZoneInfo->targetInfo != nullptr;
376  }
377 
378  ZoneInfoBroker targetInfo() const {
379  return ZoneInfoBroker(
380  (const ZI*) pgm_read_ptr(&mZoneInfo->targetInfo));
381  }
382 
383  #else
384 
385  const internal::ZoneContext* zoneContext() const {
386  return mZoneInfo->zoneContext;
387  }
388 
389  const char* name() const { return mZoneInfo->name; }
390 
391  uint32_t zoneId() const { return mZoneInfo->zoneId; }
392 
393  uint8_t numEras() const { return mZoneInfo->numEras; }
394 
395  const ZoneEraBroker era(uint8_t i) const {
396  return ZoneEraBroker(zoneContext(), &mZoneInfo->eras[i]);
397  }
398 
399  const ZoneInfoBroker targetInfo() const {
400  return ZoneInfoBroker(mZoneInfo->targetInfo);
401  }
402 
403  #endif
404 
406  void printNameTo(Print& printer) const;
407 
412  void printShortNameTo(Print& printer) const;
413 
414  private:
415  const ZI* mZoneInfo;
416 };
417 
418 
419 template <typename ZI, typename ZE, typename ZP, typename ZR>
421  const ZoneContext* zc = zoneContext();
422  ace_common::KString kname(name(), zc->fragments, zc->numFragments);
423  kname.printTo(printer);
424 }
425 
426 template <typename ZI, typename ZE, typename ZP, typename ZR>
428  ace_common::printReplaceCharTo(printer, findShortName(name()), '_', ' ');
429 }
430 
431 //-----------------------------------------------------------------------------
432 
439 template <typename ZI>
441  public:
442  ZoneRegistryBroker(const ZI* const* zoneRegistry):
443  mZoneRegistry(zoneRegistry) {}
444 
445  // use default copy constructor
446  ZoneRegistryBroker(const ZoneRegistryBroker&) = default;
447 
448  // use default assignment operator
449  ZoneRegistryBroker& operator=(const ZoneRegistryBroker&) = default;
450 
451  #if ACE_TIME_USE_PROGMEM
452 
453  const ZI* zoneInfo(uint16_t i) const {
454  return (const ZI*) pgm_read_ptr(&mZoneRegistry[i]);
455  }
456 
457  #else
458 
459  const ZI* zoneInfo(uint16_t i) const {
460  return mZoneRegistry[i];
461  }
462 
463  #endif
464 
465  private:
466  const ZI* const* mZoneRegistry;
467 };
468 
469 //-----------------------------------------------------------------------------
470 
479 template <typename ZI, typename ZE, typename ZP, typename ZR>
481  public:
487  createZoneInfoBroker(uintptr_t zoneKey) const {
488  return ZoneInfoBroker<ZI, ZE, ZP, ZR>((const ZI*) zoneKey);
489  }
490 };
491 
492 } // internal
493 
494 //-----------------------------------------------------------------------------
495 
496 namespace basic {
497 
500 
503 
506 
509  ZoneInfo, ZoneEra, ZonePolicy, ZoneRule>;
510 
516 
518  ZoneInfo, ZoneEra, ZonePolicy, ZoneRule>;
519 
520 } // basic
521 
522 //-----------------------------------------------------------------------------
523 
524 namespace extended {
525 
528 
531 
534 
537  ZoneInfo, ZoneEra, ZonePolicy, ZoneRule>;
538 
544 
546  ZoneInfo, ZoneEra, ZonePolicy, ZoneRule>;
547 
548 } // extended
549 
550 } // ace_time
551 
552 #endif
Helper functions are used in both Basic brokers and Extended brokers.
internal::ZoneEraBroker< ZoneEra, ZonePolicy, ZoneRule > ZoneEraBroker
Data broker for accessing ZoneEra.
Definition: Brokers.h:505
A factory that creates an ZoneInfoBroker.
Definition: Brokers.h:480
ZoneInfoBroker< ZI, ZE, ZP, ZR > createZoneInfoBroker(uintptr_t zoneKey) const
Definition: Brokers.h:487
Data broker for accessing ZoneEra.
Definition: Brokers.h:212
Data broker for accessing ZoneInfo.
Definition: Brokers.h:325
void printNameTo(Print &printer) const
Print a human-readable identifier (e.g.
Definition: Brokers.h:420
void printShortNameTo(Print &printer) const
Print a short human-readable identifier (e.g.
Definition: Brokers.h:427
bool equals(uintptr_t zoneKey) const
Definition: Brokers.h:340
Data broker for accessing ZonePolicy.
Definition: Brokers.h:159
Data broker for accessing the ZoneRegistry.
Definition: Brokers.h:440
Data broker for accessing ZoneRule.
Definition: Brokers.h:57
Macros and definitions that provide a consistency layer among the various Arduino boards for compatib...
Metadata about the zone database.
Definition: ZoneContext.h:16
uint8_t numFragments
Number of fragments.
Definition: ZoneContext.h:65
const char *const * fragments
Zone Name fragment list.
Definition: ZoneContext.h:68
const char *const * letters
Zone Rule letters list.
Definition: ZoneContext.h:74