|
|
@@ -1,802 +0,0 @@
|
|
|
-//
|
|
|
-// System.Data.Common.DbConnectionStringBuilder.cs
|
|
|
-//
|
|
|
-// Author:
|
|
|
-// Sureshkumar T ([email protected])
|
|
|
-// Gert Driesen ([email protected]
|
|
|
-//
|
|
|
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
|
|
|
-//
|
|
|
-// Permission is hereby granted, free of charge, to any person obtaining
|
|
|
-// a copy of this software and associated documentation files (the
|
|
|
-// "Software"), to deal in the Software without restriction, including
|
|
|
-// without limitation the rights to use, copy, modify, merge, publish,
|
|
|
-// distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
-// permit persons to whom the Software is furnished to do so, subject to
|
|
|
-// the following conditions:
|
|
|
-//
|
|
|
-// The above copyright notice and this permission notice shall be
|
|
|
-// included in all copies or substantial portions of the Software.
|
|
|
-//
|
|
|
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
|
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
|
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
|
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
-//
|
|
|
-
|
|
|
-#if NET_2_0
|
|
|
-using System;
|
|
|
-using System.Collections;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.Collections.ObjectModel;
|
|
|
-using System.ComponentModel;
|
|
|
-using System.Data;
|
|
|
-using System.Data.Common;
|
|
|
-using System.Reflection;
|
|
|
-using System.Text;
|
|
|
-
|
|
|
-namespace System.Data.Common
|
|
|
-{
|
|
|
- public class DbConnectionStringBuilder : IDictionary, ICollection, IEnumerable, ICustomTypeDescriptor
|
|
|
- {
|
|
|
- #region Fields
|
|
|
-
|
|
|
- readonly Dictionary<string, object> _dictionary;
|
|
|
- readonly bool useOdbcRules;
|
|
|
-
|
|
|
- #endregion Fields
|
|
|
-
|
|
|
- #region Constructors
|
|
|
-
|
|
|
- public DbConnectionStringBuilder () : this (false)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- public DbConnectionStringBuilder (bool useOdbcRules)
|
|
|
- {
|
|
|
- this.useOdbcRules = useOdbcRules;
|
|
|
- _dictionary = new Dictionary <string, object> (StringComparer.InvariantCultureIgnoreCase);
|
|
|
- }
|
|
|
-
|
|
|
- #endregion // Constructors
|
|
|
-
|
|
|
- #region Properties
|
|
|
-
|
|
|
- [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
|
- [EditorBrowsable (EditorBrowsableState.Never)]
|
|
|
- [Browsable (false)]
|
|
|
- [DesignOnly (true)]
|
|
|
- public bool BrowsableConnectionString {
|
|
|
- get { throw new NotImplementedException (); }
|
|
|
- set { throw new NotImplementedException (); }
|
|
|
- }
|
|
|
-
|
|
|
- [RefreshProperties (RefreshProperties.All)]
|
|
|
- public string ConnectionString {
|
|
|
- get {
|
|
|
- IDictionary<string, object> dictionary = (IDictionary <string, object>) _dictionary;
|
|
|
- StringBuilder sb = new StringBuilder ();
|
|
|
- foreach (string key in Keys) {
|
|
|
- object value = null;
|
|
|
- if (!dictionary.TryGetValue (key, out value))
|
|
|
- continue;
|
|
|
- string val = value.ToString ();
|
|
|
- AppendKeyValuePair (sb, key, val, useOdbcRules);
|
|
|
- }
|
|
|
- return sb.ToString ();
|
|
|
- }
|
|
|
- set {
|
|
|
- Clear ();
|
|
|
- if (value == null)
|
|
|
- return;
|
|
|
- if (value.Trim ().Length == 0)
|
|
|
- return;
|
|
|
- ParseConnectionString (value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- [Browsable (false)]
|
|
|
- public virtual int Count
|
|
|
- {
|
|
|
- get { return _dictionary.Count; }
|
|
|
- }
|
|
|
-
|
|
|
- [Browsable (false)]
|
|
|
- public virtual bool IsFixedSize
|
|
|
- {
|
|
|
- get { return false; }
|
|
|
- }
|
|
|
-
|
|
|
- [Browsable (false)]
|
|
|
- public bool IsReadOnly
|
|
|
- {
|
|
|
- get { throw new NotImplementedException (); }
|
|
|
- }
|
|
|
-
|
|
|
- [Browsable (false)]
|
|
|
- public virtual object this [string keyword] {
|
|
|
- get {
|
|
|
- if (ContainsKey (keyword))
|
|
|
- return _dictionary [keyword];
|
|
|
- else
|
|
|
- throw new ArgumentException (string.Format (
|
|
|
- "Keyword '{0}' does not exist",
|
|
|
- keyword));
|
|
|
- }
|
|
|
- set {
|
|
|
- if (value == null) {
|
|
|
- Remove (keyword);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (keyword == null)
|
|
|
- throw new ArgumentNullException ("keyword");
|
|
|
-
|
|
|
- if (keyword.Length == 0)
|
|
|
- throw CreateInvalidKeywordException (keyword);
|
|
|
-
|
|
|
- for (int i = 0; i < keyword.Length; i++) {
|
|
|
- char c = keyword [i];
|
|
|
- if (i == 0 && (Char.IsWhiteSpace (c) || c == ';'))
|
|
|
- throw CreateInvalidKeywordException (keyword);
|
|
|
- if (i == (keyword.Length - 1) && Char.IsWhiteSpace (c))
|
|
|
- throw CreateInvalidKeywordException (keyword);
|
|
|
- if (Char.IsControl (c))
|
|
|
- throw CreateInvalidKeywordException (keyword);
|
|
|
- }
|
|
|
-
|
|
|
- if (ContainsKey (keyword))
|
|
|
- _dictionary [keyword] = value;
|
|
|
- else
|
|
|
- _dictionary.Add (keyword, value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- [Browsable (false)]
|
|
|
- public virtual ICollection Keys
|
|
|
- {
|
|
|
- get {
|
|
|
- string [] keys = new string [_dictionary.Keys.Count];
|
|
|
- ((ICollection<string>) _dictionary.Keys).CopyTo (keys, 0);
|
|
|
- ReadOnlyCollection<string> keyColl = new ReadOnlyCollection<string> (keys);
|
|
|
- return keyColl;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- bool ICollection.IsSynchronized
|
|
|
- {
|
|
|
- get { throw new NotImplementedException (); }
|
|
|
- }
|
|
|
-
|
|
|
- object ICollection.SyncRoot
|
|
|
- {
|
|
|
- get { throw new NotImplementedException (); }
|
|
|
- }
|
|
|
-
|
|
|
- object IDictionary.this [object keyword]
|
|
|
- {
|
|
|
- get { return this [(string) keyword]; }
|
|
|
- set { this [(string) keyword] = value; }
|
|
|
- }
|
|
|
-
|
|
|
- [Browsable (false)]
|
|
|
- public virtual ICollection Values {
|
|
|
- get {
|
|
|
- object [] values = new object [_dictionary.Values.Count];
|
|
|
- ((ICollection<object>) _dictionary.Values).CopyTo (values, 0);
|
|
|
- ReadOnlyCollection<object> valuesColl = new ReadOnlyCollection<object> (values);
|
|
|
- return valuesColl;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #endregion // Properties
|
|
|
-
|
|
|
- #region Methods
|
|
|
-
|
|
|
- public void Add (string keyword, object value)
|
|
|
- {
|
|
|
- this [keyword] = value;
|
|
|
- }
|
|
|
-
|
|
|
- public static void AppendKeyValuePair (StringBuilder builder, string keyword, string value,
|
|
|
- bool useOdbcRules)
|
|
|
- {
|
|
|
- if (builder == null)
|
|
|
- throw new ArgumentNullException ("builder");
|
|
|
- if (keyword == null)
|
|
|
- throw new ArgumentNullException ("keyName");
|
|
|
- if (keyword.Length == 0)
|
|
|
- throw new ArgumentException ("Empty keyword is not valid.");
|
|
|
-
|
|
|
- if (builder.Length > 0)
|
|
|
- builder.Append (';');
|
|
|
- if (!useOdbcRules)
|
|
|
- builder.Append (keyword.Replace ("=", "=="));
|
|
|
- else
|
|
|
- builder.Append (keyword);
|
|
|
- builder.Append ('=');
|
|
|
-
|
|
|
- if (value == null || value.Length == 0)
|
|
|
- return;
|
|
|
-
|
|
|
- if (!useOdbcRules) {
|
|
|
- bool dquoteFound = (value.IndexOf ('\"') > -1);
|
|
|
- bool squoteFound = (value.IndexOf ('\'') > -1);
|
|
|
-
|
|
|
- if (dquoteFound && squoteFound) {
|
|
|
- builder.Append ('\"');
|
|
|
- builder.Append (value.Replace ("\"", "\"\""));
|
|
|
- builder.Append ('\"');
|
|
|
- } else if (dquoteFound) {
|
|
|
- builder.Append ('\'');
|
|
|
- builder.Append (value);
|
|
|
- builder.Append ('\'');
|
|
|
- } else if (squoteFound || value.IndexOf ('=') > -1 || value.IndexOf (';') > -1) {
|
|
|
- builder.Append ('\"');
|
|
|
- builder.Append (value);
|
|
|
- builder.Append ('\"');
|
|
|
- } else if (ValueNeedsQuoting (value)) {
|
|
|
- builder.Append ('\"');
|
|
|
- builder.Append (value);
|
|
|
- builder.Append ('\"');
|
|
|
- } else
|
|
|
- builder.Append (value);
|
|
|
- } else {
|
|
|
- int braces = 0;
|
|
|
- bool semicolonFound = false;
|
|
|
- int len = value.Length;
|
|
|
- bool needBraces = false;
|
|
|
-
|
|
|
- int lastChar = -1;
|
|
|
-
|
|
|
- for (int i = 0; i < len; i++) {
|
|
|
- int peek = 0;
|
|
|
- if (i == (len - 1))
|
|
|
- peek = -1;
|
|
|
- else
|
|
|
- peek = value [i + 1];
|
|
|
-
|
|
|
- char c = value [i];
|
|
|
- switch (c) {
|
|
|
- case '{':
|
|
|
- braces++;
|
|
|
- break;
|
|
|
- case '}':
|
|
|
- if (peek.Equals (c)) {
|
|
|
- i++;
|
|
|
- continue;
|
|
|
- } else {
|
|
|
- braces--;
|
|
|
- if (peek != -1)
|
|
|
- needBraces = true;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ';':
|
|
|
- semicolonFound = true;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- lastChar = c;
|
|
|
- }
|
|
|
-
|
|
|
- if (value [0] == '{' && (lastChar != '}' || (braces == 0 && needBraces))) {
|
|
|
- builder.Append ('{');
|
|
|
- builder.Append (value.Replace ("}", "}}"));
|
|
|
- builder.Append ('}');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- bool isDriver = (string.Compare (keyword, "Driver", StringComparison.InvariantCultureIgnoreCase) == 0);
|
|
|
- if (isDriver) {
|
|
|
- if (value [0] == '{' && lastChar == '}' && !needBraces) {
|
|
|
- builder.Append (value);
|
|
|
- return;
|
|
|
- }
|
|
|
- builder.Append ('{');
|
|
|
- builder.Append (value.Replace ("}", "}}"));
|
|
|
- builder.Append ('}');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (value [0] == '{' && (braces != 0 || lastChar != '}') && needBraces) {
|
|
|
- builder.Append ('{');
|
|
|
- builder.Append (value.Replace ("}", "}}"));
|
|
|
- builder.Append ('}');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (value [0] != '{' && semicolonFound) {
|
|
|
- builder.Append ('{');
|
|
|
- builder.Append (value.Replace ("}", "}}"));
|
|
|
- builder.Append ('}');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- builder.Append (value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public static void AppendKeyValuePair (StringBuilder builder, string keyword, string value)
|
|
|
- {
|
|
|
- AppendKeyValuePair (builder, keyword, value, false);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual void Clear ()
|
|
|
- {
|
|
|
- _dictionary.Clear ();
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool ContainsKey (string keyword)
|
|
|
- {
|
|
|
- if (keyword == null)
|
|
|
- throw new ArgumentNullException ("keyword");
|
|
|
- return _dictionary.ContainsKey (keyword);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool EquivalentTo (DbConnectionStringBuilder connectionStringBuilder)
|
|
|
- {
|
|
|
- bool ret = true;
|
|
|
- try {
|
|
|
- if (Count != connectionStringBuilder.Count)
|
|
|
- ret = false;
|
|
|
- else {
|
|
|
- foreach (string key in Keys) {
|
|
|
- if (!this [key].Equals (connectionStringBuilder [key])) {
|
|
|
- ret = false;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (ArgumentException) {
|
|
|
- ret = false;
|
|
|
- }
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- protected virtual void GetProperties (Hashtable propertyDescriptors)
|
|
|
- {
|
|
|
- throw new NotImplementedException ();
|
|
|
- }
|
|
|
-
|
|
|
- [MonoTODO]
|
|
|
- protected internal void ClearPropertyDescriptors ()
|
|
|
- {
|
|
|
- throw new NotImplementedException ();
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool Remove (string keyword)
|
|
|
- {
|
|
|
- if (keyword == null)
|
|
|
- throw new ArgumentNullException ("keyword");
|
|
|
- return _dictionary.Remove (keyword);
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool ShouldSerialize (string keyword)
|
|
|
- {
|
|
|
- throw new NotImplementedException ();
|
|
|
- }
|
|
|
-
|
|
|
- void ICollection.CopyTo (Array array, int index)
|
|
|
- {
|
|
|
- if (array == null)
|
|
|
- throw new ArgumentNullException ("array");
|
|
|
- KeyValuePair<string, object> [] arr = array as KeyValuePair<string, object> [];
|
|
|
- if (arr == null)
|
|
|
- throw new ArgumentException ("Target array type is not compatible with the type of items in the collection");
|
|
|
- ((ICollection<KeyValuePair<string, object>>) _dictionary).CopyTo (arr, index);
|
|
|
- }
|
|
|
-
|
|
|
- void IDictionary.Add (object keyword, object value)
|
|
|
- {
|
|
|
- this.Add ((string) keyword, value);
|
|
|
- }
|
|
|
-
|
|
|
- bool IDictionary.Contains (object keyword)
|
|
|
- {
|
|
|
- return ContainsKey ((string) keyword);
|
|
|
- }
|
|
|
-
|
|
|
- IDictionaryEnumerator IDictionary.GetEnumerator ()
|
|
|
- {
|
|
|
- return (IDictionaryEnumerator) _dictionary.GetEnumerator ();
|
|
|
- }
|
|
|
-
|
|
|
- void IDictionary.Remove (object keyword)
|
|
|
- {
|
|
|
- Remove ((string) keyword);
|
|
|
- }
|
|
|
-
|
|
|
- IEnumerator IEnumerable.GetEnumerator ()
|
|
|
- {
|
|
|
- return (IEnumerator) _dictionary.GetEnumerator ();
|
|
|
- }
|
|
|
-
|
|
|
- private static object _staticAttributeCollection = null;
|
|
|
- AttributeCollection ICustomTypeDescriptor.GetAttributes ()
|
|
|
- {
|
|
|
- object value = _staticAttributeCollection;
|
|
|
- if (value == null) {
|
|
|
- CLSCompliantAttribute clsAttr = new CLSCompliantAttribute (true);
|
|
|
- DefaultMemberAttribute defMemAttr = new DefaultMemberAttribute ("Item");
|
|
|
- Attribute [] attrs = {clsAttr, defMemAttr};
|
|
|
- value = new AttributeCollection (attrs);
|
|
|
- }
|
|
|
- System.Threading.Interlocked.CompareExchange (ref _staticAttributeCollection, value, null);
|
|
|
- return _staticAttributeCollection as AttributeCollection;
|
|
|
- }
|
|
|
-
|
|
|
- string ICustomTypeDescriptor.GetClassName ()
|
|
|
- {
|
|
|
- return this.GetType ().ToString ();
|
|
|
- }
|
|
|
-
|
|
|
- string ICustomTypeDescriptor.GetComponentName ()
|
|
|
- {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- TypeConverter ICustomTypeDescriptor.GetConverter ()
|
|
|
- {
|
|
|
- return new CollectionConverter ();
|
|
|
- }
|
|
|
-
|
|
|
- EventDescriptor ICustomTypeDescriptor.GetDefaultEvent ()
|
|
|
- {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty ()
|
|
|
- {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- object ICustomTypeDescriptor.GetEditor (Type editorBaseType)
|
|
|
- {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- EventDescriptorCollection ICustomTypeDescriptor.GetEvents ()
|
|
|
- {
|
|
|
- return EventDescriptorCollection.Empty;
|
|
|
- }
|
|
|
-
|
|
|
- EventDescriptorCollection ICustomTypeDescriptor.GetEvents (Attribute [] attributes)
|
|
|
- {
|
|
|
- return EventDescriptorCollection.Empty;
|
|
|
- }
|
|
|
-
|
|
|
- PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties ()
|
|
|
- {
|
|
|
- return PropertyDescriptorCollection.Empty;
|
|
|
- }
|
|
|
-
|
|
|
- PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties (Attribute [] attributes)
|
|
|
- {
|
|
|
- return PropertyDescriptorCollection.Empty;
|
|
|
- }
|
|
|
-
|
|
|
- object ICustomTypeDescriptor.GetPropertyOwner (PropertyDescriptor pd)
|
|
|
- {
|
|
|
- throw new NotImplementedException ();
|
|
|
- }
|
|
|
-
|
|
|
- public override string ToString ()
|
|
|
- {
|
|
|
- return ConnectionString;
|
|
|
- }
|
|
|
-
|
|
|
- public virtual bool TryGetValue (string keyword, out object value)
|
|
|
- {
|
|
|
- // FIXME : not sure, difference between this [keyword] and this method
|
|
|
- bool found = ContainsKey (keyword);
|
|
|
- if (found)
|
|
|
- value = this [keyword];
|
|
|
- else
|
|
|
- value = null;
|
|
|
- return found;
|
|
|
- }
|
|
|
-
|
|
|
- static ArgumentException CreateInvalidKeywordException (string keyword)
|
|
|
- {
|
|
|
- return new ArgumentException ("A keyword cannot contain "
|
|
|
- + "control characters, leading semicolons or "
|
|
|
- + "leading or trailing whitespace.", keyword);
|
|
|
- }
|
|
|
-
|
|
|
- static ArgumentException CreateConnectionStringInvalidException (int index)
|
|
|
- {
|
|
|
- return new ArgumentException ("Format of initialization "
|
|
|
- + "string does not conform to specifications at "
|
|
|
- + "index " + index + ".");
|
|
|
- }
|
|
|
-
|
|
|
- static bool ValueNeedsQuoting (string value)
|
|
|
- {
|
|
|
- foreach (char c in value) {
|
|
|
- if (char.IsWhiteSpace (c))
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
- void ParseConnectionString (string connectionString)
|
|
|
- {
|
|
|
- if (useOdbcRules)
|
|
|
- ParseConnectionStringOdbc (connectionString);
|
|
|
- else
|
|
|
- ParseConnectionStringNonOdbc (connectionString);
|
|
|
- }
|
|
|
-
|
|
|
- void ParseConnectionStringOdbc (string connectionString)
|
|
|
- {
|
|
|
- bool inQuote = false;
|
|
|
- bool inDQuote = false;
|
|
|
- bool inName = true;
|
|
|
- bool inBraces = false;
|
|
|
-
|
|
|
- string name = String.Empty;
|
|
|
- string val = String.Empty;
|
|
|
- StringBuilder sb = new StringBuilder ();
|
|
|
- int len = connectionString.Length;
|
|
|
-
|
|
|
- for (int i = 0; i < len; i++) {
|
|
|
- char c = connectionString [i];
|
|
|
- int peek = (i == (len - 1)) ? -1 : connectionString [i + 1];
|
|
|
-
|
|
|
- switch (c) {
|
|
|
- case '{':
|
|
|
- if (inName) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (sb.Length == 0)
|
|
|
- inBraces = true;
|
|
|
- sb.Append (c);
|
|
|
- break;
|
|
|
- case '}':
|
|
|
- if (inName || !inBraces) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (peek == -1) {
|
|
|
- sb.Append (c);
|
|
|
- inBraces = false;
|
|
|
- } else if (peek.Equals (c)) {
|
|
|
- sb.Append (c);
|
|
|
- sb.Append (c);
|
|
|
- i++;
|
|
|
- } else {
|
|
|
- int next = NextNonWhitespaceChar (connectionString, i);
|
|
|
- if (next != -1 && ((char) next) != ';')
|
|
|
- throw CreateConnectionStringInvalidException (next);
|
|
|
- sb.Append (c);
|
|
|
- inBraces = false;
|
|
|
- }
|
|
|
- break;
|
|
|
- case ';':
|
|
|
- if (inName || inBraces) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (name.Length > 0 && sb.Length > 0) {
|
|
|
- val = sb.ToString ();
|
|
|
- name = name.ToLower ().TrimEnd ();
|
|
|
- this [name] = val;
|
|
|
- } else if (sb.Length > 0)
|
|
|
- throw CreateConnectionStringInvalidException (c);
|
|
|
- inName = true;
|
|
|
- name = String.Empty;
|
|
|
- sb.Length = 0;
|
|
|
- break;
|
|
|
- case '=':
|
|
|
- if (inBraces || !inName) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- name = sb.ToString ();
|
|
|
- if (name.Length == 0)
|
|
|
- throw CreateConnectionStringInvalidException (c);
|
|
|
- sb.Length = 0;
|
|
|
- inName = false;
|
|
|
- break;
|
|
|
- default:
|
|
|
- if (inDQuote || inQuote || inBraces)
|
|
|
- sb.Append (c);
|
|
|
- else if (char.IsWhiteSpace (c)) {
|
|
|
- // ignore leading whitespace
|
|
|
- if (sb.Length > 0) {
|
|
|
- int nextChar = SkipTrailingWhitespace (connectionString, i);
|
|
|
- if (nextChar == -1)
|
|
|
- sb.Append (c);
|
|
|
- else
|
|
|
- i = nextChar;
|
|
|
- }
|
|
|
- } else
|
|
|
- sb.Append (c);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ((inName && sb.Length > 0) || inDQuote || inQuote || inBraces)
|
|
|
- throw CreateConnectionStringInvalidException (len - 1);
|
|
|
-
|
|
|
- if (name.Length > 0 && sb.Length > 0) {
|
|
|
- val = sb.ToString ();
|
|
|
- name = name.ToLower ().TrimEnd ();
|
|
|
- this [name] = val;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- void ParseConnectionStringNonOdbc (string connectionString)
|
|
|
- {
|
|
|
- bool inQuote = false;
|
|
|
- bool inDQuote = false;
|
|
|
- bool inName = true;
|
|
|
-
|
|
|
- string name = String.Empty;
|
|
|
- string val = String.Empty;
|
|
|
- StringBuilder sb = new StringBuilder ();
|
|
|
- int len = connectionString.Length;
|
|
|
-
|
|
|
- for (int i = 0; i < len; i++) {
|
|
|
- char c = connectionString [i];
|
|
|
- int peek = (i == (len - 1)) ? -1 : connectionString [i + 1];
|
|
|
-
|
|
|
- switch (c) {
|
|
|
- case '\'':
|
|
|
- if (inName) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (inDQuote)
|
|
|
- sb.Append (c);
|
|
|
- else if (inQuote) {
|
|
|
- if (peek == -1)
|
|
|
- inQuote = false;
|
|
|
- else if (peek.Equals (c)) {
|
|
|
- sb.Append (c);
|
|
|
- i++;
|
|
|
- } else {
|
|
|
- int next = NextNonWhitespaceChar (connectionString, i);
|
|
|
- if (next != -1 && ((char) next) != ';')
|
|
|
- throw CreateConnectionStringInvalidException (next);
|
|
|
- inQuote = false;
|
|
|
- }
|
|
|
-
|
|
|
- if (!inQuote) {
|
|
|
- val = sb.ToString ();
|
|
|
- name = name.ToLower ().TrimEnd ();
|
|
|
- this [name] = val;
|
|
|
- inName = true;
|
|
|
- name = String.Empty;
|
|
|
- sb.Length = 0;
|
|
|
- }
|
|
|
- } else if (sb.Length == 0)
|
|
|
- inQuote = true;
|
|
|
- else
|
|
|
- sb.Append (c);
|
|
|
- break;
|
|
|
- case '"':
|
|
|
- if (inName) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (inQuote)
|
|
|
- sb.Append (c);
|
|
|
- else if (inDQuote) {
|
|
|
- if (peek == -1)
|
|
|
- inDQuote = false;
|
|
|
- else if (peek.Equals (c)) {
|
|
|
- sb.Append (c);
|
|
|
- i++;
|
|
|
- } else {
|
|
|
- int next = NextNonWhitespaceChar (connectionString, i);
|
|
|
- if (next != -1 && ((char) next) != ';')
|
|
|
- throw CreateConnectionStringInvalidException (next);
|
|
|
- inDQuote = false;
|
|
|
- }
|
|
|
- } else if (sb.Length == 0)
|
|
|
- inDQuote = true;
|
|
|
- else
|
|
|
- sb.Append (c);
|
|
|
- break;
|
|
|
- case ';':
|
|
|
- if (inName) {
|
|
|
- sb.Append (c);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (inDQuote || inQuote)
|
|
|
- sb.Append (c);
|
|
|
- else {
|
|
|
- if (name.Length > 0 && sb.Length > 0) {
|
|
|
- val = sb.ToString ();
|
|
|
- name = name.ToLower ().TrimEnd ();
|
|
|
- this [name] = val;
|
|
|
- } else if (sb.Length > 0)
|
|
|
- throw CreateConnectionStringInvalidException (c);
|
|
|
- inName = true;
|
|
|
- name = String.Empty;
|
|
|
- sb.Length = 0;
|
|
|
- }
|
|
|
- break;
|
|
|
- case '=':
|
|
|
- if (inDQuote || inQuote || !inName)
|
|
|
- sb.Append (c);
|
|
|
- else if (peek != -1 && peek.Equals (c)) {
|
|
|
- sb.Append (c);
|
|
|
- i++;
|
|
|
- } else {
|
|
|
- name = sb.ToString ();
|
|
|
- if (name.Length == 0)
|
|
|
- throw CreateConnectionStringInvalidException (c);
|
|
|
- sb.Length = 0;
|
|
|
- inName = false;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- if (inDQuote || inQuote)
|
|
|
- sb.Append (c);
|
|
|
- else if (char.IsWhiteSpace (c)) {
|
|
|
- // ignore leading whitespace
|
|
|
- if (sb.Length > 0) {
|
|
|
- int nextChar = SkipTrailingWhitespace (connectionString, i);
|
|
|
- if (nextChar == -1)
|
|
|
- sb.Append (c);
|
|
|
- else
|
|
|
- i = nextChar;
|
|
|
- }
|
|
|
- } else
|
|
|
- sb.Append (c);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ((inName && sb.Length > 0) || inDQuote || inQuote)
|
|
|
- throw CreateConnectionStringInvalidException (len -1);
|
|
|
-
|
|
|
- if (name.Length > 0 && sb.Length > 0) {
|
|
|
- val = sb.ToString ();
|
|
|
- name = name.ToLower ().TrimEnd ();
|
|
|
- this [name] = val;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- static int SkipTrailingWhitespace (string value, int index)
|
|
|
- {
|
|
|
- int len = value.Length;
|
|
|
- for (int i = (index + 1); i < len; i++) {
|
|
|
- char c = value [i];
|
|
|
- if (c == ';')
|
|
|
- return (i - 1);
|
|
|
- if (!char.IsWhiteSpace (c))
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return len - 1;
|
|
|
- }
|
|
|
-
|
|
|
- static int NextNonWhitespaceChar (string value, int index)
|
|
|
- {
|
|
|
- int len = value.Length;
|
|
|
- for (int i = (index + 1); i < len; i++) {
|
|
|
- char c = value [i];
|
|
|
- if (!char.IsWhiteSpace (c))
|
|
|
- return (int) c;
|
|
|
- }
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- #endregion // Public Methods
|
|
|
- }
|
|
|
-}
|
|
|
-#endif // NET_2_0 using
|