AceTime 2.4.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>
91 class ZoneContextBroker {
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>
169 class ZoneRuleBroker {
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>
238 class ZonePolicyBroker {
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>
280 class ZoneEraBroker {
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 {
302 return ZonePolicyBroker<ZC, ZP, ZR>(
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>
358 class ZoneInfoBroker {
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>
429 void ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>::printNameTo(Print& printer) const {
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>
436 void ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>::printShortNameTo(Print& printer)
437 const {
438 ace_common::printReplaceCharTo(
439 printer, zoneinfo::findShortName(name()), '_', ' ');
440 }
441
442 //-----------------------------------------------------------------------------
443
450 template <typename ZI>
451 class ZoneRegistryBroker {
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>
484 class ZoneInfoStore {
485 public:
490 ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>
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
BrokerCommon.h
Helper functions are used in both Basic brokers and Extended brokers.
ZoneInfoMid.h
Data structures that describe the mid resolution zoneinfo persistence format.
ace_time::zoneinfomid::ZoneContextBroker
Data broker for accessing a ZoneContext.
Definition: BrokersMid.h:91
ace_time::zoneinfomid::ZoneEraBroker
Data broker for accessing ZoneEra.
Definition: BrokersMid.h:280
ace_time::zoneinfomid::ZoneInfoBroker
Data broker for accessing ZoneInfo.
Definition: BrokersMid.h:358
ace_time::zoneinfomid::ZoneInfoBroker::printShortNameTo
void printShortNameTo(Print &printer) const
Print a short human-readable identifier (e.g.
Definition: BrokersMid.h:436
ace_time::zoneinfomid::ZoneInfoBroker::printNameTo
void printNameTo(Print &printer) const
Print a human-readable identifier (e.g.
Definition: BrokersMid.h:429
ace_time::zoneinfomid::ZoneInfoBroker::equals
bool equals(uintptr_t zoneKey) const
Definition: BrokersMid.h:373
ace_time::zoneinfomid::ZoneInfoStore
A storage object that creates an ZoneInfoBroker from a key that identifies the ZoneInfo.
Definition: BrokersMid.h:484
ace_time::zoneinfomid::ZoneInfoStore::createZoneInfoBroker
ZoneInfoBroker< ZC, ZI, ZE, ZP, ZR > createZoneInfoBroker(uintptr_t zoneKey) const
Definition: BrokersMid.h:491
ace_time::zoneinfomid::ZonePolicyBroker
Data broker for accessing ZonePolicy.
Definition: BrokersMid.h:238
ace_time::zoneinfomid::ZoneRegistryBroker
Data broker for accessing the ZoneRegistry.
Definition: BrokersMid.h:451
ace_time::zoneinfomid::ZoneRuleBroker
Data broker for accessing ZoneRule.
Definition: BrokersMid.h:169
compat.h
Macros and definitions that provide a consistency layer among the various Arduino boards for compatib...