Shift buffer to gain space if necessary.

This commit is contained in:
Michael Jumper 2013-10-03 16:48:01 -07:00
parent e66a64be26
commit e7c81cd9b3
2 changed files with 32 additions and 7 deletions

View File

@ -142,6 +142,14 @@ typedef struct guac_instruction {
*/ */
guac_instruction* guac_instruction_alloc(); guac_instruction* guac_instruction_alloc();
/**
* Resets the parse state and contents of the given instruction, such that the
* memory of that instruction can be reused for another parse cycle.
*
* @param instruction The instruction to reset.
*/
void guac_instruction_reset(guac_instruction* instruction);
/** /**
* Appends data from the given buffer to the given instruction. The data will * Appends data from the given buffer to the given instruction. The data will
* be appended, if possible, to this instruction as a reference and thus the * be appended, if possible, to this instruction as a reference and thus the

View File

@ -55,14 +55,16 @@ guac_instruction* guac_instruction_alloc() {
return NULL; return NULL;
} }
/* Initialize state */ guac_instruction_reset(instruction);
return instruction;
}
void guac_instruction_reset(guac_instruction* instruction) {
instruction->opcode = NULL; instruction->opcode = NULL;
instruction->argc = 0; instruction->argc = 0;
instruction->state = GUAC_INSTRUCTION_PARSE_LENGTH; instruction->state = GUAC_INSTRUCTION_PARSE_LENGTH;
instruction->__elementc = 0; instruction->__elementc = 0;
return instruction;
} }
int guac_instruction_append(guac_instruction* instr, int guac_instruction_append(guac_instruction* instr,
@ -178,6 +180,7 @@ guac_instruction* guac_instruction_read(guac_socket* socket,
char* unparsed_end = socket->__instructionbuf_unparsed_end; char* unparsed_end = socket->__instructionbuf_unparsed_end;
char* unparsed_start = socket->__instructionbuf_unparsed_start; char* unparsed_start = socket->__instructionbuf_unparsed_start;
char* instr_start = socket->__instructionbuf_unparsed_start;
char* buffer_end = socket->__instructionbuf char* buffer_end = socket->__instructionbuf
+ sizeof(socket->__instructionbuf); + sizeof(socket->__instructionbuf);
@ -197,11 +200,25 @@ guac_instruction* guac_instruction_read(guac_socket* socket,
/* If no space left to read, fail */ /* If no space left to read, fail */
if (unparsed_end == buffer_end) { if (unparsed_end == buffer_end) {
/* Shift backward if possible */
if (instr_start != socket->__instructionbuf) {
memmove(socket->__instructionbuf, instr_start,
unparsed_end - instr_start);
unparsed_end -= instr_start - socket->__instructionbuf;
unparsed_start = instr_start = socket->__instructionbuf;
guac_instruction_reset(instruction);
}
/* Otherwise, no memory to read */
else {
guac_error = GUAC_STATUS_NO_MEMORY; guac_error = GUAC_STATUS_NO_MEMORY;
guac_error_message = "Instruction too long"; guac_error_message = "Instruction too long";
return NULL; return NULL;
} }
}
/* No instruction yet? Get more data ... */ /* No instruction yet? Get more data ... */
retval = guac_socket_select(socket, usec_timeout); retval = guac_socket_select(socket, usec_timeout);
if (retval <= 0) if (retval <= 0)