* (since it operates on single lines of input).
* </ul>
*/
public String[] parse(CharSequence line) {
List<String> tokens = new ArrayList<>();
CharacterIterator ci = new CharSequenceCharacterIterator(line);
StringBuilder tok = new StringBuilder();
State state = State.BEGIN;
loop: for (char c = ci.first();; c = ci.next()) {
switch (c) {
case '"':
switch (state) {
case BEGIN:
// start of a quoted string
state = State.QUOTEDSTRING;
break;
case QUOTEDSTRING:
// either end of the quoted string or start of a quoted
// quote
char c2 = ci.next();
if (c2 == '"') {
// double double-quotes – a quoted double-quote
tok.append('"');
} else if (c2 == CharacterIterator.DONE || c2 == delimiter) {
// terminating quote for the quoted string
tokens.add(tok.toString());
tok = new StringBuilder();
state = State.BEGIN;
// avoid running the main loop body over the DONE (which would add
// the now empty token to the list of tokens although no token
// started)
if (c2 == CharacterIterator.DONE) {
break loop;
}
} else {
throw new CSVFormatException(
"Data encountered outside a quoted string.", ci.getIndex());
}
break;
case STRING:
// stray double-quote in the middle of an unquoted string
throw new CSVFormatException(
"Stray double-quote within unquoted field", ci.getIndex());
default:
}
break;
case CharacterIterator.DONE:
if (state == State.QUOTEDSTRING) {
// end of string in the middle of a quoted string – not
// good
throw new CSVFormatException(
"Encountered end of line in a quoted string.", ci.getIndex());
}
tokens.add(tok.toString());
break loop;
default:
if (c == getDelimiter()) {