| 142 | } |
| 143 | |
| 144 | utils::optional<Identifier> Identifier::parse(const std::string &str) { |
| 145 | Identifier id; |
| 146 | // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx is 36 long: 16 bytes * 2 hex digits / byte + 4 hyphens |
| 147 | if (str.length() != 36) return {}; |
| 148 | int charIdx = 0; |
| 149 | int byteIdx = 0; |
| 150 | auto input = reinterpret_cast<const uint8_t*>(str.c_str()); |
| 151 | |
| 152 | // [xxxxxxxx]-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
| 153 | while (byteIdx < 4) { |
| 154 | if (!parseByte(id.data_, input, charIdx, byteIdx)) return {}; |
| 155 | } |
| 156 | // xxxxxxxx[-]xxxx-xxxx-xxxx-xxxxxxxxxxxx |
| 157 | if (input[charIdx++] != '-') return {}; |
| 158 | |
| 159 | // xxxxxxxx-[xxxx-xxxx-xxxx-]xxxxxxxxxxxx - 3x 2 bytes and a hyphen |
| 160 | for (size_t idx = 0; idx < 3; ++idx) { |
| 161 | if (!parseByte(id.data_, input, charIdx, byteIdx)) return {}; |
| 162 | if (!parseByte(id.data_, input, charIdx, byteIdx)) return {}; |
| 163 | if (input[charIdx++] != '-') return {}; |
| 164 | } |
| 165 | |
| 166 | // xxxxxxxx-xxxx-xxxx-xxxx-[xxxxxxxxxxxx] - the rest, i.e. until byte 16 |
| 167 | while (byteIdx < 16) { |
| 168 | if (!parseByte(id.data_, input, charIdx, byteIdx)) return {}; |
| 169 | } |
| 170 | return id; |
| 171 | } |
| 172 | |
| 173 | bool Identifier::parseByte(Data &data, const uint8_t *input, int &charIdx, int &byteIdx) { |
| 174 | uint8_t upper, lower; |
no test coverage detected