in src/libguac/parser.c [59:165]
int guac_parser_append(guac_parser* parser, void* buffer, int length) {
char* char_buffer = (char*) buffer;
int bytes_parsed = 0;
/* Do not exceed maximum number of elements */
if (parser->__elementc == GUAC_INSTRUCTION_MAX_ELEMENTS
&& parser->state != GUAC_PARSE_COMPLETE) {
parser->state = GUAC_PARSE_ERROR;
return 0;
}
/* Parse element length */
if (parser->state == GUAC_PARSE_LENGTH) {
int parsed_length = parser->__element_length;
while (bytes_parsed < length) {
/* Pull next character */
char c = *(char_buffer++);
bytes_parsed++;
/* If digit, add to length */
if (c >= '0' && c <= '9')
parsed_length = parsed_length*10 + c - '0';
/* If period, switch to parsing content */
else if (c == '.') {
parser->__elementv[parser->__elementc++] = char_buffer;
parser->state = GUAC_PARSE_CONTENT;
break;
}
/* If not digit, parse error */
else {
parser->state = GUAC_PARSE_ERROR;
return 0;
}
}
/* If too long, parse error */
if (parsed_length > GUAC_INSTRUCTION_MAX_LENGTH) {
parser->state = GUAC_PARSE_ERROR;
return 0;
}
/* Save length */
parser->__element_length = parsed_length;
} /* end parse length */
/* Parse element content */
if (parser->state == GUAC_PARSE_CONTENT) {
while (bytes_parsed < length && parser->__element_length >= 0) {
/* Get length of current character */
char c = *char_buffer;
int char_length = guac_utf8_charsize((unsigned char) c);
/* If full character not present in buffer, stop now */
if (char_length + bytes_parsed > length)
break;
/* Record character as parsed */
bytes_parsed += char_length;
/* If end of element, handle terminator */
if (parser->__element_length == 0) {
*char_buffer = '\0';
/* If semicolon, store end-of-instruction */
if (c == ';') {
parser->state = GUAC_PARSE_COMPLETE;
parser->opcode = parser->__elementv[0];
parser->argv = &(parser->__elementv[1]);
parser->argc = parser->__elementc - 1;
break;
}
/* If comma, move on to next element */
else if (c == ',') {
parser->state = GUAC_PARSE_LENGTH;
break;
}
/* Otherwise, parse error */
else {
parser->state = GUAC_PARSE_ERROR;
return 0;
}
} /* end if end of element */
/* Advance to next character */
parser->__element_length--;
char_buffer += char_length;
}
} /* end parse content */
return bytes_parsed;
}