Implemented support for new instruction format (inbound), simplified instruction parsing.
This commit is contained in:
parent
197029c3d8
commit
076b749225
@ -86,6 +86,11 @@ typedef struct GUACIO {
|
|||||||
*/
|
*/
|
||||||
char out_buf[8192];
|
char out_buf[8192];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current location of parsing within the instruction buffer.
|
||||||
|
*/
|
||||||
|
int instructionbuf_parse_start;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current size of the instruction buffer.
|
* The current size of the instruction buffer.
|
||||||
*/
|
*/
|
||||||
@ -103,6 +108,17 @@ typedef struct GUACIO {
|
|||||||
*/
|
*/
|
||||||
char* instructionbuf;
|
char* instructionbuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of elements parsed so far.
|
||||||
|
*/
|
||||||
|
int instructionbuf_elementc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of pointers into the instruction buffer, where each pointer
|
||||||
|
* points to the start of the corresponding element.
|
||||||
|
*/
|
||||||
|
char* instructionbuf_elementv[64];
|
||||||
|
|
||||||
} GUACIO;
|
} GUACIO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +73,8 @@ GUACIO* guac_open(int fd) {
|
|||||||
io->instructionbuf_size = 1024;
|
io->instructionbuf_size = 1024;
|
||||||
io->instructionbuf = malloc(io->instructionbuf_size);
|
io->instructionbuf = malloc(io->instructionbuf_size);
|
||||||
io->instructionbuf_used_length = 0;
|
io->instructionbuf_used_length = 0;
|
||||||
|
io->instructionbuf_parse_start = 0;
|
||||||
|
io->instructionbuf_elementc = 0;
|
||||||
|
|
||||||
return io;
|
return io;
|
||||||
|
|
||||||
|
@ -359,62 +359,83 @@ int __guac_fill_instructionbuf(GUACIO* io) {
|
|||||||
int guac_read_instruction(GUACIO* io, guac_instruction* parsed_instruction) {
|
int guac_read_instruction(GUACIO* io, guac_instruction* parsed_instruction) {
|
||||||
|
|
||||||
int retval;
|
int retval;
|
||||||
int i = 0;
|
int i = io->instructionbuf_parse_start;
|
||||||
int argcount = 0;
|
|
||||||
int j;
|
|
||||||
int current_arg = 0;
|
|
||||||
|
|
||||||
/* Loop until a instruction is read */
|
/* Loop until a instruction is read */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
/* Search for end of instruction */
|
/* Length of element */
|
||||||
for (; i < io->instructionbuf_used_length; i++) {
|
int element_length = 0;
|
||||||
|
|
||||||
/* Count arguments as we look for the end */
|
/* Parse instruction in buffe */
|
||||||
if (io->instructionbuf[i] == ',')
|
while (i < io->instructionbuf_used_length) {
|
||||||
argcount++;
|
|
||||||
else if (io->instructionbuf[i] == ':' && argcount == 0)
|
|
||||||
argcount++;
|
|
||||||
|
|
||||||
/* End found ... */
|
/* Read character from buffer */
|
||||||
else if (io->instructionbuf[i] == ';') {
|
char c = io->instructionbuf[i++];
|
||||||
|
|
||||||
/* Parse new instruction */
|
/* If digit, calculate element length */
|
||||||
char* instruction = malloc(i+1);
|
if (c >= '0' && c <= '9')
|
||||||
memcpy(instruction, io->instructionbuf, i+1);
|
element_length = element_length * 10 + c - '0';
|
||||||
instruction[i] = '\0'; /* Replace semicolon with null terminator. */
|
|
||||||
|
|
||||||
parsed_instruction->opcode = NULL;
|
/* Otherwise, if end of length */
|
||||||
|
else if (c == '.') {
|
||||||
|
|
||||||
parsed_instruction->argc = argcount;
|
/* Verify element is fully read */
|
||||||
parsed_instruction->argv = malloc(sizeof(char*) * argcount);
|
if (i + element_length < io->instructionbuf_used_length) {
|
||||||
|
|
||||||
for (j=0; j<i; j++) {
|
/* Get element value */
|
||||||
|
char* elementv = &(io->instructionbuf[i]);
|
||||||
|
|
||||||
|
/* Get terminator, set null terminator of elementv */
|
||||||
|
char terminator = elementv[element_length];
|
||||||
|
elementv[element_length] = '\0';
|
||||||
|
|
||||||
/* If encountered a colon, and no opcode parsed yet, set opcode and following argument */
|
/* Move to terminator of element */
|
||||||
if (instruction[j] == ':' && parsed_instruction->opcode == NULL) {
|
i += element_length;
|
||||||
instruction[j] = '\0';
|
|
||||||
parsed_instruction->argv[current_arg++] = &(instruction[j+1]);
|
|
||||||
parsed_instruction->opcode = instruction;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If encountered a comma, set following argument */
|
/* Reset element length */
|
||||||
else if (instruction[j] == ',') {
|
element_length = 0;
|
||||||
instruction[j] = '\0';
|
|
||||||
parsed_instruction->argv[current_arg++] = &(instruction[j+1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no arguments, set opcode to entire instruction */
|
/* As element has been read successfully, update
|
||||||
if (parsed_instruction->opcode == NULL)
|
* parse start */
|
||||||
parsed_instruction->opcode = instruction;
|
io->instructionbuf_parse_start = i;
|
||||||
|
|
||||||
/* Found. Reset buffer */
|
/* Save element */
|
||||||
memmove(io->instructionbuf, io->instructionbuf + i + 1, io->instructionbuf_used_length - i - 1);
|
io->instructionbuf_elementv[io->instructionbuf_elementc++] = elementv;
|
||||||
io->instructionbuf_used_length -= i + 1;
|
|
||||||
|
/* Finish parse if terminator is a semicolon */
|
||||||
|
if (terminator == ';') {
|
||||||
|
|
||||||
|
int j;
|
||||||
|
|
||||||
|
/* Init parsed instruction */
|
||||||
|
parsed_instruction->argc = io->instructionbuf_elementc - 1;
|
||||||
|
parsed_instruction->argv = malloc(sizeof(char*) * parsed_instruction->argc);
|
||||||
|
|
||||||
|
/* Set opcode */
|
||||||
|
parsed_instruction->opcode = strdup(io->instructionbuf_elementv[0]);
|
||||||
|
|
||||||
|
/* Copy element values to parsed instruction */
|
||||||
|
for (j=0; j<parsed_instruction->argc; j++)
|
||||||
|
parsed_instruction->argv[j] = strdup(io->instructionbuf_elementv[j+1]);
|
||||||
|
|
||||||
|
/* Reset buffer */
|
||||||
|
memmove(io->instructionbuf, io->instructionbuf + i + 1, io->instructionbuf_used_length - i - 1);
|
||||||
|
io->instructionbuf_used_length -= i + 1;
|
||||||
|
io->instructionbuf_parse_start = 0;
|
||||||
|
io->instructionbuf_elementc = 0;
|
||||||
|
|
||||||
|
/* Done */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
} /* end if terminator */
|
||||||
|
|
||||||
|
} /* end if element fully read */
|
||||||
|
|
||||||
|
/* Otherwise, read more data */
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
/* Done */
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user