// This file is generated by apc_parsers.py do not edit! #pragma once #include "base64.h" static inline void parse_multicell_code(PS *self, uint8_t *parser_buf, const size_t parser_buf_pos) { unsigned int pos = 0; size_t payload_start = 0; enum PARSER_STATES { KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE, PAYLOAD }; enum PARSER_STATES state = KEY, value_state = FLAG; MultiCellCommand g = {0}; unsigned int i, code; uint64_t lcode; int64_t accumulator; bool is_negative; (void)is_negative; size_t sz; enum KEYS { width = 'w', scale = 's', subscale_n = 'n', subscale_d = 'd', vertical_align = 'v', horizontal_align = 'h' }; enum KEYS key = 'a'; if (parser_buf[pos] == ';') state = AFTER_VALUE; while (pos < parser_buf_pos) { switch (state) { case KEY: key = parser_buf[pos++]; state = EQUAL; switch (key) { case width: value_state = UINT; break; case scale: value_state = UINT; break; case subscale_n: value_state = UINT; break; case subscale_d: value_state = UINT; break; case vertical_align: value_state = UINT; break; case horizontal_align: value_state = UINT; break; default: REPORT_ERROR("Malformed MultiCellCommand control block, invalid key " "character: 0x%x", key); return; } break; case EQUAL: if (parser_buf[pos++] != '=') { REPORT_ERROR("Malformed MultiCellCommand control block, no = after " "key, found: 0x%x instead", parser_buf[pos - 1]); return; } state = value_state; break; case FLAG: switch (key) { default: break; } state = AFTER_VALUE; break; case INT: #define READ_UINT \ for (i = pos, accumulator = 0; i < MIN(parser_buf_pos, pos + 10); i++) { \ int64_t n = parser_buf[i] - '0'; \ if (n < 0 || n > 9) \ break; \ accumulator += n * digit_multipliers[i - pos]; \ } \ if (i == pos) { \ REPORT_ERROR("Malformed MultiCellCommand control block, expecting an " \ "integer value for key: %c", \ key & 0xFF); \ return; \ } \ lcode = accumulator / digit_multipliers[i - pos - 1]; \ pos = i; \ if (lcode > UINT32_MAX) { \ REPORT_ERROR( \ "Malformed MultiCellCommand control block, number is too large"); \ return; \ } \ code = lcode; is_negative = false; if (parser_buf[pos] == '-') { is_negative = true; pos++; } #define I(x) \ case x: \ g.x = is_negative ? 0 - (int32_t)code : (int32_t)code; \ break READ_UINT; switch (key) { ; default: break; } state = AFTER_VALUE; break; #undef I case UINT: READ_UINT; #define U(x) \ case x: \ g.x = code; \ break switch (key) { U(width); U(scale); U(subscale_n); U(subscale_d); U(vertical_align); U(horizontal_align); default: break; } state = AFTER_VALUE; break; #undef U #undef READ_UINT case AFTER_VALUE: switch (parser_buf[pos++]) { default: REPORT_ERROR("Malformed MultiCellCommand control block, expecting a : " "or semi-colon after a value, found: 0x%x", parser_buf[pos - 1]); return; case ':': state = KEY; break; case ';': state = PAYLOAD; break; } break; case PAYLOAD: { sz = parser_buf_pos - pos; payload_start = pos; g.payload_sz = sz; pos = parser_buf_pos; } break; } // end switch } // end while switch (state) { case EQUAL: REPORT_ERROR("Malformed MultiCellCommand control block, no = after key"); return; case INT: case UINT: REPORT_ERROR( "Malformed MultiCellCommand control block, expecting an integer value"); return; case FLAG: REPORT_ERROR( "Malformed MultiCellCommand control block, expecting a flag value"); return; default: break; } REPORT_VA_COMMAND( "K s { sI sI sI sI sI sI ss#}", self->window_id, "multicell_command", "width", (unsigned int)g.width, "scale", (unsigned int)g.scale, "subscale_n", (unsigned int)g.subscale_n, "subscale_d", (unsigned int)g.subscale_d, "vertical_align", (unsigned int)g.vertical_align, "horizontal_align", (unsigned int)g.horizontal_align, "", (char *)parser_buf + payload_start, g.payload_sz); screen_handle_multicell_command(self->screen, &g, parser_buf + payload_start); }