EndpointAddressProcessor.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 / EndpointAddressProcessor.cs / 1 / EndpointAddressProcessor.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Dispatcher
{ 
    using System;
    using System.ServiceModel.Channels; 
    using System.ServiceModel; 
    using System.Collections.Generic;
    using System.Diagnostics; 
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Xml; 
    using System.Xml.Schema;
 
    internal class EndpointAddressProcessor 
    {
        internal static readonly QNameKeyComparer QNameComparer = new QNameKeyComparer(); 

        // QName Attributes
        internal static readonly string XsiNs = XmlSchema.InstanceNamespace;
        internal const string SerNs = "http://schemas.microsoft.com/2003/10/Serialization/"; 
        internal const string TypeLN = "type";
        internal const string ItemTypeLN = "ItemType"; 
        internal const string FactoryTypeLN = "FactoryType"; 

        // Pooling 
        internal EndpointAddressProcessor next;

        StringBuilder builder;
        byte[] resultData; 

        internal EndpointAddressProcessor(int length) 
        { 
            this.builder = new StringBuilder();
            this.resultData = new byte[length]; 
        }

        internal EndpointAddressProcessor Next
        { 
            get
            { 
                return this.next; 
            }
            set 
            {
                this.next = value;
            }
        } 

        internal static string GetComparableForm(StringBuilder builder, XmlReader reader) 
        { 
            List attrSet = new List();
            int valueLength = -1; 
            while (!reader.EOF)
            {
                XmlNodeType type = reader.MoveToContent();
                switch (type) 
                {
                    case XmlNodeType.Element: 
                        CompleteValue(builder, valueLength); 
                        valueLength = -1;
 
                        builder.Append("<");
                        AppendString(builder, reader.LocalName);
                        builder.Append(":");
                        AppendString(builder, reader.NamespaceURI); 
                        builder.Append(" ");
 
                        // Scan attributes 
                        attrSet.Clear();
                        if (reader.MoveToFirstAttribute()) 
                        {
                            do
                            {
                                // Ignore namespaces 
                                if (reader.Prefix == "xmlns" || reader.Name == "xmlns")
                                { 
                                    continue; 
                                }
                                if (reader.LocalName == AddressingStrings.IsReferenceParameter && reader.NamespaceURI == Addressing10Strings.Namespace) 
                                {
                                    continue;  // ignore IsReferenceParameter
                                }
 
                                string val = reader.Value;
                                if ((reader.LocalName == TypeLN && reader.NamespaceURI == XsiNs) || 
                                    (reader.NamespaceURI == SerNs && (reader.LocalName == ItemTypeLN || reader.LocalName == FactoryTypeLN))) 
                                {
                                    string local, ns; 
                                    XmlUtil.ParseQName(reader, val, out local, out ns);
                                    val = local + "^" + local.Length.ToString(CultureInfo.InvariantCulture) + ":" + ns + "^" + ns.Length.ToString(CultureInfo.InvariantCulture);
                                }
                                else if (reader.LocalName == XD.UtilityDictionary.IdAttribute.Value && reader.NamespaceURI == XD.UtilityDictionary.Namespace.Value) 
                                {
                                    // ignore wsu:Id attributes added by security to sign the header 
                                    continue; 
                                }
                                attrSet.Add(new Attr(reader.LocalName, reader.NamespaceURI, val)); 
                            } while (reader.MoveToNextAttribute());
                        }
                        reader.MoveToElement();
 
                        if (attrSet.Count > 0)
                        { 
                            attrSet.Sort(); 
                            for (int i = 0; i < attrSet.Count; ++i)
                            { 
                                Attr a = attrSet[i];

                                AppendString(builder, a.local);
                                builder.Append(":"); 
                                AppendString(builder, a.ns);
                                builder.Append("=\""); 
                                AppendString(builder, a.val); 
                                builder.Append("\" ");
                            } 
                        }

                        if (reader.IsEmptyElement)
                            builder.Append(">");  // Should be the same as an empty tag. 
                        else
                            builder.Append(">"); 
                        break; 

                    case XmlNodeType.EndElement: 
                        CompleteValue(builder, valueLength);
                        valueLength = -1;
                        builder.Append("");
                        break; 

                    // Need to escape CDATA values 
                    case XmlNodeType.CDATA: 
                        CompleteValue(builder, valueLength);
                        valueLength = -1; 

                        builder.Append(""); 
                        break;
 
                    case XmlNodeType.SignificantWhitespace: 
                    case XmlNodeType.Text:
                        if (valueLength < 0) 
                            valueLength = builder.Length;

                        builder.Append(reader.Value);
                        break; 

                    default: 
                        // Do nothing 
                        break;
                } 
                reader.Read();
            }
            return builder.ToString();
        } 

        static void AppendString(StringBuilder builder, string s) 
        { 
            builder.Append(s);
            builder.Append("^"); 
            builder.Append(s.Length.ToString(CultureInfo.InvariantCulture));
        }

        static void CompleteValue(StringBuilder builder, int startLength) 
        {
            if (startLength < 0) 
                return; 

            int len = builder.Length - startLength; 
            builder.Append("^");
            builder.Append(len.ToString(CultureInfo.InvariantCulture));
        }
 
        internal void Clear(int length)
        { 
            if(this.resultData.Length == length) 
            {
                Array.Clear(this.resultData, 0, this.resultData.Length); 
            }
            else
            {
                this.resultData = new byte[length]; 
            }
        } 
 
        internal void ProcessHeaders(Message msg, Dictionary qnameLookup, Dictionary headerLookup)
        { 
            string key;
            HeaderBit[] bits;
            QName qname;
            MessageHeaders headers = msg.Headers; 
            for(int j = 0; j < headers.Count; ++j)
            { 
                qname.name = headers[j].Name; 
                qname.ns = headers[j].Namespace;
                if (headers.MessageVersion.Addressing == AddressingVersion.WSAddressing10 
                    && !headers[j].IsReferenceParameter)
                {
                    continue;
                } 
                if(qnameLookup.ContainsKey(qname))
                { 
                    builder.Remove(0, builder.Length); 
                    XmlReader reader = headers.GetReaderAtHeader(j).ReadSubtree();
                    reader.Read();  // Needed after call to ReadSubtree 
                    key = GetComparableForm(builder, reader);

                    if(headerLookup.TryGetValue(key, out bits))
                    { 
                        SetBit(bits);
                    } 
                } 
            }
        } 

        internal void SetBit(HeaderBit[] bits)
        {
            if(bits.Length == 1) 
            {
                this.resultData[bits[0].index] |= bits[0].mask; 
            } 
            else
            { 
                byte[] results = this.resultData;
                for(int i = 0; i < bits.Length; ++i)
                {
                    if((results[bits[i].index] & bits[i].mask) == 0) 
                    {
                        results[bits[i].index] |= bits[i].mask; 
                        break; 
                    }
                } 
            }
        }

        internal bool TestExact(byte[] exact) 
        {
            DiagnosticUtility.DebugAssert(this.resultData.Length == exact.Length, ""); 
 
            byte[] results = this.resultData;
            for(int i = 0; i < exact.Length; ++i) 
            {
                if(results[i] != exact[i])
                {
                    return false; 
                }
            } 
 
            return true;
        } 

        internal bool TestMask(byte[] mask)
        {
            if(mask == null) 
            {
                return true; 
            } 

            byte[] results = this.resultData; 
            for(int i = 0; i < mask.Length; ++i)
            {
                if((results[i] & mask[i]) != mask[i])
                { 
                    return false;
                } 
            } 

            return true; 
        }

        internal struct QName
        { 
            internal string name;
            internal string ns; 
        } 

        internal class QNameKeyComparer : IComparer, IEqualityComparer 
        {
            internal QNameKeyComparer()
            {
            } 

            public int Compare(QName x, QName y) 
            { 
                int i = string.CompareOrdinal(x.name, y.name);
                if(i != 0) 
                    return i;

                return string.CompareOrdinal(x.ns, y.ns);
            } 

            public bool Equals(QName x, QName y) 
            { 
                int i = string.CompareOrdinal(x.name, y.name);
                if(i != 0) 
                    return false;

                return string.CompareOrdinal(x.ns, y.ns) == 0;
            } 

            public int GetHashCode(QName obj) 
            { 
                return obj.name.GetHashCode() ^ obj.ns.GetHashCode();
            } 
        }

        internal struct HeaderBit
        { 
            internal int index;
            internal byte mask; 
 
            internal HeaderBit(int bitNum)
            { 
                this.index = bitNum / 8;
                this.mask = (byte)(1 << (bitNum % 8));
            }
 
            internal void AddToMask(ref byte[] mask)
            { 
                if(mask == null) 
                {
                    mask = new byte[this.index+1]; 
                }
                else if(mask.Length <= this.index)
                {
                    Array.Resize(ref mask, this.index+1); 
                }
 
                mask[this.index] |= this.mask; 
            }
        } 

        class Attr : IComparable
        {
            internal string local; 
            internal string ns;
            internal string val; 
            string key; 

            internal Attr(string l, string ns, string v) 
            {
                this.local = l;
                this.ns = ns;
                this.val = v; 
                this.key = ns + ":" + l;
            } 
 
            public int CompareTo(Attr a)
            { 
                return string.Compare(this.key, a.key, StringComparison.Ordinal);
            }
        }
    } 
}

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