| 240 | } |
| 241 | |
| 242 | static uint8_t calc_tokenized_var_version(const calc_var_t *var) { |
| 243 | static const uint8_t twoByteTokens[] = {0x5C, 0x5D, 0x5E, 0x60, 0x61, 0x62, 0x63, 0x7E, 0xBB, 0xAA, 0xEF}; |
| 244 | bool usesRTC = false; |
| 245 | int maxBB = -1; |
| 246 | int maxEF = -1; |
| 247 | uint16_t offset = 2; |
| 248 | while (offset < var->size) { |
| 249 | uint8_t firstByte = var->data[offset++]; |
| 250 | if (memchr(twoByteTokens, firstByte, sizeof(twoByteTokens)) != NULL) { |
| 251 | if (offset >= var->size) { |
| 252 | break; |
| 253 | } |
| 254 | uint8_t secondByte = var->data[offset++]; |
| 255 | if (firstByte == 0xBB) { |
| 256 | if (secondByte > maxBB) maxBB = secondByte; |
| 257 | } else if (firstByte == 0xEF) { |
| 258 | if (secondByte <= 0x10) usesRTC = true; |
| 259 | if (secondByte > maxEF) maxEF = secondByte; |
| 260 | } |
| 261 | } |
| 262 | } |
| 263 | uint8_t version = usesRTC ? 0x20 : 0x00; |
| 264 | if (maxBB > 0xF5 || maxEF > 0xA6) { |
| 265 | version = 0xFF; |
| 266 | } else if (maxEF > 0x98) { |
| 267 | version |= 0x0C; |
| 268 | } else if (maxEF > 0x75) { |
| 269 | version |= 0x0B; |
| 270 | } else if (maxEF > 0x40) { |
| 271 | version |= 0x0A; |
| 272 | } else if (maxEF > 0x3E) { |
| 273 | version |= 0x07; |
| 274 | } else if (maxEF > 0x16) { |
| 275 | version |= 0x06; |
| 276 | } else if (maxEF > 0x12) { |
| 277 | version |= 0x05; |
| 278 | } else if (maxEF > -1) { |
| 279 | version |= 0x04; |
| 280 | } else if (maxBB > 0xDA) { |
| 281 | version |= 0x03; |
| 282 | } else if (maxBB > 0xCE) { |
| 283 | version |= 0x02; |
| 284 | } else if (maxBB > 0x67) { |
| 285 | version |= 0x01; |
| 286 | } |
| 287 | return version; |
| 288 | } |
| 289 | |
| 290 | void vat_search_init(calc_var_t *var) { |
| 291 | memset(var, 0, sizeof *var); |