The Labs \ Source Viewer \ SSCLI \ System.Net \ SpnDictionary

  1. //------------------------------------------------------------------------------
  2. // <copyright file="_SpnDictionary.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. /*++ 
  16. Abstract:
  17.     This internal class implements a static mutlithreaded dictionary for user-registered SPNs.
  18.     An SPN is mapped based on a Uri prefix that contains scheme, host and port.
  19. Author:
  20.     Alexei Vopilov    15-Nov-2003
  21. Revision History:
  22. --*/
  23. namespace System.Net
  24. {
  25.     using System;
  26.     using System.Collections;
  27.     using System.Collections.Specialized;
  28.     using System.Security.Permissions;
  29.    
  30.     internal class SpnDictionary : StringDictionary
  31.     {
  32.        
  33.         //
  34.         //A Hashtable can support one writer and multiple readers concurrently
  35.         //
  36.        
  37.         private Hashtable m_SyncTable = Hashtable.Synchronized(new Hashtable());
  38.        
  39.         //
  40.         //
  41.         internal SpnDictionary() : base()
  42.         {
  43.         }
  44.         //
  45.         //
  46.         //
  47.         public override int Count {
  48.             get {
  49.                 ExceptionHelper.WebPermissionUnrestricted.Demand();
  50.                 return m_SyncTable.Count;
  51.             }
  52.         }
  53.         //
  54.         // We are thread safe
  55.         //
  56.         public override bool IsSynchronized {
  57.             get { return true; }
  58.         }
  59.         //
  60.         // Internal lookup, bypasses security checks
  61.         //
  62.         internal string InternalGet(string canonicalKey)
  63.         {
  64.             int lastLength = 0;
  65.             string key = null;
  66.            
  67.             foreach (object o in m_SyncTable.Keys) {
  68.                 string s = (string)o;
  69.                 if (s != null && s.Length > lastLength) {
  70.                     if (String.Compare(s, 0, canonicalKey, 0, s.Length, StringComparison.OrdinalIgnoreCase) == 0) {
  71.                         lastLength = s.Length;
  72.                         key = s;
  73.                     }
  74.                 }
  75.             }
  76.             return (key != null) ? (string)m_SyncTable[key] : null;
  77.         }
  78.        
  79.         internal void InternalSet(string canonicalKey, string spn)
  80.         {
  81.             m_SyncTable[canonicalKey] = spn;
  82.         }
  83.         //
  84.         // Public lookup method
  85.         //
  86.         public override string this[string key]
  87.         {
  88.             get {
  89.                 key = GetCanonicalKey(key);
  90.                 return InternalGet(key);
  91.             }
  92.             set {
  93.                 key = GetCanonicalKey(key);
  94.                 InternalSet(key, value);
  95.             }
  96.         }
  97.         //
  98.         public override ICollection Keys {
  99.             get {
  100.                 ExceptionHelper.WebPermissionUnrestricted.Demand();
  101.                 return m_SyncTable.Keys;
  102.             }
  103.         }
  104.         //
  105.         public override object SyncRoot {
  106.             [HostProtection(Synchronization = true)]
  107.             get {
  108.                 ExceptionHelper.WebPermissionUnrestricted.Demand();
  109.                 return m_SyncTable;
  110.             }
  111.         }
  112.         //
  113.         public override ICollection Values {
  114.             get {
  115.                 ExceptionHelper.WebPermissionUnrestricted.Demand();
  116.                 return m_SyncTable.Values;
  117.             }
  118.         }
  119.         //
  120.         public override void Add(string key, string value)
  121.         {
  122.             key = GetCanonicalKey(key);
  123.             m_SyncTable.Add(key, value);
  124.         }
  125.         //
  126.         public override void Clear()
  127.         {
  128.             ExceptionHelper.WebPermissionUnrestricted.Demand();
  129.             m_SyncTable.Clear();
  130.         }
  131.         //
  132.         public override bool ContainsKey(string key)
  133.         {
  134.             key = GetCanonicalKey(key);
  135.             return m_SyncTable.ContainsKey(key);
  136.         }
  137.         //
  138.         public override bool ContainsValue(string value)
  139.         {
  140.             ExceptionHelper.WebPermissionUnrestricted.Demand();
  141.             return m_SyncTable.ContainsValue(value);
  142.         }
  143.         //
  144.         public override void CopyTo(Array array, int index)
  145.         {
  146.             ExceptionHelper.WebPermissionUnrestricted.Demand();
  147.             m_SyncTable.CopyTo(array, index);
  148.         }
  149.         //
  150.         public override IEnumerator GetEnumerator()
  151.         {
  152.             ExceptionHelper.WebPermissionUnrestricted.Demand();
  153.             return m_SyncTable.GetEnumerator();
  154.         }
  155.         //
  156.         public override void Remove(string key)
  157.         {
  158.             key = GetCanonicalKey(key);
  159.             m_SyncTable.Remove(key);
  160.         }
  161.        
  162.         //
  163.         // Private stuff: We want to serialize on updates on one thread
  164.         //
  165.         private static string GetCanonicalKey(string key)
  166.         {
  167.             if (key == null) {
  168.                 throw new ArgumentNullException("key");
  169.             }
  170.             try {
  171.                 Uri uri = new Uri(key);
  172.                 key = uri.GetParts(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.SafeUnescaped);
  173.                 new WebPermission(NetworkAccess.Connect, new Uri(key)).Demand();
  174.             }
  175.             catch (UriFormatException e) {
  176.                 throw new ArgumentException(SR.GetString(SR.net_mustbeuri, "key"), "key", e);
  177.             }
  178.             return key;
  179.         }
  180.     }
  181.    
  182. }

Developer Fusion