in core/src/main/java/com/jetbrains/youtrackdb/internal/core/serialization/serializer/StringSerializerHelper.java [625:872]
public static int parse(
final String iSource,
final StringBuilder iBuffer,
final int beginIndex,
final int endIndex,
final char[] iSeparator,
final boolean iStringSeparatorExtended,
final boolean iConsiderBraces,
final boolean iConsiderSets,
final int iMinPosSeparatorAreValid,
boolean considerBags,
final boolean iUnicode,
boolean iPreserveQuotes,
final int iMaxValueSizeBeforeSkip,
final char... iJumpChars) {
if (beginIndex < 0) {
return beginIndex;
}
var stringBeginChar = ' ';
var encodeMode = false;
var insideParenthesis = 0;
var insideList = 0;
var insideSet = 0;
var insideMap = 0;
var insideLinkPart = 0;
var insideBag = 0;
var tooBigValue = false;
final var max = endIndex > -1 ? endIndex + 1 : iSource.length();
// iBuffer.ensureCapacity(max);
// JUMP FIRST CHARS
var i = beginIndex;
for (; i < max; ++i) {
final var c = iSource.charAt(i);
if (!isCharPresent(c, iJumpChars)) {
break;
}
}
for (; i < max; ++i) {
final var c = iSource.charAt(i);
if (stringBeginChar == ' ') {
// OUTSIDE A STRING
if (iConsiderBraces) {
if (c == LIST_BEGIN) {
if (i < iMinPosSeparatorAreValid
|| insideParenthesis > 0
|| insideList > 0
|| !isCharPresent(c, iSeparator)) {
insideList++;
}
} else if (c == LIST_END) {
if (i < iMinPosSeparatorAreValid
|| insideParenthesis > 0
|| insideList > 0
|| !isCharPresent(c, iSeparator)) {
if (insideList == 0) {
throw new SerializationException(
"Found invalid "
+ LIST_END
+ " character at position "
+ i
+ " of text "
+ iSource
+ ". Ensure it is opened and closed correctly.");
}
insideList--;
}
} else if (c == EMBEDDED_BEGIN) {
insideParenthesis++;
} else if (c == EMBEDDED_END) {
// if (!isCharPresent(c, iRecordSeparator)) {
if (insideParenthesis == 0) {
throw new SerializationException(
"Found invalid "
+ EMBEDDED_END
+ " character at position "
+ i
+ " of text "
+ iSource
+ ". Ensure it is opened and closed correctly.");
}
// }
insideParenthesis--;
} else if (c == MAP_BEGIN) {
insideMap++;
} else if (c == MAP_END) {
if (i < iMinPosSeparatorAreValid || !isCharPresent(c, iSeparator)) {
if (insideMap == 0) {
throw new SerializationException(
"Found invalid "
+ MAP_END
+ " character at position "
+ i
+ " of text "
+ iSource
+ ". Ensure it is opened and closed correctly.");
}
insideMap--;
}
} else if (c == LINK)
// FIRST PART OF LINK
{
insideLinkPart = 1;
} else if (insideLinkPart == 1 && c == RID.SEPARATOR)
// SECOND PART OF LINK
{
insideLinkPart = 2;
} else {
if (iConsiderSets) {
if (c == SET_BEGIN) {
insideSet++;
} else if (c == SET_END) {
if (i < iMinPosSeparatorAreValid || !isCharPresent(c, iSeparator)) {
if (insideSet == 0) {
throw new SerializationException(
"Found invalid "
+ SET_END
+ " character at position "
+ i
+ " of text "
+ iSource
+ ". Ensure it is opened and closed correctly.");
}
insideSet--;
}
}
}
if (considerBags) {
if (c == BAG_BEGIN) {
insideBag++;
} else if (c == BAG_END) {
if (!isCharPresent(c, iSeparator)) {
if (insideBag == 0) {
throw new SerializationException(
"Found invalid "
+ BAG_BEGIN
+ " character. Ensure it is opened and closed correctly.");
}
insideBag--;
}
}
}
}
}
if (insideLinkPart > 0
&& c != '-'
&& !Character.isDigit(c)
&& c != RID.SEPARATOR
&& c != LINK) {
insideLinkPart = 0;
}
if ((c == '"' || c == '`' || iStringSeparatorExtended && c == '\'') && !encodeMode) {
// START STRING
stringBeginChar = c;
}
if (insideParenthesis == 0
&& insideList == 0
&& insideSet == 0
&& insideMap == 0
&& insideLinkPart == 0
&& insideBag == 0) {
// OUTSIDE A PARAMS/COLLECTION/MAP
if (i >= iMinPosSeparatorAreValid && isCharPresent(c, iSeparator)) {
// SEPARATOR (OUTSIDE A STRING): PUSH
return i + 1;
}
}
if (iJumpChars.length > 0) {
if (i >= iMinPosSeparatorAreValid && isCharPresent(c, iJumpChars)) {
continue;
}
}
} else {
// INSIDE A STRING
if ((c == '"' || c == '`' || iStringSeparatorExtended && c == '\'') && !encodeMode) {
// CLOSE THE STRING ?
if (stringBeginChar == c) {
// SAME CHAR AS THE BEGIN OF THE STRING: CLOSE IT AND PUSH
stringBeginChar = ' ';
}
}
}
if (c == '\\' && !encodeMode && !iPreserveQuotes) {
// ESCAPE CHARS
final var nextChar = iSource.charAt(i + 1);
if (nextChar == 'u' && iUnicode) {
i =
StringParser.readUnicode(
iSource, i + 2, tooBigValue ? new StringBuilder() : iBuffer);
continue;
} else if (nextChar == 'n') {
if (!tooBigValue) {
iBuffer.append("\n");
}
i++;
continue;
} else if (nextChar == 'r') {
if (!tooBigValue) {
iBuffer.append("\r");
}
i++;
continue;
} else if (nextChar == 't') {
if (!tooBigValue) {
iBuffer.append("\t");
}
i++;
continue;
} else if (nextChar == 'f') {
if (!tooBigValue) {
iBuffer.append("\f");
}
i++;
continue;
} else {
encodeMode = true;
}
} else {
encodeMode = false;
}
if (c != '\\' && encodeMode) {
encodeMode = false;
}
if (iMaxValueSizeBeforeSkip > 0 && iBuffer.length() > iMaxValueSizeBeforeSkip) {
tooBigValue = true;
iBuffer.setLength(0);
iBuffer.append(SKIPPED_VALUE);
}
if (!tooBigValue) {
iBuffer.append(c);
}
}
return -1;
}