in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParserSession.java [727:805]
private String parseString(ParserReader r) throws IOException, ParseException {
r.mark();
int qc = r.read(); // The quote character being used (" or ')
if (qc != '"' && isStrict()) {
String msg = (
qc == '\''
? "Invalid quote character \"{0}\" being used."
: "Did not find quote character marking beginning of string. Character=\"{0}\""
);
throw new ParseException(this, msg, (char)qc);
}
final boolean isQuoted = (qc == '\'' || qc == '"');
String s = null;
boolean isInEscape = false;
int c = 0;
while (c != -1) {
c = r.read();
// Strict syntax requires that all control characters be escaped.
if (isStrict() && c <= 0x1F)
throw new ParseException(this, "Unescaped control character encountered: ''0x{0}''", String.format("%04X", c));
if (isInEscape) {
switch (c) {
case 'n': r.replace('\n'); break;
case 'r': r.replace('\r'); break;
case 't': r.replace('\t'); break;
case 'f': r.replace('\f'); break;
case 'b': r.replace('\b'); break;
case '\\': r.replace('\\'); break;
case '/': r.replace('/'); break;
case '\'': r.replace('\''); break;
case '"': r.replace('"'); break;
case 'u': {
String n = r.read(4);
try {
r.replace(Integer.parseInt(n, 16), 6);
} catch (NumberFormatException e) {
throw new ParseException(this, "Invalid Unicode escape sequence in string.");
}
break;
}
default:
throw new ParseException(this, "Invalid escape sequence in string.");
}
isInEscape = false;
} else {
if (c == '\\') {
isInEscape = true;
r.delete();
} else if (isQuoted) {
if (c == qc) {
s = r.getMarked(1, -1);
break;
}
} else {
if (c == ',' || c == '}' || c == ']' || isWhitespace(c)) {
s = r.getMarked(0, -1);
r.unread();
break;
} else if (c == -1) {
s = r.getMarked(0, 0);
break;
}
}
}
}
if (s == null)
throw new ParseException(this, "Could not find expected end character ''{0}''.", (char)qc);
// Look for concatenated string (i.e. whitespace followed by +).
skipCommentsAndSpace(r);
if (r.peek() == '+') {
if (isStrict())
throw new ParseException(this, "String concatenation detected.");
r.read(); // Skip past '+'
skipCommentsAndSpace(r);
s += parseString(r);
}
return trim(s); // End of input reached.
}