_SpnDictionary.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Net / System / Net / _SpnDictionary.cs / 1305376 / _SpnDictionary.cs

                            /*++ 
Copyright (c) Microsoft Corporation

Module Name:
 
    _SpnDictionary.cs
 
Abstract: 
    This internal class implements a static mutlithreaded dictionary for user-registered SPNs.
    An SPN is mapped based on a Uri prefix that contains scheme, host and port. 


Author:
 
    Alexei Vopilov    15-Nov-2003
 
Revision History: 

--*/ 

namespace System.Net {
    using System;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.Security.Permissions; 
 
    internal class SpnDictionary : StringDictionary {
 
        //
        //A Hashtable can support one writer and multiple readers concurrently
        //
 
        private Hashtable m_SyncTable = Hashtable.Synchronized(new Hashtable());
 
        // 
        //
        internal SpnDictionary():base() { 
        }
        //
        //
        // 
        public override int Count {
            get { 
                ExceptionHelper.WebPermissionUnrestricted.Demand(); 
                return m_SyncTable.Count;
            } 
        }
        //
        // We are thread safe
        // 
        public override bool IsSynchronized {
            get { 
                return true; 
            }
        } 
        //
        // Internal lookup, bypasses security checks
        //
        internal string InternalGet(string canonicalKey) 
        {
            int lastLength = 0; 
            string key = null; 

            // This lock is required to avoid getting InvalidOperationException 
            // because the collection was modified during enumeration. By design
            // a Synchronized Hashtable throws if modifications occur while an
            // enumeration is in progress. Manually locking the Hashtable to
            // prevent modification during enumeration is the best solution. 
            // Catching the exception and retrying could potentially never
            // succeed in the face of significant updates. 
            lock (m_SyncTable.SyncRoot) { 
                foreach (object o in m_SyncTable.Keys){
                    string s = (string) o; 
                    if(s != null && s.Length > lastLength){
                        if(String.Compare(s,0,canonicalKey,0,s.Length,StringComparison.OrdinalIgnoreCase) == 0){
                             lastLength = s.Length;
                             key = s; 
                        }
                    } 
                } 
            }
            return (key != null) ? (string)m_SyncTable[key]: null; 
        }

        internal void InternalSet(string canonicalKey, string spn)
        { 
            m_SyncTable[canonicalKey] = spn;
        } 
        // 
        // Public lookup method
        // 
        public override string this[string key] {
            get {
                key = GetCanonicalKey(key);
                return InternalGet(key); 
            }
            set { 
                key = GetCanonicalKey(key); 
                InternalSet(key, value);
            } 
        }
        //
        public override ICollection Keys {
            get { 
                ExceptionHelper.WebPermissionUnrestricted.Demand();
                return m_SyncTable.Keys; 
            } 
        }
        // 
        public override object SyncRoot {
            [HostProtection(Synchronization=true)]
            get {
                ExceptionHelper.WebPermissionUnrestricted.Demand(); 
                return m_SyncTable;
            } 
        } 
        //
        public override ICollection Values { 
            get {
                ExceptionHelper.WebPermissionUnrestricted.Demand();
                return m_SyncTable.Values;
            } 
        }
        // 
        public override void Add(string key, string value) { 
            key = GetCanonicalKey(key);
            m_SyncTable.Add(key, value); 
        }
        //
        public override void Clear() {
            ExceptionHelper.WebPermissionUnrestricted.Demand(); 
            m_SyncTable.Clear();
        } 
        // 
        public override bool ContainsKey(string key) {
            key = GetCanonicalKey(key); 
            return m_SyncTable.ContainsKey(key);
        }
        //
        public override bool ContainsValue(string value) { 
            ExceptionHelper.WebPermissionUnrestricted.Demand();
            return m_SyncTable.ContainsValue(value); 
        } 
        //
        public override void CopyTo(Array array, int index) { 
            ExceptionHelper.WebPermissionUnrestricted.Demand();
            m_SyncTable.CopyTo(array, index);
        }
        // 
        public override IEnumerator GetEnumerator() {
            ExceptionHelper.WebPermissionUnrestricted.Demand(); 
            return m_SyncTable.GetEnumerator(); 
        }
        // 
        public override void Remove(string key) {
            key = GetCanonicalKey(key);
            m_SyncTable.Remove(key);
        } 

        // 
        // Private stuff: We want to serialize on updates on one thread 
        //
        private static string GetCanonicalKey(string key) 
        {
            if( key == null ) {
                throw new ArgumentNullException("key");
            } 
            try {
                Uri uri = new Uri(key); 
                key = uri.GetParts(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.SafeUnescaped); 
                new WebPermission(NetworkAccess.Connect, new Uri(key)).Demand();
            } 
            catch(UriFormatException e) {
                throw new ArgumentException(SR.GetString(SR.net_mustbeuri, "key"), "key", e);
            }
            return key; 
        }
    } 
 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK