From 81768daba97394e319cd0db9ea224d93e7ecb1e3 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 1 Oct 2013 18:06:19 -0700 Subject: [PATCH] Stub out independent instruction parser. --- src/libguac/guacamole/instruction.h | 79 +++++++++++++++++++++++++++++ src/libguac/instruction.c | 36 +++++++++++++ 2 files changed, 115 insertions(+) diff --git a/src/libguac/guacamole/instruction.h b/src/libguac/guacamole/instruction.h index 6eb2fd93..08f6ec82 100644 --- a/src/libguac/guacamole/instruction.h +++ b/src/libguac/guacamole/instruction.h @@ -47,6 +47,50 @@ * @file instruction.h */ +/** + * The maximum number of bytes per instruction. + */ +#define GUAC_INSTRUCTION_MAX_LENGTH 32768 + +/** + * The maximum number of digits to allow per length prefix. + */ +#define GUAC_INSTRUCTION_MAX_DIGITS 5 + +/** + * The maximum number of elements per instruction, including the opcode. + */ +#define GUAC_INSTRUCTION_MAX_ELEMENTS 64 + +/** + * All possible states of the instruction parser. + */ +typedef enum guac_instruction_parse_state { + + /** + * The parser is currently waiting for data to complete the length prefix + * of the current element of the instruction. + */ + GUAC_INSTRUCTION_PARSE_LENGTH, + + /** + * The parser has finished reading the length prefix and is currently + * waiting for data to complete the content of the instruction. + */ + GUAC_INSTRUCTION_PARSE_CONTENT, + + /** + * The instruction has been fully parsed. + */ + GUAC_INSTRUCTION_PARSE_COMPLETE, + + /** + * The instruction cannot be parsed because of a protocol error. + */ + GUAC_INSTRUCTION_PARSE_ERROR + +} guac_instruction_parse_state; + /** * Represents a single instruction within the Guacamole protocol. */ @@ -67,8 +111,43 @@ typedef struct guac_instruction { */ char** argv; + /** + * The parse state of the instruction. + */ + guac_instruction_parse_state state; + + /** + * The remaining length of the current element, if known. + */ + int __element_remaining_length; + } guac_instruction; +/** + * Allocates a new instruction. Each instruction contains within itself the + * necessary facilities to parse instruction data. + * + * @return The newly allocated instruction, or NULL if an error occurs during + * allocation, in which case guac_error will be set appropriately. + */ +guac_instruction* guac_instruction_alloc(); + +/** + * 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 + * buffer must remain valid throughout the life of the instruction. This + * function may modify the contents of the buffer when those contents are + * part of an element within the instruction being read. + * + * @param instruction The instruction to append data to. + * @param buffer A buffer containing data that should be appended to this + * instruction. + * @param length The number of bytes available for appending within the buffer. + * @return The number of bytes appended to this instruction, which may be + * zero if more data is needed. + */ +int guac_instruction_append(guac_instruction* instruction, + void* buffer, int length); /** * Frees all memory allocated to the given instruction. diff --git a/src/libguac/instruction.c b/src/libguac/instruction.c index 78724d64..0b134a21 100644 --- a/src/libguac/instruction.c +++ b/src/libguac/instruction.c @@ -45,6 +45,42 @@ #include "socket.h" #include "unicode.h" +guac_instruction* guac_instruction_alloc() { + + /* Allocate space for instruction */ + guac_instruction* instruction = malloc(sizeof(guac_instruction)); + if (instruction == NULL) { + guac_error = GUAC_STATUS_NO_MEMORY; + guac_error_message = "Insufficient memory to allocate instruction"; + return NULL; + } + + /* Initialize state */ + instruction->state = GUAC_INSTRUCTION_PARSE_LENGTH; + + return instruction; + +} + +int guac_instruction_append(guac_instruction* instruction, + void* buffer, int length) { + + int bytes_parsed = 0; + + /* Parse element length */ + if (instruction->state == GUAC_INSTRUCTION_PARSE_LENGTH) { + /* STUB */ + } + + /* Parse element content */ + if (instruction->state == GUAC_INSTRUCTION_PARSE_CONTENT) { + /* STUB */ + } + + return bytes_parsed; + +} + int __guac_fill_instructionbuf(guac_socket* socket) { int retval;