in src/main/java/org/apache/commons/csv/Lexer.java [326:383]
private Token parseEncapsulatedToken(final Token token) throws IOException {
token.isQuoted = true;
// save current line number in case needed for IOE
final long startLineNumber = getCurrentLineNumber();
int c;
while (true) {
c = reader.read();
if (isEscape(c)) {
if (isEscapeDelimiter()) {
token.content.append(delimiter);
} else {
final int unescaped = readEscape();
if (unescaped == END_OF_STREAM) { // unexpected char after escape
token.content.append((char) c).append((char) reader.getLastChar());
} else {
token.content.append((char) unescaped);
}
}
} else if (isQuoteChar(c)) {
if (isQuoteChar(reader.lookAhead())) {
// double or escaped encapsulator -> add single encapsulator to token
c = reader.read();
token.content.append((char) c);
} else {
// token finish mark (encapsulator) reached: ignore whitespace till delimiter
while (true) {
c = reader.read();
if (isDelimiter(c)) {
token.type = TOKEN;
return token;
}
if (isEndOfFile(c)) {
token.type = EOF;
token.isReady = true; // There is data at EOF
return token;
}
if (readEndOfLine(c)) {
token.type = EORECORD;
return token;
}
if (!Character.isWhitespace((char)c)) {
// error invalid char between token and next delimiter
throw new IOException("(line " + getCurrentLineNumber() +
") invalid char between encapsulated token and delimiter");
}
}
}
} else if (isEndOfFile(c)) {
// error condition (end of file before end of token)
throw new IOException("(startline " + startLineNumber +
") EOF reached before encapsulated token finished");
} else {
// consume character
token.content.append((char) c);
}
}
}