internal static int GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string keyname, out string keyvalue) { int startposition = currentPosition; buffer.Length = 0; keyname = null; keyvalue = null; char currentChar = '\0'; ParserState parserState = ParserState.NothingYet; int length = connectionString.Length; for (; currentPosition < length; ++currentPosition) { currentChar = connectionString[currentPosition]; switch (parserState) { case ParserState.NothingYet: // [\\s;]* if ((';' == currentChar) || char.IsWhiteSpace(currentChar)) { continue; } if ('\0' == currentChar) { parserState = ParserState.NullTermination; continue; } if (char.IsControl(currentChar)) { throw ADP.ConnectionStringSyntax(startposition); } startposition = currentPosition; if ('=' != currentChar) { parserState = ParserState.Key; break; } else { parserState = ParserState.KeyEqual; continue; } case ParserState.Key: // (?<key>([^=\\s\\p{Cc}]|\\s+[^=\\s\\p{Cc}]|\\s+==|==)+) if ('=' == currentChar) { parserState = ParserState.KeyEqual; continue; } if (char.IsWhiteSpace(currentChar)) { break; } if (char.IsControl(currentChar)) { throw ADP.ConnectionStringSyntax(startposition); } break; case ParserState.KeyEqual: // \\s*=(?!=)\\s* if (!useOdbcRules && '=' == currentChar) { parserState = ParserState.Key; break; } keyname = GetKeyName(buffer); if (string.IsNullOrEmpty(keyname)) { throw ADP.ConnectionStringSyntax(startposition); } buffer.Length = 0; parserState = ParserState.KeyEnd; goto case ParserState.KeyEnd; case ParserState.KeyEnd: if (char.IsWhiteSpace(currentChar)) { continue; } if (useOdbcRules) { if ('{' == currentChar) { parserState = ParserState.BraceQuoteValue; break; } } else { if ('\'' == currentChar) { parserState = ParserState.SingleQuoteValue; continue; } if ('"' == currentChar) { parserState = ParserState.DoubleQuoteValue; continue; } } if (';' == currentChar) { goto ParserExit; } if ('\0' == currentChar) { goto ParserExit; } if (char.IsControl(currentChar)) { throw ADP.ConnectionStringSyntax(startposition); } parserState = ParserState.UnquotedValue; break; case ParserState.UnquotedValue: // "((?![\"'\\s])" + "([^;\\s\\p{Cc}]|\\s+[^;\\s\\p{Cc}])*" + "(?<![\"']))" if (char.IsWhiteSpace(currentChar)) { break; } if (char.IsControl(currentChar) || ';' == currentChar) { goto ParserExit; } break; case ParserState.DoubleQuoteValue: // "(\"([^\"\u0000]|\"\")*\")" if ('"' == currentChar) { parserState = ParserState.DoubleQuoteValueQuote; continue; } if ('\0' == currentChar) { throw ADP.ConnectionStringSyntax(startposition); } break; case ParserState.DoubleQuoteValueQuote: if ('"' == currentChar) { parserState = ParserState.DoubleQuoteValue; break; } keyvalue = GetKeyValue(buffer, false); parserState = ParserState.QuotedValueEnd; goto case ParserState.QuotedValueEnd; case ParserState.SingleQuoteValue: // "('([^'\u0000]|'')*')" if ('\'' == currentChar) { parserState = ParserState.SingleQuoteValueQuote; continue; } if ('\0' == currentChar) { throw ADP.ConnectionStringSyntax(startposition); } break; case ParserState.SingleQuoteValueQuote: if ('\'' == currentChar) { parserState = ParserState.SingleQuoteValue; break; } keyvalue = GetKeyValue(buffer, false); parserState = ParserState.QuotedValueEnd; goto case ParserState.QuotedValueEnd; case ParserState.BraceQuoteValue: // "(\\{([^\\}\u0000]|\\}\\})*\\})" if ('}' == currentChar) { parserState = ParserState.BraceQuoteValueQuote; break; } if ('\0' == currentChar) { throw ADP.ConnectionStringSyntax(startposition); } break; case ParserState.BraceQuoteValueQuote: if ('}' == currentChar) { parserState = ParserState.BraceQuoteValue; break; } keyvalue = GetKeyValue(buffer, false); parserState = ParserState.QuotedValueEnd; goto case ParserState.QuotedValueEnd; case ParserState.QuotedValueEnd: if (char.IsWhiteSpace(currentChar)) { continue; } if (';' == currentChar) { goto ParserExit; } if ('\0' == currentChar) { parserState = ParserState.NullTermination; continue; } throw ADP.ConnectionStringSyntax(startposition); // unbalanced single quote case ParserState.NullTermination: // [\\s;\u0000]* if ('\0' == currentChar) { continue; } if (char.IsWhiteSpace(currentChar)) { continue; } throw ADP.ConnectionStringSyntax(currentPosition); default: throw ADP.InternalError(ADP.InternalErrorCode.InvalidParserState1); } buffer.Append(currentChar); } ParserExit: switch (parserState) { case ParserState.Key: case ParserState.DoubleQuoteValue: case ParserState.SingleQuoteValue: case ParserState.BraceQuoteValue: // keyword not found/unbalanced double/single quote throw ADP.ConnectionStringSyntax(startposition); case ParserState.KeyEqual: // equal sign at end of line keyname = GetKeyName(buffer); if (string.IsNullOrEmpty(keyname)) { throw ADP.ConnectionStringSyntax(startposition); } break; case ParserState.UnquotedValue: // unquoted value at end of line keyvalue = GetKeyValue(buffer, true); char tmpChar = keyvalue[keyvalue.Length - 1]; if (!useOdbcRules && (('\'' == tmpChar) || ('"' == tmpChar))) { throw ADP.ConnectionStringSyntax(startposition); // unquoted value must not end in quote, except for odbc } break; case ParserState.DoubleQuoteValueQuote: case ParserState.SingleQuoteValueQuote: case ParserState.BraceQuoteValueQuote: case ParserState.QuotedValueEnd: // quoted value at end of line keyvalue = GetKeyValue(buffer, false); break; case ParserState.NothingYet: case ParserState.KeyEnd: case ParserState.NullTermination: // do nothing break; default: throw ADP.InternalError(ADP.InternalErrorCode.InvalidParserState2); } if ((';' == currentChar) && (currentPosition < connectionString.Length)) { currentPosition++; } return(currentPosition); }