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); }
static internal int GetKeyValuePair(string connectionString, int currentPosition, StringBuilder buffer, 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 ('=' == currentChar) { parserState = ParserState.Key; break; } keyname = GetKeyName(buffer); if (ADP.IsEmpty(keyname)) { throw ADP.ConnectionStringSyntax(startposition); } buffer.Length = 0; parserState = ParserState.KeyEnd; goto case ParserState.KeyEnd; case ParserState.KeyEnd: if (Char.IsWhiteSpace(currentChar)) { continue; } { 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 (ADP.IsEmpty(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 (('\'' == 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); }