MessageFilterTable.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Dispatcher / MessageFilterTable.cs / 1 / MessageFilterTable.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System;
    using System.ServiceModel.Channels; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Diagnostics;
    using System.ServiceModel.Diagnostics;
    using System.Runtime.Serialization;
 
    [DataContract]
    public class MessageFilterTable : IMessageFilterTable 
    { 
        Dictionary filterTypeMappings;
        Dictionary filters; 
        SortedBuffer tables;
        int defaultPriority;

        public MessageFilterTable() 
            : this(0)
        { 
        } 

        public MessageFilterTable(int defaultPriority) 
        {
            Init(defaultPriority);
        }
 
        [OnDeserializing]
        private void OnDeserializing(StreamingContext context) 
        { 
            Init(0);
        } 

        void Init(int defaultPriority)
        {
            CreateEmptyTables(); 
            this.defaultPriority = defaultPriority;
        } 
 
        public TFilterData this[MessageFilter filter]
        { 
            get
            {
                return this.filters[filter];
            } 
            set
            { 
                if(this.ContainsKey(filter)) 
                {
                    int p = this.GetPriority(filter); 
                    this.Remove(filter);
                    this.Add(filter, value, p);
                }
                else 
                {
                    this.Add(filter, value, this.defaultPriority); 
                } 
            }
        } 

        public int Count
        {
            get 
            {
                return this.filters.Count; 
            } 
        }
 
        [DataMember]
        public int DefaultPriority
        {
            get 
            {
                return this.defaultPriority; 
            } 
            set
            { 
                this.defaultPriority = value;
            }
        }
 
        [DataMember]
        Entry[] Entries 
        { 
            get
            { 
                Entry[] entries = new Entry[Count];
                int i = 0;
                foreach (KeyValuePair item in this.filters)
                { 
                    entries[i++] = new Entry(item.Key, item.Value, GetPriority(item.Key));
                } 
                return entries; 
            }
            set 
            {
                for (int i = 0; i < value.Length; ++i)
                {
                    Entry e = value[i]; 
                    Add(e.filter, e.data, e.priority);
                } 
            } 
        }
 
        public bool IsReadOnly
        {
            get
            { 
                return false;
            } 
        } 

        public ICollection Keys 
        {
            get
            {
                return this.filters.Keys; 
            }
        } 
 
        public ICollection Values
        { 
            get
            {
                return this.filters.Values;
            } 
        }
 
        public void Add(MessageFilter filter, TFilterData data) 
        {
            this.Add(filter, data, this.defaultPriority); 
        }

        public void Add(MessageFilter filter, TFilterData data, int priority)
        { 
            if(filter == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("filter"); 
            }
 
            if(this.filters.ContainsKey(filter))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("filter", SR.GetString(SR.FilterExists));
            } 

#pragma warning suppress 56506 // [....], PreSharp generates a false warning here 
            Type filterType = filter.GetType(); 
            Type tableType = null;
            IMessageFilterTable table = null; 

            if(this.filterTypeMappings.TryGetValue(filterType, out tableType))
            {
                for(int i = 0; i < this.tables.Count; ++i) 
                {
                    if(this.tables[i].priority == priority && this.tables[i].table.GetType().Equals(tableType)) 
                    { 
                        table = this.tables[i].table;
                        break; 
                    }
                }
                if(table == null)
                { 
                    table = CreateFilterTable(filter);
                    ValidateTable(table); 
                    if(!table.GetType().Equals(tableType)) 
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FilterTableTypeMismatch))); 
                    }
                    table.Add(filter, data);
                    this.tables.Add(new FilterTableEntry(priority, table));
                } 
                else
                { 
                    table.Add(filter, data); 
                }
            } 
            else
            {
                table = CreateFilterTable(filter);
                ValidateTable(table); 
                this.filterTypeMappings.Add(filterType, table.GetType());
 
                FilterTableEntry entry = new FilterTableEntry(priority, table); 
                int idx = this.tables.IndexOf(entry);
                if(idx >= 0) 
                {
                    table = this.tables[idx].table;
                }
                else 
                {
                    this.tables.Add(entry); 
                } 

                table.Add(filter, data); 
            }

            this.filters.Add(filter, data);
        } 

        public void Add(KeyValuePair item) 
        { 
            this.Add(item.Key, item.Value);
        } 

        public void Clear()
        {
            this.filters.Clear(); 
            this.tables.Clear();
        } 
 
        public bool Contains(KeyValuePair item)
        { 
            return ((ICollection>)this.filters).Contains(item);
        }

        public bool ContainsKey(MessageFilter filter) 
        {
            return this.filters.ContainsKey(filter); 
        } 

        public void CopyTo(KeyValuePair[] array, int arrayIndex) 
        {
            ((ICollection>)this.filters).CopyTo(array, arrayIndex);
        }
 
        void CreateEmptyTables()
        { 
            this.filterTypeMappings = new Dictionary(); 
            this.filters = new Dictionary();
            this.tables = new SortedBuffer(); 
        }

        protected virtual IMessageFilterTable CreateFilterTable(MessageFilter filter)
        { 
            IMessageFilterTable ft = filter.CreateFilterTable();
 
            if (ft == null) 
                return new SequentialMessageFilterTable();
 
            return ft;
        }

        IEnumerator IEnumerable.GetEnumerator() 
        {
            return this.GetEnumerator(); 
        } 

        public IEnumerator> GetEnumerator() 
        {
            return ((ICollection>)this.filters).GetEnumerator();
        }
 
        public int GetPriority(MessageFilter filter)
        { 
            TFilterData d = this.filters[filter]; 
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                if(this.tables[i].table.ContainsKey(filter))
                {
                    return this.tables[i].priority;
                } 
            }
 
 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperCritical(new InvalidOperationException(SR.GetString(SR.FilterTableInvalidForLookup)));
        } 

        public bool GetMatchingValue(Message message, out TFilterData data)
        {
            bool dataSet = false; 
            int pri = int.MinValue;
 
            data = default(TFilterData); 
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                // Watch for the end of a bucket
 				if (pri > this.tables[i].priority && dataSet)
				{
                    break; 
                }
                pri = this.tables[i].priority; 
 
                if(this.tables[i].table.GetMatchingValue(message, out data))
                { 
                    if(dataSet)
                    {
                        throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, null), message);
                    } 

                    dataSet = true; 
                } 
            }
 
            return dataSet;
        }

        internal bool GetMatchingValue(Message message, out TFilterData data, out bool addressMatched) 
        {
            bool dataSet = false; 
            int pri = int.MinValue; 
            data = default(TFilterData);
            addressMatched = false; 
            for(int i = 0; i < this.tables.Count; ++i)
            {
                // Watch for the end of a bucket
				if (pri > this.tables[i].priority && dataSet) 
				{
                    break; 
                } 
                pri = this.tables[i].priority;
 
                bool matchResult;
                IMessageFilterTable table = this.tables[i].table;
                AndMessageFilterTable andTable = table as AndMessageFilterTable;
                if (andTable != null) 
                {
                    bool addressResult; 
                    matchResult = andTable.GetMatchingValue(message, out data, out addressResult); 
                    addressMatched |= addressResult;
                } 
                else
                {
                    matchResult = table.GetMatchingValue(message, out data);
                } 

                if(matchResult) 
                { 
                    if(dataSet)
                    { 
                        throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, null), message);
                    }

                    addressMatched = true; 
                    dataSet = true;
                } 
            } 

            return dataSet; 
        }

        public bool GetMatchingValue(MessageBuffer buffer, out TFilterData data)
        { 
            bool dataSet = false;
            int pri = int.MinValue; 
            data = default(TFilterData); 
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                // Watch for the end of a bucket
 				if (pri > this.tables[i].priority && dataSet)
				{
                    break; 
                }
                pri = this.tables[i].priority; 
 
                if(this.tables[i].table.GetMatchingValue(buffer, out data))
                { 
                    if(dataSet)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, null));
                    } 

                    dataSet = true; 
                } 
            }
 
            return dataSet;
        }

        public bool GetMatchingValues(Message message, ICollection results) 
        {
            if (results == null) 
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
            } 
            int count = results.Count;
            int pri = int.MinValue;
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                // Watch for the end of a bucket
 				if (pri > this.tables[i].priority && count != results.Count) 
 				{ 
                    break;
                } 
                pri = this.tables[i].priority;
                this.tables[i].table.GetMatchingValues(message, results);
            }
 
            return count != results.Count;
        } 
 
        public bool GetMatchingValues(MessageBuffer buffer, ICollection results)
        { 
            if (results == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
            } 
            int count = results.Count;
            int pri = int.MinValue; 
            for(int i = 0; i < this.tables.Count; ++i) 
            {
                // Watch for the end of a bucket 
				if (pri > this.tables[i].priority && count != results.Count)
 				{
                    break;
                } 
                pri = this.tables[i].priority;
                this.tables[i].table.GetMatchingValues(buffer, results); 
            } 

            return count != results.Count; 
        }

        public bool GetMatchingFilter(Message message, out MessageFilter filter)
        { 
            MessageFilter f;
            int pri = int.MinValue; 
            filter = null; 
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                // Watch for the end of a bucket
				if (pri > this.tables[i].priority && filter != null)
				{
                    break; 
                }
                pri = this.tables[i].priority; 
 
                if(this.tables[i].table.GetMatchingFilter(message, out f))
                { 
                    if(filter == null)
                    {
                        filter = f;
                    } 
                    else
                    { 
                        Collection c = new Collection(); 
                        c.Add(filter);
                        c.Add(f); 
                        throw TraceUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, c), message);
                    }
                }
            } 

            return filter != null; 
        } 

        public bool GetMatchingFilter(MessageBuffer buffer, out MessageFilter filter) 
        {
            MessageFilter f;
            int pri = int.MinValue;
            filter = null; 
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                // Watch for the end of a bucket 
				if (pri > this.tables[i].priority && filter != null)
 				{ 
                    break;
                }
                pri = this.tables[i].priority;
 
                if(this.tables[i].table.GetMatchingFilter(buffer, out f))
                { 
                    if(filter == null) 
                    {
                        filter = f; 
                    }
                    else
                    {
                        Collection c = new Collection(); 
                        c.Add(filter);
                        c.Add(f); 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MultipleFilterMatchesException(SR.GetString(SR.FilterMultipleMatches), null, c)); 
                    }
                } 
            }

            return filter != null;
        } 

        public bool GetMatchingFilters(Message message, ICollection results) 
        { 
            if (results == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
            }
            int count = results.Count;
            int pri = int.MinValue; 
            for(int i = 0; i < this.tables.Count; ++i)
            { 
                // Watch for the end of a bucket 
                if(pri > this.tables[i].priority && count != results.Count)
                { 
                    break;
                }
                pri = this.tables[i].priority;
                this.tables[i].table.GetMatchingFilters(message, results); 
            }
 
            return count != results.Count; 
        }
 
        public bool GetMatchingFilters(MessageBuffer buffer, ICollection results)
        {
            if (results == null)
            { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("results");
            } 
            int count = results.Count; 
            int pri = int.MinValue;
            for(int i = 0; i < this.tables.Count; ++i) 
            {
                // Watch for the end of a bucket
				if (pri > this.tables[i].priority && count != results.Count)
 				{ 
                    break;
                } 
                pri = this.tables[i].priority; 
                this.tables[i].table.GetMatchingFilters(buffer, results);
            } 

            return count != results.Count;
        }
 
        public bool Remove(MessageFilter filter)
        { 
            for(int i = 0; i < this.tables.Count; ++i) 
            {
                if(this.tables[i].table.Remove(filter)) 
                {
                    if(this.tables[i].table.Count == 0)
                    {
                        this.tables.RemoveAt(i); 
                    }
                    return this.filters.Remove(filter); 
                } 
            }
            return false; 
        }

        public bool Remove(KeyValuePair item)
        { 
            if(((ICollection>)this.filters).Contains(item))
            { 
                return this.Remove(item.Key); 
            }
            return false; 
        }

        public bool TryGetValue(MessageFilter filter, out TFilterData data)
        { 
            return this.filters.TryGetValue(filter, out data);
        } 
 
        void ValidateTable(IMessageFilterTable table)
        { 
            Type t = this.GetType();
            if(t.IsInstanceOfType(table))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.FilterBadTableType))); 
            }
        } 
 
        ///////////////////////////////////////////////////
 
        struct FilterTableEntry
        {
            internal IMessageFilterTable table;
            internal int priority; 

            internal FilterTableEntry(int pri, IMessageFilterTable t) 
            { 
                this.priority = pri;
                this.table = t; 
            }
        }

        class TableEntryComparer : IComparer 
        {
            public TableEntryComparer() {} 
 
            public int Compare(FilterTableEntry x, FilterTableEntry y)
            { 
                // Highest priority first
                int p = y.priority.CompareTo(x.priority);
                if(p != 0)
                { 
                    return p;
                } 
 
                return x.table.GetType().FullName.CompareTo(y.table.GetType().FullName);
            } 

            public bool Equals(FilterTableEntry x, FilterTableEntry y)
            {
                // Highest priority first 
                int p = y.priority.CompareTo(x.priority);
                if(p != 0) 
                { 
                    return false;
                } 

                return x.table.GetType().FullName.Equals(y.table.GetType().FullName);
            }
 
            public int GetHashCode(FilterTableEntry table)
            { 
                return table.GetHashCode(); 
            }
        } 

        [DataContract]
        class Entry
        { 
            [DataMember(IsRequired = true)]
            internal MessageFilter filter; 
 
            [DataMember(IsRequired = true)]
            internal TFilterData data; 

            [DataMember(IsRequired = true)]
            internal int priority;
 
            internal Entry(MessageFilter f, TFilterData d, int p)
            { 
                filter = f; 
                data = d;
                priority = p; 
            }
        }
    }
} 

// 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