AceTime  2.3.0
Date and time classes for Arduino that support timezones from the TZ Database.
BrokersMid.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_MID_H
7 #define ACE_TIME_BROKERS_MID_H
8 
24 #include <stdint.h> // uintptr_t, uint32_t, etc
25 #include <Arduino.h> // pgm_read_xxx()
26 #include <AceCommon.h> // KString
27 #include "compat.h" // ACE_TIME_USE_PROGMEM
28 #include "BrokerCommon.h"
29 #include "ZoneInfoMid.h"
30 
31 class __FlashStringHelper;
32 class Print;
33 
34 namespace ace_time {
35 namespace zoneinfomid {
36 
37 //-----------------------------------------------------------------------------
38 
49 inline int16_t toDeltaMinutes(uint8_t deltaCode) {
50  return ((int16_t)(deltaCode & 0x0f) - 4) * 15;
51 }
52 
59 inline int16_t toOffsetMinutes(uint8_t offsetCode, uint8_t deltaCode) {
60  return ((int8_t)offsetCode * 15) + ((deltaCode & 0xf0) >> 4);
61 }
62 
63 
70 inline uint16_t timeCodeToMinutes(uint8_t code, uint8_t modifier) {
71  return code * (uint16_t) 15 + (modifier & 0x0f);
72 }
73 
79 inline uint8_t toSuffix(uint8_t modifier) {
80  return modifier & 0xf0;
81 }
82 
83 //-----------------------------------------------------------------------------
84 
90 template <typename ZC>
92  public:
93  explicit ZoneContextBroker(const ZC* zoneContext = nullptr)
94  : mZoneContext(zoneContext)
95  {}
96 
97  // use the default copy constructor
98  ZoneContextBroker(const ZoneContextBroker&) = default;
99 
100  // use the default assignment operator
101  ZoneContextBroker& operator=(const ZoneContextBroker&) = default;
102 
103  bool isNull() const { return mZoneContext == nullptr; }
104 
105  const ZC* raw() const { return mZoneContext; }
106 
107  int16_t startYear() const {
108  return (int16_t) pgm_read_word(&mZoneContext->startYear);
109  }
110 
111  int16_t untilYear() const {
112  return (int16_t) pgm_read_word(&mZoneContext->untilYear);
113  }
114 
115  int16_t startYearAccurate() const {
116  return (int16_t) pgm_read_word(&mZoneContext->startYearAccurate);
117  }
118 
119  int16_t untilYearAccurate() const {
120  return (int16_t) pgm_read_word(&mZoneContext->untilYearAccurate);
121  }
122 
123  int16_t baseYear() const {
124  return (int16_t) pgm_read_word(&mZoneContext->baseYear);
125  }
126 
127  int16_t maxTransitions() const {
128  return (int16_t) pgm_read_word(&mZoneContext->maxTransitions);
129  }
130 
131  const __FlashStringHelper* tzVersion() const {
132  return (const __FlashStringHelper*)
133  pgm_read_ptr(&mZoneContext->tzVersion);
134  }
135 
136  uint8_t numFragments() const {
137  return (uint8_t) pgm_read_byte(&mZoneContext->numFragments);
138  }
139 
140  uint8_t numLetters() const {
141  return (uint8_t) pgm_read_byte(&mZoneContext->numLetters);
142  }
143 
144  const __FlashStringHelper* const* fragments() const {
145  return (const __FlashStringHelper* const*)
146  pgm_read_ptr(&mZoneContext->fragments);
147  }
148 
149  const __FlashStringHelper* letter(uint8_t i) const {
150  const char * const* letters = (const char* const*)
151  pgm_read_ptr(&mZoneContext->letters);
152  const char* letter = (const char*) pgm_read_ptr(letters + i);
153  return (const __FlashStringHelper*) letter;
154  }
155 
156  private:
157  const ZC* mZoneContext;
158 };
159 
160 //-----------------------------------------------------------------------------
161 
168 template <typename ZC, typename ZR>
170  public:
171  explicit ZoneRuleBroker(
172  const ZC* zoneContext = nullptr,
173  const ZR* zoneRule = nullptr)
174  : mZoneContext(zoneContext)
175  , mZoneRule(zoneRule)
176  {}
177 
178  // use the default copy constructor
179  ZoneRuleBroker(const ZoneRuleBroker&) = default;
180 
181  // use the default assignment operator
182  ZoneRuleBroker& operator=(const ZoneRuleBroker&) = default;
183 
184  bool isNull() const { return mZoneRule == nullptr; }
185 
186  int16_t fromYear() const {
187  return pgm_read_word(&mZoneRule->fromYear);
188  }
189 
190  int16_t toYear() const {
191  return pgm_read_word(&mZoneRule->toYear);
192  }
193 
194  uint8_t inMonth() const {
195  return pgm_read_byte(&mZoneRule->inMonth);
196  }
197 
198  uint8_t onDayOfWeek() const {
199  return pgm_read_byte(&mZoneRule->onDayOfWeek);
200  }
201 
202  int8_t onDayOfMonth() const {
203  return pgm_read_byte(&mZoneRule->onDayOfMonth);
204  }
205 
206  uint32_t atTimeSeconds() const {
207  return 60 * timeCodeToMinutes(
208  pgm_read_byte(&mZoneRule->atTimeCode),
209  pgm_read_byte(&mZoneRule->atTimeModifier));
210  }
211 
212  uint8_t atTimeSuffix() const {
213  return toSuffix(pgm_read_byte(&mZoneRule->atTimeModifier));
214  }
215 
216  int32_t deltaSeconds() const {
217  return 60 * toDeltaMinutes(pgm_read_byte(&mZoneRule->deltaCode));
218  }
219 
220  const __FlashStringHelper* letter() const {
221  uint8_t index = pgm_read_byte(&mZoneRule->letterIndex);
222  return ZoneContextBroker<ZC>(mZoneContext).letter(index);
223  }
224 
225  private:
226  const ZC* mZoneContext;
227  const ZR* mZoneRule;
228 };
229 
237 template <typename ZC, typename ZP, typename ZR>
239  public:
240  explicit ZonePolicyBroker(
241  const ZC* zoneContext,
242  const ZP* zonePolicy)
243  : mZoneContext(zoneContext)
244  , mZonePolicy(zonePolicy)
245  {}
246 
247  // use default copy constructor
248  ZonePolicyBroker(const ZonePolicyBroker&) = default;
249 
250  // use default assignment operator
251  ZonePolicyBroker& operator=(const ZonePolicyBroker&) = default;
252 
253  bool isNull() const { return mZonePolicy == nullptr; }
254 
255  uint8_t numRules() const {
256  return pgm_read_byte(&mZonePolicy->numRules);
257  }
258 
259  const ZoneRuleBroker<ZC, ZR> rule(uint8_t i) const {
260  const ZR* rules = (const ZR*) pgm_read_ptr(&mZonePolicy->rules);
261  return ZoneRuleBroker<ZC, ZR>(mZoneContext, &rules[i]);
262  }
263 
264  private:
265  const ZC* mZoneContext;
266  const ZP* mZonePolicy;
267 };
268 
269 //-----------------------------------------------------------------------------
270 
279 template <typename ZC, typename ZE, typename ZP, typename ZR>
281  public:
282  explicit ZoneEraBroker(
283  const ZC* zoneContext = nullptr,
284  const ZE* zoneEra = nullptr)
285  : mZoneContext(zoneContext)
286  , mZoneEra(zoneEra)
287  {}
288 
289  // use default copy constructor
290  ZoneEraBroker(const ZoneEraBroker&) = default;
291 
292  // use default assignment operator
293  ZoneEraBroker& operator=(const ZoneEraBroker&) = default;
294 
295  bool isNull() const { return mZoneEra == nullptr; }
296 
297  bool equals(const ZoneEraBroker& other) const {
298  return mZoneEra == other.mZoneEra;
299  }
300 
301  const ZonePolicyBroker<ZC, ZP, ZR> zonePolicy() const {
303  mZoneContext,
304  (const ZP*) pgm_read_ptr(&mZoneEra->zonePolicy));
305  }
306 
307  int32_t offsetSeconds() const {
308  return 60 * toOffsetMinutes(
309  pgm_read_byte(&mZoneEra->offsetCode),
310  pgm_read_byte(&mZoneEra->deltaCode));
311  }
312 
313  int32_t deltaSeconds() const {
314  return 60 * toDeltaMinutes(pgm_read_byte(&mZoneEra->deltaCode));
315  }
316 
317  const char* format() const {
318  return (const char*) pgm_read_ptr(&mZoneEra->format);
319  }
320 
321  int16_t untilYear() const {
322  return pgm_read_word(&mZoneEra->untilYear);
323  }
324 
325  uint8_t untilMonth() const {
326  return pgm_read_byte(&mZoneEra->untilMonth);
327  }
328 
329  uint8_t untilDay() const {
330  return pgm_read_byte(&mZoneEra->untilDay);
331  }
332 
333  uint32_t untilTimeSeconds() const {
334  return 60 * timeCodeToMinutes(
335  pgm_read_byte(&mZoneEra->untilTimeCode),
336  pgm_read_byte(&mZoneEra->untilTimeModifier));
337  }
338 
339  uint8_t untilTimeSuffix() const {
340  return toSuffix(pgm_read_byte(&mZoneEra->untilTimeModifier));
341  }
342 
343  private:
344  const ZC* mZoneContext;
345  const ZE* mZoneEra;
346 };
347 
357 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
359  public:
360  explicit ZoneInfoBroker(const ZI* zoneInfo = nullptr):
361  mZoneInfo(zoneInfo) {}
362 
363  // use default copy constructor
364  ZoneInfoBroker(const ZoneInfoBroker&) = default;
365 
366  // use default assignment operator
367  ZoneInfoBroker& operator=(const ZoneInfoBroker&) = default;
368 
373  bool equals(uintptr_t zoneKey) const {
374  return mZoneInfo == (const ZI*) zoneKey;
375  }
376 
377  bool equals(const ZoneInfoBroker& zoneInfoBroker) const {
378  return mZoneInfo == zoneInfoBroker.mZoneInfo;
379  }
380 
381  bool isNull() const { return mZoneInfo == nullptr; }
382 
383  const ZoneContextBroker<ZC> zoneContext() const {
384  const ZC* context = (const ZC*) pgm_read_ptr(&mZoneInfo->zoneContext);
385  return ZoneContextBroker<ZC>(context);
386  }
387 
388  const __FlashStringHelper* name() const {
389  return FPSTR(pgm_read_ptr(&mZoneInfo->name));
390  }
391 
392  uint32_t zoneId() const {
393  return pgm_read_dword(&mZoneInfo->zoneId);
394  }
395 
396  uint8_t numEras() const {
397  return pgm_read_byte(&mZoneInfo->numEras);
398  }
399 
400  const ZoneEraBroker<ZC, ZE, ZP, ZR> era(uint8_t i) const {
401  auto eras = (const ZE*) pgm_read_ptr(&mZoneInfo->eras);
402  return ZoneEraBroker<ZC, ZE, ZP, ZR>(zoneContext().raw(), &eras[i]);
403  }
404 
405  bool isLink() const {
406  return mZoneInfo->targetInfo != nullptr;
407  }
408 
409  ZoneInfoBroker targetInfo() const {
410  return ZoneInfoBroker(
411  (const ZI*) pgm_read_ptr(&mZoneInfo->targetInfo));
412  }
413 
415  void printNameTo(Print& printer) const;
416 
421  void printShortNameTo(Print& printer) const;
422 
423  private:
424  const ZI* mZoneInfo;
425 };
426 
427 
428 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
430  ZoneContextBroker<ZC> zc = zoneContext();
431  ace_common::KString kname(name(), zc.fragments(), zc.numFragments());
432  kname.printTo(printer);
433 }
434 
435 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
437  const {
438  ace_common::printReplaceCharTo(
439  printer, zoneinfo::findShortName(name()), '_', ' ');
440 }
441 
442 //-----------------------------------------------------------------------------
443 
450 template <typename ZI>
452  public:
453  ZoneRegistryBroker(const ZI* const* zoneRegistry):
454  mZoneRegistry(zoneRegistry) {}
455 
456  // use default copy constructor
457  ZoneRegistryBroker(const ZoneRegistryBroker&) = default;
458 
459  // use default assignment operator
460  ZoneRegistryBroker& operator=(const ZoneRegistryBroker&) = default;
461 
462  const ZI* zoneInfo(uint16_t i) const {
463  return (const ZI*) pgm_read_ptr(&mZoneRegistry[i]);
464  }
465 
466  private:
467  const ZI* const* mZoneRegistry;
468 };
469 
470 //-----------------------------------------------------------------------------
471 
483 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
485  public:
491  createZoneInfoBroker(uintptr_t zoneKey) const {
492  return ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>((const ZI*) zoneKey);
493  }
494 };
495 
496 } // zoneinfomid
497 } // ace_time
498 
499 #endif
Helper functions are used in both Basic brokers and Extended brokers.
Data broker for accessing a ZoneContext.
Definition: BrokersMid.h:91
Data broker for accessing ZoneEra.
Definition: BrokersMid.h:280
Data broker for accessing ZoneInfo.
Definition: BrokersMid.h:358
void printShortNameTo(Print &printer) const
Print a short human-readable identifier (e.g.
Definition: BrokersMid.h:436
void printNameTo(Print &printer) const
Print a human-readable identifier (e.g.
Definition: BrokersMid.h:429
bool equals(uintptr_t zoneKey) const
Definition: BrokersMid.h:373
A storage object that creates an ZoneInfoBroker from a key that identifies the ZoneInfo.
Definition: BrokersMid.h:484
ZoneInfoBroker< ZC, ZI, ZE, ZP, ZR > createZoneInfoBroker(uintptr_t zoneKey) const
Definition: BrokersMid.h:491
Data broker for accessing ZonePolicy.
Definition: BrokersMid.h:238
Data broker for accessing the ZoneRegistry.
Definition: BrokersMid.h:451
Data broker for accessing ZoneRule.
Definition: BrokersMid.h:169
Macros and definitions that provide a consistency layer among the various Arduino boards for compatib...