Implement decoding of graphics command payload

This commit is contained in:
Kovid Goyal 2017-09-25 15:41:55 +05:30
parent b8d9629ee4
commit a9ed44eecc
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 49 additions and 2 deletions

View File

@ -264,3 +264,43 @@ encode_utf8(uint32_t ch, char* dest) {
}
return 0;
}
// Base64
static uint8_t b64_encoding_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
static uint8_t b64_decoding_table[256] = {0};
const char*
base64_decode(const uint32_t *src, size_t src_sz, uint8_t *dest, size_t dest_capacity, size_t *dest_sz) {
if (!b64_decoding_table['B']) { for (uint8_t i = 0; i < sizeof(b64_encoding_table)/sizeof(b64_encoding_table[0]); i++) b64_decoding_table[b64_encoding_table[i]] = i; }
if (!src_sz) { *dest_sz = 0; return NULL; }
if (src_sz % 4 != 0) return "base64 encoded data must have a length that is a multiple of four";
*dest_sz = (src_sz / 4) * 3;
if (src[src_sz - 1] == '=') (*dest_sz)--;
if (src[src_sz - 2] == '=') (*dest_sz)--;
if (*dest_sz > dest_capacity) return "output buffer too small";
for (size_t i = 0, j = 0; i < src_sz;) {
uint32_t sextet_a = src[i] == '=' ? 0 & i++ : b64_decoding_table[src[i++]];
uint32_t sextet_b = src[i] == '=' ? 0 & i++ : b64_decoding_table[src[i++]];
uint32_t sextet_c = src[i] == '=' ? 0 & i++ : b64_decoding_table[src[i++]];
uint32_t sextet_d = src[i] == '=' ? 0 & i++ : b64_decoding_table[src[i++]];
uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
if (j < *dest_sz) dest[j++] = (triple >> 2 * 8) & 0xFF;
if (j < *dest_sz) dest[j++] = (triple >> 1 * 8) & 0xFF;
if (j < *dest_sz) dest[j++] = (triple >> 0 * 8) & 0xFF;
}
return NULL;
}

View File

@ -286,6 +286,7 @@ PyTypeObject ChildMonitor_Type;
}
// Global functions
const char* base64_decode(const uint32_t *src, size_t src_sz, uint8_t *dest, size_t dest_capacity, size_t *dest_sz);
Line* alloc_line();
Cursor* alloc_cursor();
LineBuf* alloc_linebuf(unsigned int, unsigned int);

View File

@ -11,5 +11,5 @@ typedef struct {
uint32_t format, more, id;
uint32_t width, height, x_offset, y_offset, data_height, data_width, num_cells, num_lines;
int32_t z_index;
char payload[4096];
size_t payload_sz;
} GraphicsCommand;

View File

@ -557,6 +557,9 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
unsigned int i, code, ch;
bool is_negative;
memset(&g, 0, sizeof(g));
static uint8_t payload[4096];
size_t sz;
const char *err;
while (pos < screen->parser_buf_pos - 1) {
switch(state) {
@ -629,7 +632,10 @@ parse_graphics_code(Screen *screen, PyObject UNUSED *dump_callback) {
#undef SET_ATTR
#undef READ_UINT
case PAYLOAD:
break; // TODO
sz = screen->parser_buf_pos - (pos - 1);
err = base64_decode(screen->parser_buf + pos - 1, sz, payload, sizeof(payload), &g.payload_sz);
if (err != NULL) { REPORT_ERROR("Failed to parse graphics command payload with error: %s", err); return; }
break;
}
}
}