AceTime 2.4.0 Date and time classes for Arduino that support timezones from the TZ Database.

BrokersHigh.h
Go to the documentation of this file.
1 /*
2 * MIT License
3 * Copyright (c) 2023 Brian T. Park
4 */
5
6 #ifndef ACE_TIME_BROKERS_HIGH_H
7 #define ACE_TIME_BROKERS_HIGH_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 "ZoneInfoHigh.h"
30
31 class __FlashStringHelper;
32 class Print;
33
34 namespace ace_time {
35 namespace zoneinfohigh {
36
37 //-----------------------------------------------------------------------------
38
43 inline int32_t toDeltaSeconds(uint8_t deltaMinutes) {
44 return int32_t(60) * (int8_t) deltaMinutes;
45 }
46
50 inline int32_t toOffsetSeconds(uint16_t offsetCode, uint8_t offsetRemainder) {
51 return int32_t(15) * (int16_t) offsetCode + (int32_t) offsetRemainder;
52 }
53
60 inline uint32_t timeCodeToSeconds(uint16_t code, uint8_t modifier) {
61 return code * (uint32_t) 15 + (modifier & 0x0f);
62 }
63
69 inline uint8_t toSuffix(uint8_t modifier) {
70 return modifier & 0xf0;
71 }
72
73 //-----------------------------------------------------------------------------
74
80 template <typename ZC>
81 class ZoneContextBroker {
82 public:
83 explicit ZoneContextBroker(const ZC* zoneContext = nullptr)
84 : mZoneContext(zoneContext)
85 {}
86
87 // use the default copy constructor
88 ZoneContextBroker(const ZoneContextBroker&) = default;
89
90 // use the default assignment operator
91 ZoneContextBroker& operator=(const ZoneContextBroker&) = default;
92
93 bool isNull() const { return mZoneContext == nullptr; }
94
95 const ZC* raw() const { return mZoneContext; }
96
97 int16_t startYear() const {
98 return (int16_t) pgm_read_word(&mZoneContext->startYear);
99 }
100
101 int16_t untilYear() const {
102 return (int16_t) pgm_read_word(&mZoneContext->untilYear);
103 }
104
105 int16_t startYearAccurate() const {
106 return (int16_t) pgm_read_word(&mZoneContext->startYearAccurate);
107 }
108
109 int16_t untilYearAccurate() const {
110 return (int16_t) pgm_read_word(&mZoneContext->untilYearAccurate);
111 }
112
113 int16_t baseYear() const {
114 return (int16_t) pgm_read_word(&mZoneContext->baseYear);
115 }
116
117 int16_t maxTransitions() const {
118 return (int16_t) pgm_read_word(&mZoneContext->maxTransitions);
119 }
120
121 const __FlashStringHelper* tzVersion() const {
122 return (const __FlashStringHelper*)
123 pgm_read_ptr(&mZoneContext->tzVersion);
124 }
125
126 uint8_t numFragments() const {
127 return (uint8_t) pgm_read_byte(&mZoneContext->numFragments);
128 }
129
130 uint8_t numLetters() const {
131 return (uint8_t) pgm_read_byte(&mZoneContext->numLetters);
132 }
133
134 const __FlashStringHelper* const* fragments() const {
135 return (const __FlashStringHelper* const*)
136 pgm_read_ptr(&mZoneContext->fragments);
137 }
138
139 const __FlashStringHelper* letter(uint8_t i) const {
140 const char * const* letters = (const char* const*)
141 pgm_read_ptr(&mZoneContext->letters);
142 const char* letter = (const char*) pgm_read_ptr(letters + i);
143 return (const __FlashStringHelper*) letter;
144 }
145
146 private:
147 const ZC* mZoneContext;
148 };
149
150 //-----------------------------------------------------------------------------
151
158 template <typename ZC, typename ZR>
159 class ZoneRuleBroker {
160 public:
161 explicit ZoneRuleBroker(
162 const ZC* zoneContext = nullptr,
163 const ZR* zoneRule = nullptr)
164 : mZoneContext(zoneContext)
165 , mZoneRule(zoneRule)
166 {}
167
168 // use the default copy constructor
169 ZoneRuleBroker(const ZoneRuleBroker&) = default;
170
171 // use the default assignment operator
172 ZoneRuleBroker& operator=(const ZoneRuleBroker&) = default;
173
174 bool isNull() const { return mZoneRule == nullptr; }
175
176 int16_t fromYear() const {
177 return pgm_read_word(&mZoneRule->fromYear);
178 }
179
180 int16_t toYear() const {
181 return pgm_read_word(&mZoneRule->toYear);
182 }
183
184 uint8_t inMonth() const {
185 return pgm_read_byte(&mZoneRule->inMonth);
186 }
187
188 uint8_t onDayOfWeek() const {
189 return pgm_read_byte(&mZoneRule->onDayOfWeek);
190 }
191
192 int8_t onDayOfMonth() const {
193 return pgm_read_byte(&mZoneRule->onDayOfMonth);
194 }
195
196 uint32_t atTimeSeconds() const {
197 return timeCodeToSeconds(
198 pgm_read_word(&mZoneRule->atTimeCode),
199 pgm_read_byte(&mZoneRule->atTimeModifier));
200 }
201
202 uint8_t atTimeSuffix() const {
203 return toSuffix(pgm_read_byte(&mZoneRule->atTimeModifier));
204 }
205
206 int32_t deltaSeconds() const {
207 return toDeltaSeconds(pgm_read_byte(&mZoneRule->deltaMinutes));
208 }
209
210 const __FlashStringHelper* letter() const {
211 uint8_t index = pgm_read_byte(&mZoneRule->letterIndex);
212 return ZoneContextBroker<ZC>(mZoneContext).letter(index);
213 }
214
215 private:
216 const ZC* mZoneContext;
217 const ZR* mZoneRule;
218 };
219
227 template <typename ZC, typename ZP, typename ZR>
228 class ZonePolicyBroker {
229 public:
230 explicit ZonePolicyBroker(
231 const ZC* zoneContext,
232 const ZP* zonePolicy)
233 : mZoneContext(zoneContext)
234 , mZonePolicy(zonePolicy)
235 {}
236
237 // use default copy constructor
238 ZonePolicyBroker(const ZonePolicyBroker&) = default;
239
240 // use default assignment operator
241 ZonePolicyBroker& operator=(const ZonePolicyBroker&) = default;
242
243 bool isNull() const { return mZonePolicy == nullptr; }
244
245 uint8_t numRules() const {
246 return pgm_read_byte(&mZonePolicy->numRules);
247 }
248
249 const ZoneRuleBroker<ZC, ZR> rule(uint8_t i) const {
250 const ZR* rules = (const ZR*) pgm_read_ptr(&mZonePolicy->rules);
251 return ZoneRuleBroker<ZC, ZR>(mZoneContext, &rules[i]);
252 }
253
254 private:
255 const ZC* mZoneContext;
256 const ZP* mZonePolicy;
257 };
258
259 //-----------------------------------------------------------------------------
260
269 template <typename ZC, typename ZE, typename ZP, typename ZR>
270 class ZoneEraBroker {
271 public:
272 explicit ZoneEraBroker(
273 const ZC* zoneContext = nullptr,
274 const ZE* zoneEra = nullptr)
275 : mZoneContext(zoneContext)
276 , mZoneEra(zoneEra)
277 {}
278
279 // use default copy constructor
280 ZoneEraBroker(const ZoneEraBroker&) = default;
281
282 // use default assignment operator
283 ZoneEraBroker& operator=(const ZoneEraBroker&) = default;
284
285 bool isNull() const { return mZoneEra == nullptr; }
286
287 bool equals(const ZoneEraBroker& other) const {
288 return mZoneEra == other.mZoneEra;
289 }
290
291 const ZonePolicyBroker<ZC, ZP, ZR> zonePolicy() const {
292 return ZonePolicyBroker<ZC, ZP, ZR>(
293 mZoneContext,
294 (const ZP*) pgm_read_ptr(&mZoneEra->zonePolicy));
295 }
296
297 int32_t offsetSeconds() const {
298 return toOffsetSeconds(
299 pgm_read_word(&mZoneEra->offsetCode),
300 pgm_read_byte(&mZoneEra->offsetRemainder));
301 }
302
303 int32_t deltaSeconds() const {
304 return toDeltaSeconds(pgm_read_byte(&mZoneEra->deltaMinutes));
305 }
306
307 const char* format() const {
308 return (const char*) pgm_read_ptr(&mZoneEra->format);
309 }
310
311 int16_t untilYear() const {
312 return pgm_read_word(&mZoneEra->untilYear);
313 }
314
315 uint8_t untilMonth() const {
316 return pgm_read_byte(&mZoneEra->untilMonth);
317 }
318
319 uint8_t untilDay() const {
320 return pgm_read_byte(&mZoneEra->untilDay);
321 }
322
323 uint32_t untilTimeSeconds() const {
324 return timeCodeToSeconds(
325 pgm_read_word(&mZoneEra->untilTimeCode),
326 pgm_read_byte(&mZoneEra->untilTimeModifier));
327 }
328
329 uint8_t untilTimeSuffix() const {
330 return toSuffix(pgm_read_byte(&mZoneEra->untilTimeModifier));
331 }
332
333 private:
334 const ZC* mZoneContext;
335 const ZE* mZoneEra;
336 };
337
347 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
348 class ZoneInfoBroker {
349 public:
350 explicit ZoneInfoBroker(const ZI* zoneInfo = nullptr):
351 mZoneInfo(zoneInfo) {}
352
353 // use default copy constructor
354 ZoneInfoBroker(const ZoneInfoBroker&) = default;
355
356 // use default assignment operator
357 ZoneInfoBroker& operator=(const ZoneInfoBroker&) = default;
358
363 bool equals(uintptr_t zoneKey) const {
364 return mZoneInfo == (const ZI*) zoneKey;
365 }
366
367 bool equals(const ZoneInfoBroker& zoneInfoBroker) const {
368 return mZoneInfo == zoneInfoBroker.mZoneInfo;
369 }
370
371 bool isNull() const { return mZoneInfo == nullptr; }
372
373 const ZoneContextBroker<ZC> zoneContext() const {
374 const ZC* context = (const ZC*) pgm_read_ptr(&mZoneInfo->zoneContext);
375 return ZoneContextBroker<ZC>(context);
376 }
377
378 const __FlashStringHelper* name() const {
379 return FPSTR(pgm_read_ptr(&mZoneInfo->name));
380 }
381
382 uint32_t zoneId() const {
383 return pgm_read_dword(&mZoneInfo->zoneId);
384 }
385
386 uint8_t numEras() const {
387 return pgm_read_byte(&mZoneInfo->numEras);
388 }
389
390 const ZoneEraBroker<ZC, ZE, ZP, ZR> era(uint8_t i) const {
391 auto eras = (const ZE*) pgm_read_ptr(&mZoneInfo->eras);
392 return ZoneEraBroker<ZC, ZE, ZP, ZR>(zoneContext().raw(), &eras[i]);
393 }
394
395 bool isLink() const {
396 return mZoneInfo->targetInfo != nullptr;
397 }
398
399 ZoneInfoBroker targetInfo() const {
400 return ZoneInfoBroker(
401 (const ZI*) pgm_read_ptr(&mZoneInfo->targetInfo));
402 }
403
405 void printNameTo(Print& printer) const;
406
411 void printShortNameTo(Print& printer) const;
412
413 private:
414 const ZI* mZoneInfo;
415 };
416
417
418 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
419 void ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>::printNameTo(Print& printer) const {
420 ZoneContextBroker<ZC> zc = zoneContext();
421 ace_common::KString kname(name(), zc.fragments(), zc.numFragments());
422 kname.printTo(printer);
423 }
424
425 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
426 void ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>::printShortNameTo(Print& printer)
427 const {
428 ace_common::printReplaceCharTo(
429 printer, zoneinfo::findShortName(name()), '_', ' ');
430 }
431
432 //-----------------------------------------------------------------------------
433
440 template <typename ZI>
441 class ZoneRegistryBroker {
442 public:
443 ZoneRegistryBroker(const ZI* const* zoneRegistry):
444 mZoneRegistry(zoneRegistry) {}
445
446 // use default copy constructor
447 ZoneRegistryBroker(const ZoneRegistryBroker&) = default;
448
449 // use default assignment operator
450 ZoneRegistryBroker& operator=(const ZoneRegistryBroker&) = default;
451
452 const ZI* zoneInfo(uint16_t i) const {
453 return (const ZI*) pgm_read_ptr(&mZoneRegistry[i]);
454 }
455
456 private:
457 const ZI* const* mZoneRegistry;
458 };
459
460 //-----------------------------------------------------------------------------
461
473 template <typename ZC, typename ZI, typename ZE, typename ZP, typename ZR>
474 class ZoneInfoStore {
475 public:
480 ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>
481 createZoneInfoBroker(uintptr_t zoneKey) const {
482 return ZoneInfoBroker<ZC, ZI, ZE, ZP, ZR>((const ZI*) zoneKey);
483 }
484 };
485
486 } // zoneinfohigh
487 } // ace_time
488
489 #endif
BrokerCommon.h
Helper functions are used in both Basic brokers and Extended brokers.
ace_time::zoneinfohigh::timeCodeToSeconds
uint32_t timeCodeToSeconds(uint16_t code, uint8_t modifier)
Convert (code, modifier) holding the UNTIL time in ZoneInfo or AT time in ZoneRule into seconds.
Definition: BrokersHigh.h:60
ace_time::zoneinfohigh::toSuffix
uint8_t toSuffix(uint8_t modifier)
Extract the 'w', 's' 'u' suffix from the 'modifier' field, so that they can be compared against kSuff...
Definition: BrokersHigh.h:69
ace_time::zoneinfohigh::toDeltaSeconds
int32_t toDeltaSeconds(uint8_t deltaMinutes)
Convert the deltaMinutes holding the RULES/DSTOFF field in ZoneEra or the SAVE field in ZoneRule to d...
Definition: BrokersHigh.h:43
ace_time::zoneinfohigh::toOffsetSeconds
int32_t toOffsetSeconds(uint16_t offsetCode, uint8_t offsetRemainder)
Convert (code, remainder) holding the STDOFF field of ZoneEra into seconds.
Definition: BrokersHigh.h:50
ZoneInfoHigh.h
Data structures that encodes the high resolution zoneinfo database persistence format.
ace_time::zoneinfohigh::ZoneContextBroker
Data broker for accessing a ZoneContext.
Definition: BrokersHigh.h:81
ace_time::zoneinfohigh::ZoneEraBroker
Data broker for accessing ZoneEra.
Definition: BrokersHigh.h:270
ace_time::zoneinfohigh::ZoneInfoBroker
Data broker for accessing ZoneInfo.
Definition: BrokersHigh.h:348
ace_time::zoneinfohigh::ZoneInfoBroker::equals
bool equals(uintptr_t zoneKey) const
Definition: BrokersHigh.h:363
ace_time::zoneinfohigh::ZoneInfoBroker::printShortNameTo
void printShortNameTo(Print &printer) const
Print a short human-readable identifier (e.g.
Definition: BrokersHigh.h:426
ace_time::zoneinfohigh::ZoneInfoBroker::printNameTo
void printNameTo(Print &printer) const
Print a human-readable identifier (e.g.
Definition: BrokersHigh.h:419
ace_time::zoneinfohigh::ZoneInfoStore
A storage object that creates an ZoneInfoBroker from a key that identifies the ZoneInfo.
Definition: BrokersHigh.h:474
ace_time::zoneinfohigh::ZoneInfoStore::createZoneInfoBroker
ZoneInfoBroker< ZC, ZI, ZE, ZP, ZR > createZoneInfoBroker(uintptr_t zoneKey) const
Definition: BrokersHigh.h:481
ace_time::zoneinfohigh::ZonePolicyBroker
Data broker for accessing ZonePolicy.
Definition: BrokersHigh.h:228
ace_time::zoneinfohigh::ZoneRegistryBroker
Data broker for accessing the ZoneRegistry.
Definition: BrokersHigh.h:441
ace_time::zoneinfohigh::ZoneRuleBroker
Data broker for accessing ZoneRule.
Definition: BrokersHigh.h:159
compat.h
Macros and definitions that provide a consistency layer among the various Arduino boards for compatib...