static int ExtractToken(string fullExpression, string tokenBegin, Token token) { // Cant find opening Parentheses if (tokenBegin[1] != '(') { throw new InvalidDataContractException(SRClient.ExpressionMissingOpenParentheses(fullExpression, tokenBegin)); } int indexOfClose = tokenBegin.IndexOf(')'); int indexOfComma = tokenBegin.IndexOf(','); int indexOfDefaultBegin = tokenBegin.IndexOf(":{", StringComparison.InvariantCultureIgnoreCase); int indexOfDefaultEnd = indexOfDefaultBegin + 2; int defaultFullLength = 0; // Here we 'read' default value which may contain any character if (indexOfDefaultBegin > 1 && indexOfDefaultBegin < indexOfClose) { if (indexOfDefaultBegin < 3) { throw new InvalidDataContractException(SRClient.ExpressionMissingProperty(fullExpression, tokenBegin)); } var escape = false; while (true) { if (indexOfDefaultEnd >= tokenBegin.Length) { throw new InvalidDataContractException(SRClient.ExpressionMissingDefaultEnd(fullExpression, tokenBegin)); } if (tokenBegin[indexOfDefaultEnd] == '}' && !escape) { break; } escape = tokenBegin[indexOfDefaultEnd] == '\\' && !escape; indexOfDefaultEnd++; } defaultFullLength = indexOfDefaultEnd - indexOfDefaultBegin + 1; token.DefaultValue = tokenBegin.Substring(indexOfDefaultBegin + 2, defaultFullLength - 3); // Fix indexes if default value contains ')' or ',' indexOfComma = tokenBegin.IndexOf(',', indexOfDefaultEnd); indexOfClose = tokenBegin.IndexOf(')', indexOfDefaultEnd); } // Cant find closing Parentheses if (indexOfClose == -1) { throw new InvalidDataContractException(SRClient.ExpressionMissingClosingParentheses(fullExpression, tokenBegin)); } // When percentage or hash is used comma is prohibited if ((token.Type == TokenType.Percentage || token.Type == TokenType.Hash) && indexOfComma != -1 && indexOfComma < indexOfClose) { throw new InvalidDataContractException(SRClient.ExpressionErrorParsePercentFormat(fullExpression, tokenBegin)); } // When dot is used comma is mandatory if (token.Type == TokenType.Dot && indexOfComma == -1) { throw new InvalidDataContractException(SRClient.ExpressionErrorParseDotFormat(fullExpression, tokenBegin)); } int shortLength = 0; if (indexOfComma != -1 && indexOfComma < indexOfClose) { string shortLengthString = tokenBegin.Substring(indexOfComma + 1, indexOfClose - indexOfComma - 1); if (!int.TryParse(shortLengthString, out shortLength) || shortLength < 0) { throw new InvalidDataContractException(SRClient.ExpressionIsNotPositiveInteger(fullExpression, tokenBegin, shortLengthString)); } if (shortLength == 0) { token.EmptyString = true; } token.Length = shortLength; token.Property = tokenBegin.Substring(2, indexOfComma - 2 - defaultFullLength); } else { token.Property = tokenBegin.Substring(2, indexOfClose - 2 - defaultFullLength); } token.Property = token.Property.Trim(); return(indexOfClose); }