private static Dictionary<string, string> SplitConnectionString(string connectionString, Dictionary<string, string> synonyms, bool firstKey) { var parsetable = new Dictionary<string, string>(); Regex parser = (firstKey ? s_connectionStringRegexOdbc : s_connectionStringRegex); const int KeyIndex = 1, ValueIndex = 2; Debug.Assert(KeyIndex == parser.GroupNumberFromName("key"), "wrong key index"); Debug.Assert(ValueIndex == parser.GroupNumberFromName("value"), "wrong value index"); if (null != connectionString) { Match match = parser.Match(connectionString); if (!match.Success || (match.Length != connectionString.Length)) { throw ADP.ConnectionStringSyntax(match.Length); } int indexValue = 0; CaptureCollection keyvalues = match.Groups[ValueIndex].Captures; foreach (Capture keypair in match.Groups[KeyIndex].Captures) { string keyname = (firstKey ? keypair.Value : keypair.Value.Replace("==", "=")).ToLower(CultureInfo.InvariantCulture); string keyvalue = keyvalues[indexValue++].Value; if (0 < keyvalue.Length) { if (!firstKey) { switch (keyvalue[0]) { case '\"': keyvalue = keyvalue.Substring(1, keyvalue.Length - 2).Replace("\"\"", "\""); break; case '\'': keyvalue = keyvalue.Substring(1, keyvalue.Length - 2).Replace("\'\'", "\'"); break; default: break; } } } else { keyvalue = null; } DebugTraceKeyValuePair(keyname, keyvalue, synonyms); string synonym; string realkeyname = null != synonyms ? (synonyms.TryGetValue(keyname, out synonym) ? synonym : null) : keyname; if (!IsKeyNameValid(realkeyname)) { throw ADP.KeywordNotSupported(keyname); } if (!firstKey || !parsetable.ContainsKey(realkeyname)) { parsetable[realkeyname] = keyvalue; // last key-value pair wins (or first) } } } return parsetable; }
private static Hashtable SplitConnectionString(string connectionString, Hashtable synonyms) { Hashtable parsetable = new Hashtable(); Regex parser = s_connectionStringRegex; const int KeyIndex = 1, ValueIndex = 2; Debug.Assert(KeyIndex == parser.GroupNumberFromName("key"), "wrong key index"); Debug.Assert(ValueIndex == parser.GroupNumberFromName("value"), "wrong value index"); if (null != connectionString) { Match match = parser.Match(connectionString); if (!match.Success || (match.Length != connectionString.Length)) { throw ADP.ConnectionStringSyntax(match.Length); } int indexValue = 0; CaptureCollection keyvalues = match.Groups[ValueIndex].Captures; foreach (Capture keypair in match.Groups[KeyIndex].Captures) { string keyname = keypair.Value.Replace("==", "=").ToLowerInvariant(); string keyvalue = keyvalues[indexValue++].Value; if (0 < keyvalue.Length) { { switch (keyvalue[0]) { case '\"': keyvalue = keyvalue.Substring(1, keyvalue.Length - 2).Replace("\"\"", "\""); break; case '\'': keyvalue = keyvalue.Substring(1, keyvalue.Length - 2).Replace("\'\'", "\'"); break; default: break; } } } else { keyvalue = null; } DebugTraceKeyValuePair(keyname, keyvalue, synonyms); string realkeyname = ((null != synonyms) ? (string)synonyms[keyname] : keyname); if (!IsKeyNameValid(realkeyname)) { throw ADP.KeywordNotSupported(keyname); } { parsetable[realkeyname] = keyvalue; // last key-value pair wins (or first) } } } return(parsetable); }
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); }
internal static int GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, bool useOdbcRules, out string keyname, out string keyvalue) { int index = currentPosition; buffer.Length = 0; keyname = null; keyvalue = null; char c = '\0'; ParserState nothingYet = ParserState.NothingYet; int length = connectionString.Length; while (currentPosition < length) { c = connectionString[currentPosition]; switch (nothingYet) { case ParserState.NothingYet: if ((';' != c) && !char.IsWhiteSpace(c)) { if (c != '\0') { break; } nothingYet = ParserState.NullTermination; } goto Label_0255; case ParserState.Key: if ('=' != c) { goto Label_00BD; } nothingYet = ParserState.KeyEqual; goto Label_0255; case ParserState.KeyEqual: if (useOdbcRules || ('=' != c)) { goto Label_00E9; } nothingYet = ParserState.Key; goto Label_024D; case ParserState.KeyEnd: goto Label_010C; case ParserState.UnquotedValue: if (char.IsWhiteSpace(c) || (!char.IsControl(c) && (';' != c))) { goto Label_024D; } goto Label_0262; case ParserState.DoubleQuoteValue: if ('"' != c) { goto Label_0192; } nothingYet = ParserState.DoubleQuoteValueQuote; goto Label_0255; case ParserState.DoubleQuoteValueQuote: if ('"' != c) { goto Label_01AB; } nothingYet = ParserState.DoubleQuoteValue; goto Label_024D; case ParserState.SingleQuoteValue: if ('\'' != c) { goto Label_01C7; } nothingYet = ParserState.SingleQuoteValueQuote; goto Label_0255; case ParserState.SingleQuoteValueQuote: if ('\'' != c) { goto Label_01DD; } nothingYet = ParserState.SingleQuoteValue; goto Label_024D; case ParserState.BraceQuoteValue: if ('}' != c) { goto Label_01F6; } nothingYet = ParserState.BraceQuoteValueQuote; goto Label_024D; case ParserState.BraceQuoteValueQuote: if ('}' != c) { goto Label_020A; } nothingYet = ParserState.BraceQuoteValue; goto Label_024D; case ParserState.QuotedValueEnd: goto Label_0217; case ParserState.NullTermination: if ((c != '\0') && !char.IsWhiteSpace(c)) { throw ADP.ConnectionStringSyntax(currentPosition); } goto Label_0255; default: throw ADP.InternalError(ADP.InternalErrorCode.InvalidParserState1); } if (char.IsControl(c)) { throw ADP.ConnectionStringSyntax(index); } index = currentPosition; if ('=' != c) { nothingYet = ParserState.Key; goto Label_024D; } nothingYet = ParserState.KeyEqual; goto Label_0255; Label_00BD: if (char.IsWhiteSpace(c) || !char.IsControl(c)) { goto Label_024D; } throw ADP.ConnectionStringSyntax(index); Label_00E9: keyname = GetKeyName(buffer); if (ADP.IsEmpty(keyname)) { throw ADP.ConnectionStringSyntax(index); } buffer.Length = 0; nothingYet = ParserState.KeyEnd; Label_010C: if (char.IsWhiteSpace(c)) { goto Label_0255; } if (useOdbcRules) { if ('{' != c) { goto Label_013F; } nothingYet = ParserState.BraceQuoteValue; goto Label_024D; } if ('\'' == c) { nothingYet = ParserState.SingleQuoteValue; goto Label_0255; } if ('"' == c) { nothingYet = ParserState.DoubleQuoteValue; goto Label_0255; } Label_013F: if ((';' == c) || (c == '\0')) { break; } if (char.IsControl(c)) { throw ADP.ConnectionStringSyntax(index); } nothingYet = ParserState.UnquotedValue; goto Label_024D; Label_0192: if (c != '\0') { goto Label_024D; } throw ADP.ConnectionStringSyntax(index); Label_01AB: keyvalue = GetKeyValue(buffer, false); nothingYet = ParserState.QuotedValueEnd; goto Label_0217; Label_01C7: if (c != '\0') { goto Label_024D; } throw ADP.ConnectionStringSyntax(index); Label_01DD: keyvalue = GetKeyValue(buffer, false); nothingYet = ParserState.QuotedValueEnd; goto Label_0217; Label_01F6: if (c != '\0') { goto Label_024D; } throw ADP.ConnectionStringSyntax(index); Label_020A: keyvalue = GetKeyValue(buffer, false); nothingYet = ParserState.QuotedValueEnd; Label_0217: if (char.IsWhiteSpace(c)) { goto Label_0255; } if (';' == c) { break; } if (c == '\0') { nothingYet = ParserState.NullTermination; goto Label_0255; } throw ADP.ConnectionStringSyntax(index); Label_024D: buffer.Append(c); Label_0255: currentPosition++; } Label_0262: switch (nothingYet) { case ParserState.NothingYet: case ParserState.KeyEnd: case ParserState.NullTermination: break; case ParserState.Key: case ParserState.DoubleQuoteValue: case ParserState.SingleQuoteValue: case ParserState.BraceQuoteValue: throw ADP.ConnectionStringSyntax(index); case ParserState.KeyEqual: keyname = GetKeyName(buffer); if (ADP.IsEmpty(keyname)) { throw ADP.ConnectionStringSyntax(index); } break; case ParserState.UnquotedValue: { keyvalue = GetKeyValue(buffer, true); char ch2 = keyvalue[keyvalue.Length - 1]; if (!useOdbcRules && (('\'' == ch2) || ('"' == ch2))) { throw ADP.ConnectionStringSyntax(index); } break; } case ParserState.DoubleQuoteValueQuote: case ParserState.SingleQuoteValueQuote: case ParserState.BraceQuoteValueQuote: case ParserState.QuotedValueEnd: keyvalue = GetKeyValue(buffer, false); break; default: throw ADP.InternalError(ADP.InternalErrorCode.InvalidParserState2); } if ((';' == c) && (currentPosition < connectionString.Length)) { currentPosition++; } return(currentPosition); }