// This file is generated by apc_parsers.py do not edit! #pragma once #include "base64.h" static inline void parse_graphics_code(PS *self, uint8_t *parser_buf, const size_t parser_buf_pos) { unsigned int pos = 1; enum PARSER_STATES { KEY, EQUAL, UINT, INT, FLAG, AFTER_VALUE, PAYLOAD }; enum PARSER_STATES state = KEY, value_state = FLAG; GraphicsCommand g = {0}; unsigned int i, code; uint64_t lcode; int64_t accumulator; bool is_negative; (void)is_negative; size_t sz; enum KEYS { action = 'a', delete_action = 'd', transmission_type = 't', compressed = 'o', format = 'f', more = 'm', id = 'i', image_number = 'I', placement_id = 'p', quiet = 'q', width = 'w', height = 'h', x_offset = 'x', y_offset = 'y', data_height = 'v', data_width = 's', data_sz = 'S', data_offset = 'O', num_cells = 'c', num_lines = 'r', cell_x_offset = 'X', cell_y_offset = 'Y', z_index = 'z', cursor_movement = 'C', unicode_placement = 'U', parent_id = 'P', parent_placement_id = 'Q', offset_from_parent_x = 'H', offset_from_parent_y = 'V' }; 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 action: value_state = FLAG; break; case delete_action: value_state = FLAG; break; case transmission_type: value_state = FLAG; break; case compressed: value_state = FLAG; break; case format: value_state = UINT; break; case more: value_state = UINT; break; case id: value_state = UINT; break; case image_number: value_state = UINT; break; case placement_id: value_state = UINT; break; case quiet: value_state = UINT; break; case width: value_state = UINT; break; case height: value_state = UINT; break; case x_offset: value_state = UINT; break; case y_offset: value_state = UINT; break; case data_height: value_state = UINT; break; case data_width: value_state = UINT; break; case data_sz: value_state = UINT; break; case data_offset: value_state = UINT; break; case num_cells: value_state = UINT; break; case num_lines: value_state = UINT; break; case cell_x_offset: value_state = UINT; break; case cell_y_offset: value_state = UINT; break; case z_index: value_state = INT; break; case cursor_movement: value_state = UINT; break; case unicode_placement: value_state = UINT; break; case parent_id: value_state = UINT; break; case parent_placement_id: value_state = UINT; break; case offset_from_parent_x: value_state = INT; break; case offset_from_parent_y: value_state = INT; break; default: REPORT_ERROR("Malformed GraphicsCommand control block, invalid key " "character: 0x%x", key); return; } break; case EQUAL: if (parser_buf[pos++] != '=') { REPORT_ERROR("Malformed GraphicsCommand control block, no = after key, " "found: 0x%x instead", parser_buf[pos - 1]); return; } state = value_state; break; case FLAG: switch (key) { case action: { g.action = parser_buf[pos++]; if (g.action != 'T' && g.action != 'a' && g.action != 'c' && g.action != 'd' && g.action != 'f' && g.action != 'p' && g.action != 'q' && g.action != 't') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for action: 0x%x", g.action); return; }; } break; case delete_action: { g.delete_action = parser_buf[pos++]; if (g.delete_action != 'A' && g.delete_action != 'C' && g.delete_action != 'F' && g.delete_action != 'I' && g.delete_action != 'N' && g.delete_action != 'P' && g.delete_action != 'Q' && g.delete_action != 'R' && g.delete_action != 'X' && g.delete_action != 'Y' && g.delete_action != 'Z' && g.delete_action != 'a' && g.delete_action != 'c' && g.delete_action != 'f' && g.delete_action != 'i' && g.delete_action != 'n' && g.delete_action != 'p' && g.delete_action != 'q' && g.delete_action != 'r' && g.delete_action != 'x' && g.delete_action != 'y' && g.delete_action != 'z') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for delete_action: 0x%x", g.delete_action); return; }; } break; case transmission_type: { g.transmission_type = parser_buf[pos++]; if (g.transmission_type != 'd' && g.transmission_type != 'f' && g.transmission_type != 's' && g.transmission_type != 't') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for transmission_type: 0x%x", g.transmission_type); return; }; } break; case compressed: { g.compressed = parser_buf[pos++]; if (g.compressed != 'z') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for compressed: 0x%x", g.compressed); return; }; } break; 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 GraphicsCommand 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 GraphicsCommand 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) { I(z_index); I(offset_from_parent_x); I(offset_from_parent_y); default: break; } state = AFTER_VALUE; break; #undef I case UINT: READ_UINT; #define U(x) \ case x: \ g.x = code; \ break switch (key) { U(format); U(more); U(id); U(image_number); U(placement_id); U(quiet); U(width); U(height); U(x_offset); U(y_offset); U(data_height); U(data_width); U(data_sz); U(data_offset); U(num_cells); U(num_lines); U(cell_x_offset); U(cell_y_offset); U(cursor_movement); U(unicode_placement); U(parent_id); U(parent_placement_id); default: break; } state = AFTER_VALUE; break; #undef U #undef READ_UINT case AFTER_VALUE: switch (parser_buf[pos++]) { default: REPORT_ERROR("Malformed GraphicsCommand 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; g.payload_sz = MAX(BUF_EXTRA, sz); if (!base64_decode8(parser_buf + pos, sz, parser_buf, &g.payload_sz)) { g.payload_sz = MAX(BUF_EXTRA, sz); REPORT_ERROR("Failed to parse GraphicsCommand command payload with " "error: invalid base64 data in chunk of size: %zu " "with output buffer size: %zu", sz, g.payload_sz); return; } pos = parser_buf_pos; } break; } // end switch } // end while switch (state) { case EQUAL: REPORT_ERROR("Malformed GraphicsCommand control block, no = after key"); return; case INT: case UINT: REPORT_ERROR( "Malformed GraphicsCommand control block, expecting an integer value"); return; case FLAG: REPORT_ERROR( "Malformed GraphicsCommand control block, expecting a flag value"); return; default: break; } REPORT_VA_COMMAND( "K s {sc sc sc sc sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI sI " "sI sI sI sI si si si ss#}", self->window_id, "graphics_command", "action", g.action, "delete_action", g.delete_action, "transmission_type", g.transmission_type, "compressed", g.compressed, "format", (unsigned int)g.format, "more", (unsigned int)g.more, "id", (unsigned int)g.id, "image_number", (unsigned int)g.image_number, "placement_id", (unsigned int)g.placement_id, "quiet", (unsigned int)g.quiet, "width", (unsigned int)g.width, "height", (unsigned int)g.height, "x_offset", (unsigned int)g.x_offset, "y_offset", (unsigned int)g.y_offset, "data_height", (unsigned int)g.data_height, "data_width", (unsigned int)g.data_width, "data_sz", (unsigned int)g.data_sz, "data_offset", (unsigned int)g.data_offset, "num_cells", (unsigned int)g.num_cells, "num_lines", (unsigned int)g.num_lines, "cell_x_offset", (unsigned int)g.cell_x_offset, "cell_y_offset", (unsigned int)g.cell_y_offset, "cursor_movement", (unsigned int)g.cursor_movement, "unicode_placement", (unsigned int)g.unicode_placement, "parent_id", (unsigned int)g.parent_id, "parent_placement_id", (unsigned int)g.parent_placement_id, "z_index", (int)g.z_index, "offset_from_parent_x", (int)g.offset_from_parent_x, "offset_from_parent_y", (int)g.offset_from_parent_y, "", (char *)parser_buf, g.payload_sz); screen_handle_graphics_command(self->screen, &g, parser_buf); }