context: /* --------------------------------------------------------------------------
   * Copyrights
   *
   * Portions created by or assigned to Cursive Systems, Inc. are
   * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
   * information for Cursive Systems, Inc. is available at
   * http://www.cursive.net/.
   *
   * License
   *
   * Jabber-Net is licensed under the LGPL.
   * See LICENSE.txt for details.
   * --------------------------------------------------------------------------*/
  
  using System;
  using System.Collections;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Diagnostics;
  using System.Security.Cryptography;
  using System.Text;
  using System.Xml;
  using jabber.protocol;
  using jabber.protocol.client;
  using jabber.protocol.iq;
  using jabber.protocol.x;
  using bedrock.util;
  using bedrock.io;
  
  namespace jabber.connection
  {
      /// <summary>
      /// Manages the entity capabilities information for the local connection as well as remote ones.
      /// See XEP-0115, version 1.5 for details.
      /// </summary>
      [SVN("$Id$")]
      public class CapsManager : StreamComponent
      {
          /// <summary>
          /// Defines the default hash function to use for calculating ver attributes.
          /// </summary>
          public const string DEFAULT_HASH = "sha-1";
  
          private const string SEP = "<";
  
          /// <summary>
          /// Required designer variable.
          /// </summary>
          private System.ComponentModel.IContainer components = null;
  
          private DiscoNode m_disco;
          private string m_hash = DEFAULT_HASH;
          private string m_ver = null;
  
          private FileMap<DiscoInfo> m_cache = null;
          private DiscoManager m_discoManager = null;
  
          /// <summary>
          /// Creates a new capability manager.
          /// </summary>
          public CapsManager() : this((DiscoNode) null)
          {
          }
  
          /// <summary>
          /// Creates a new capability manager and associates it with a container.
          /// </summary>
          /// <param name="container">Parent container.</param>
          public CapsManager(IContainer container) : this((DiscoNode) null)
          {
              container.Add(this);
          }
  
          /// <summary>
          /// Create a CapsManager from an existing Disco Node.  Pass in null
          /// to use a placeholder.
          /// </summary>
          /// <param name="node"></param>
          public CapsManager(DiscoNode node)
          {
              InitializeComponent();
              this.OnStreamChanged += new bedrock.ObjectHandler(CapsManager_OnStreamChanged);
  
              if (node == null)
                  m_disco = new DiscoNode(new JID(null, "placeholder", null), null);
              else
                  m_disco = node;
          }
  
          /// <summary>
          /// Performs tasks associated with freeing, releasing, or resetting resources.
          /// </summary>
          /// <param name="disposing">
          /// True if managed resources should be disposed; otherwise, false.
          /// </param>
          protected override void Dispose(bool disposing)
          {
              if (disposing && (components != null))
              {
                  components.Dispose();
              }
              base.Dispose(disposing);
          }
  
          /// <summary>
          /// The RosterManager for this view
          /// </summary>
          [Category("Cache")]
          public DiscoManager DiscoManager
          {
              get
              {
                  // If we are running in the designer, let's try to auto-hook a RosterManager
                  if ((m_discoManager == null) && DesignMode)
                  {
                      IDesignerHost host = (IDesignerHost) base.GetService(typeof (IDesignerHost));
                      this.DiscoManager = (DiscoManager) jabber.connection.StreamComponent.GetComponentFromHost(host, typeof (DiscoManager));
                  }
                  return m_discoManager;
              }
              set
              {
                  if ((object) m_discoManager == (object) value)
                      return;
                  m_discoManager = value;
              }
          }
  
          /// <summary>
          /// The file to store a cache of all received caps into.  If no cache file is supplied,
          /// caps queries will not be generated.
          /// </summary>
          [Category("Cache")]
          public string FileName
          {
              get
              {
                  if (m_cache == null)
                      return null;
                  return m_cache.FileName;
              }
              set
              {
                  if (m_cache == null)
                  {
                      ElementFactory ef = new ElementFactory();
                      ef.AddType(new jabber.protocol.iq.Factory());
  
                      m_cache = new FileMap<DiscoInfo>(value, ef);
                  }
                  else
                      m_cache.FileName = value;
              }
          }
  
          /// <summary>
          /// Adds a feature to the feature list
          /// </summary>
          /// <param name="feature"></param>
          public void AddFeature(string feature)
          {
              m_ver = null;
              m_disco.AddFeature(feature);
          }
  
          /// <summary>
          /// Removes a feature from the feature list
          /// </summary>
          /// <param name="feature"></param>
          public void RemoveFeature(string feature)
          {
              m_ver = null;
              m_disco.RemoveFeature(feature);
          }
  
          /// <summary>
          /// Gets or sets the current features enabled by this entity.
          /// </summary>
          [Category("Capabilities")]
          [DefaultValue(null)]
          public string[] Features
          {
              get
              {
                  if (m_disco.Features == null)
                      return new string[0];
                  return m_disco.FeatureNames;
              }
              set
              {
                  m_ver = null;
                  m_disco.ClearFeatures();
                  if (value != null)
                      foreach (string feature in value)
                          m_disco.AddFeature(feature);
              }
          }
  
          private static HashAlgorithm GetHasher(string name)
          {
              switch (name)
              {
                  case null:
                      return null;
                  case "sha-1":
                      return SHA1.Create();
                  case "sha-256":
                      return SHA256.Create();
                  case "sha-512":
                      return SHA512.Create();
                  case "sha-384":
                      return SHA384.Create();
                  case "md5":
                      return MD5.Create();
              }
              throw new ArgumentException("Invalid hash method: " + name, "Hash");
          }
  
          /// <summary>
          /// Gets or sets the hash algorithm to use.
          /// </summary>
          [Category("Capabilities")]
          [DefaultValue(DEFAULT_HASH)]
          public string Hash
          {
  
gt:             get { return m_hash; }