int charsParsed = 0;
// Do not exceed maximum number of elements
if (elementCount == INSTRUCTION_MAX_ELEMENTS && state != State.COMPLETE) {
state = State.ERROR;
throw new GuacamoleServerException("Instruction contains too many elements.");
}
// Parse element length
if (state == State.PARSING_LENGTH) {
int parsedLength = elementLength;
while (charsParsed < length) {
// Pull next character
char c = chunk[offset + charsParsed++];
// If digit, add to length
if (c >= '0' && c <= '9')
parsedLength = parsedLength*10 + c - '0';
// If period, switch to parsing content
else if (c == '.') {
state = State.PARSING_CONTENT;
break;
}
// If not digit, parse error
else {
state = State.ERROR;
throw new GuacamoleServerException("Non-numeric character in element length.");
}
}
// If too long, parse error
if (parsedLength > INSTRUCTION_MAX_LENGTH) {
state = State.ERROR;
throw new GuacamoleServerException("Instruction exceeds maximum length.");
}
// Save length
elementLength = parsedLength;
} // end parse length
// Parse element content, if available
if (state == State.PARSING_CONTENT && charsParsed + elementLength + 1 <= length) {
// Read element
String element = new String(chunk, offset + charsParsed, elementLength);
charsParsed += elementLength;
elementLength = 0;
// Read terminator char following element
char terminator = chunk[offset + charsParsed++];
// Add element to currently parsed elements
elements[elementCount++] = element;
// If semicolon, store end-of-instruction
if (terminator == ';') {
state = State.COMPLETE;
parsedInstruction = new GuacamoleInstruction(elements[0],
Arrays.asList(elements).subList(1, elementCount));
}
// If comma, move on to next element
else if (terminator == ',')
state = State.PARSING_LENGTH;
// Otherwise, parse error
else {
state = State.ERROR;
throw new GuacamoleServerException("Element terminator of instruction was not ';' nor ','");
}
} // end parse content
return charsParsed;