context: // created on 29/11/2007
  
  
  // Npgsql.NpgsqlConnectionStringBuilder.cs
  
  //
  
  // Author:
  
  //	Glen Parker (glenebob@nwlink.com)
  
  //	Ben Sagal (bensagal@gmail.com)
  
  //	Tao Wang (dancefire@gmail.com)
  
  //
  
  //	Copyright (C) 2007 The Npgsql Development Team
  
  //	npgsql-general@gborg.postgresql.org
  
  //	http://gborg.postgresql.org/project/npgsql/projdisplay.php
  
  //
  
  // Permission to use, copy, modify, and distribute this software and its
  
  // documentation for any purpose, without fee, and without a written
  
  // agreement is hereby granted, provided that the above copyright notice
  
  // and this paragraph and the following two paragraphs appear in all copies.
  
  // 
  
  // IN NO EVENT SHALL THE NPGSQL DEVELOPMENT TEAM BE LIABLE TO ANY PARTY
  
  // FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
  
  // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
  
  // DOCUMENTATION, EVEN IF THE NPGSQL DEVELOPMENT TEAM HAS BEEN ADVISED OF
  
  // THE POSSIBILITY OF SUCH DAMAGE.
  
  // 
  
  // THE NPGSQL DEVELOPMENT TEAM SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  
  // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  
  // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
  
  // ON AN "AS IS" BASIS, AND THE NPGSQL DEVELOPMENT TEAM HAS NO OBLIGATIONS
  
  // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  
  
  using System;
  using System.Collections.Generic;
  using System.Data.Common;
  using System.Reflection;
  using System.Resources;
  using System.Text;
  
  namespace Npgsql
  
  {
  	public sealed class NpgsqlConnectionStringBuilder : DbConnectionStringBuilder
  
  	{
  		private static readonly ResourceManager resman = new ResourceManager(MethodBase.GetCurrentMethod().DeclaringType);
  
  		private static readonly Dictionary<Keywords, object> defaults = new Dictionary<Keywords, object>();
  
  
  		private string originalConnectionString;
  
  
  		private const int POOL_SIZE_LIMIT = 1024;
  
  		private const int TIMEOUT_LIMIT = 1024;
  
  
  		static NpgsqlConnectionStringBuilder()
  
  		{
  			defaults.Add(Keywords.Host, string.Empty);
  
  			defaults.Add(Keywords.Port, 5432);
  
  			defaults.Add(Keywords.Protocol, ProtocolVersion.Version3);
  
  			defaults.Add(Keywords.Database, string.Empty);
  
  			defaults.Add(Keywords.UserName, string.Empty);
  
  			defaults.Add(Keywords.Password, string.Empty);
  
  			defaults.Add(Keywords.SSL, false);
  
  			defaults.Add(Keywords.SslMode, SslMode.Disable);
  
  			defaults.Add(Keywords.Timeout, 15);
  
  			defaults.Add(Keywords.SearchPath, string.Empty);
  
  			defaults.Add(Keywords.Pooling, true);
  
  			defaults.Add(Keywords.ConnectionLifeTime, 15);
  
  			defaults.Add(Keywords.MinPoolSize, 1);
  
  			defaults.Add(Keywords.MaxPoolSize, 20);
  
  			defaults.Add(Keywords.SyncNotification, false);
  
  			defaults.Add(Keywords.CommandTimeout, 20);
  
  			defaults.Add(Keywords.Enlist, false);
  
  			defaults.Add(Keywords.PreloadReader, false);
  
  			defaults.Add(Keywords.UseExtendedTypes, false);
              defaults.Add(Keywords.IntegratedSecurity, false);
              
              defaults.Add(Keywords.Compatible, THIS_VERSION);
  		}
  
  
  		public NpgsqlConnectionStringBuilder()
  
  		{
  			this.Clear();
              
  		}
  
  		public NpgsqlConnectionStringBuilder(string connectionString) 
  
  		{
  		    this.Clear();
  		    
  		    this.originalConnectionString = connectionString;
  
  		    base.ConnectionString = connectionString;
  		}
  
  
  		/// <summary>
  		/// Return an exact copy of this NpgsqlConnectionString.
  		/// </summary>
  		public NpgsqlConnectionStringBuilder Clone()
  
  		{
  			NpgsqlConnectionStringBuilder builder = new NpgsqlConnectionStringBuilder();
  
  			foreach (string key in this.Keys)
  
  			{
  				builder[key] = this[key];
  			}
  
  			return builder;
  		}
  
  		#region Parsing Functions
  
  		private static SslMode ToSslMode(object value)
  
  		{
  			if (value is SslMode)
  
  			{
  				return (SslMode) value;
  			}
  
  			else
  
  			{
  				return (SslMode) Enum.Parse(typeof (SslMode), value.ToString(), true);
  			}
  		}
  
  
  		private static ProtocolVersion ToProtocolVersion(object value)
  
  		{
  			if (value is ProtocolVersion)
  
  			{
  				return (ProtocolVersion) value;
  			}
  
  			else
  
  			{
  				int ver = Convert.ToInt32(value);
  
  
  				switch (ver)
  
  				{
  					case 2:
  
  						return ProtocolVersion.Version2;
  
  					case 3:
  
  						return ProtocolVersion.Version3;
  
  					default:
  
  						throw new InvalidCastException(value.ToString());
  				}
  			}
  		}
  
  
  		private static string ToString(ProtocolVersion protocolVersion)
  
  		{
  			switch (protocolVersion)
  
  			{
  				case ProtocolVersion.Version2:
  
  					return "2";
  
  				case ProtocolVersion.Version3:
  
  					return "3";
  
  				default:
  
  					return string.Empty;
  			}
  		}
  
  
  		private static int ToInt32(object value, int min, int max, string key)
  
  		{
  			int v = Convert.ToInt32(value);
  
  			if (v < min)
  
  			{
  				throw new ArgumentOutOfRangeException(String.Format(resman.GetString("Exception_IntegerKeyValMin"), key, min), key);
  			}
  
  			else if (v > max)
  
  			{
  				throw new ArgumentOutOfRangeException(String.Format(resman.GetString("Exception_IntegerKeyValMax"), key, max), key);
  			}
  
  			return v;
  		}
  
  
  		private static Boolean ToBoolean(object value)
  
  		{
  			string text = value as string;
  
  			if (text != null)
  
  			{
  				switch (text.ToLowerInvariant())
  
  				{
  					case "t":
  
  					case "true":
  
  					case "y":
  
  					case "yes":
  
  						return true;
  
  
  					case "f":
  
  					case "false":
  
  					case "n":
  
  					case "no":
  
  						return false;
  
  
  					default:
  
  						throw new InvalidCastException(value.ToString());
  				}
  			}
  
  			else
  
  			{
  				return Convert.ToBoolean(value);
  			}
  		}
  
          private Boolean ToIntegratedSecurity(object value)
          {
              string text = value as string;
              if (text != null)
              {
                  switch (text.ToLowerInvariant())
                  {
                      case "t":
                      case "true":
                      case "y":
                      case "yes":
                      case "sspi":
                          return true;
  
                      case "f":
                      case "false":
                      case "n":
                      case "no":
                          return false;
  
                      default:
                          throw new InvalidCastException(value.ToString());
                  }
              }
              else
              {
                  return Convert.ToBoolean(value);
              }
          }
  
  		#endregion
  
  		#region Properties
  
  		private string _host;
  
  
  		public string Host
  
  		{
  			get { return _host; }
  
  			set { SetValue(GetKeyName(Keywords.Host), value); }
  		}
  
  
  		private int _port;
  
  
  		public int Port
  
  		{
  			get { return _port; }
  
  			set { SetValue(GetKeyName(Keywords.Port), value); }
  		}
  
  
  		private ProtocolVersion _protocol;
  
  
  		public ProtocolVersion Protocol
  
  		{
  			get { return _protocol; }
  
  			set { SetValue(GetKeyName(Keywords.Protocol), value); }
  		}
  
  		private string _database;
  
  
  		public string Database
  
  		{
  			get { return _database; }
  
  			set { SetValue(GetKeyName(Keywords.Database), value); }
  		}
  
  		private string _username;
  
  
  		public string UserName
  
  		{
  			get
              {
  
gt:                 if ((_integrated_security) && (String.IsNullOrEmpty(_username)))