|
| 1 | +/* |
| 2 | +Copyright (c) 2023 Bert Melis. All rights reserved. |
| 3 | +
|
| 4 | +This work is licensed under the terms of the MIT license. |
| 5 | +For a copy, see <https://opensource.org/licenses/MIT> or |
| 6 | +the LICENSE file. |
| 7 | +*/ |
| 8 | + |
| 9 | +#include "ConversionHelpers.h" |
| 10 | + |
| 11 | +bool isDigit(const char c) { |
| 12 | + return c >= '0' && c <= '9'; |
| 13 | +} |
| 14 | + |
| 15 | +namespace VitoWiFi { |
| 16 | + |
| 17 | +std::size_t encodeSchedule(const char* schedule, std::size_t len, uint8_t* output) { |
| 18 | + enum ScheduleParserStep { |
| 19 | + Hours1, |
| 20 | + Hours2, |
| 21 | + Minutes1, |
| 22 | + Minutes2, |
| 23 | + Space, |
| 24 | + }; |
| 25 | + |
| 26 | + std::size_t i = 0 - 1; // first operation in iteration is ++i |
| 27 | + std::size_t scheduleIndex = 0; |
| 28 | + ScheduleParserStep step = ScheduleParserStep::Hours1; |
| 29 | + unsigned int hour = 0; |
| 30 | + unsigned int minutes = 0; |
| 31 | + |
| 32 | + while (++i < len) { |
| 33 | + if (step == ScheduleParserStep::Hours1) { |
| 34 | + if (isDigit(schedule[i])) { |
| 35 | + hour = schedule[i] - '0'; |
| 36 | + step = ScheduleParserStep::Hours2; |
| 37 | + continue; |
| 38 | + } |
| 39 | + } else if (step == ScheduleParserStep::Hours2) { |
| 40 | + if (isDigit(schedule[i])) { |
| 41 | + hour = hour * 10 + (schedule[i] - '0'); |
| 42 | + continue; |
| 43 | + } else if (schedule[i] == ':') { |
| 44 | + step = ScheduleParserStep::Minutes1; |
| 45 | + continue; |
| 46 | + } |
| 47 | + } else if (step == ScheduleParserStep::Minutes1) { |
| 48 | + if (isDigit(schedule[i])) { |
| 49 | + minutes = schedule[i] - '0'; |
| 50 | + step = ScheduleParserStep::Minutes2; |
| 51 | + continue; |
| 52 | + } |
| 53 | + } else if (step == ScheduleParserStep::Minutes2) { |
| 54 | + if (schedule[i] == '0') { |
| 55 | + minutes = minutes * 10 + (schedule[i] - '0'); |
| 56 | + // parsing is possibly complete |
| 57 | + if (hour <= 23 || minutes <= 59) { |
| 58 | + output[scheduleIndex] = (0xF8 & hour << 3) | minutes / 10; |
| 59 | + ++scheduleIndex; |
| 60 | + step = ScheduleParserStep::Space; |
| 61 | + continue; |
| 62 | + } |
| 63 | + } |
| 64 | + } else { // step == ScheduleParserStep::Space |
| 65 | + if (schedule[i] == ' ') { |
| 66 | + step = ScheduleParserStep::Hours1; |
| 67 | + continue; |
| 68 | + } |
| 69 | + } |
| 70 | + return 0; |
| 71 | + } |
| 72 | + if (scheduleIndex % 2 == 0 && step == ScheduleParserStep::Space) { |
| 73 | + // TODO(bertmelis): hours have to be ordered |
| 74 | + return (scheduleIndex + 1) / 2; |
| 75 | + } |
| 76 | + return 0; |
| 77 | +} |
| 78 | + |
| 79 | +std::size_t encodeSchedule(const char* schedule, uint8_t* output) { |
| 80 | + return encodeSchedule(schedule, strlen(schedule), output); |
| 81 | +} |
| 82 | + |
| 83 | +std::size_t decodeSchedule(const uint8_t* data, std::size_t len, char* output, std::size_t maxLen) { |
| 84 | + assert(len == 8); |
| 85 | + assert(maxLen >= 48); // 8 times 07:30, 7 spaces and 0-terminator --> 8 * 5 + 7 * 1 + 1 |
| 86 | + |
| 87 | + std::size_t pos = 0; |
| 88 | + for (std::size_t i = 0; i < 8; ++i) { |
| 89 | + unsigned int hour = std::min(23, data[i] >> 3); |
| 90 | + unsigned int minutes = std::min(59, (data[i] & 0x07) * 10); |
| 91 | + int res = snprintf("%u.02:%u.02"); |
| 92 | + if (i < 7) |
| 93 | + } |
| 94 | + |
| 95 | +} |
| 96 | + |
| 97 | +} // end namespace VitoWiFi |
0 commit comments