XmlQueryType.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / XmlUtils / System / Xml / Xsl / XmlQueryType.cs / 1 / XmlQueryType.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System.Collections.Generic;
using System.Diagnostics; 
using System.IO;
using System.Text;
using System.Xml.Schema;
 
namespace System.Xml.Xsl {
 
    ///  
    /// XmlQueryType contains static type information that describes the structure and possible values of dynamic
    /// instances of the Xml data model. 
    ///
    /// Every XmlQueryType is composed of a Prime type and a cardinality.  The Prime type itself may be a union
    /// between several item types.  The XmlQueryType IList implementation allows callers
    /// to enumerate the item types.  Other properties expose other information about the type. 
    /// 
    internal abstract class XmlQueryType : ListBase { 
        private static readonly BitMatrix TypeCodeDerivation; 
        private int hashCode;
 

        //-----------------------------------------------
        // Static Constructor
        //----------------------------------------------- 
        static XmlQueryType() {
            TypeCodeDerivation = new BitMatrix(BaseTypeCodes.Length); 
 
            // Build derivation matrix
            for (int i = 0; i < BaseTypeCodes.Length; i++) { 
                int nextAncestor = i;

                while (true) {
                    TypeCodeDerivation[i, nextAncestor] = true; 
                    if ((int)BaseTypeCodes[nextAncestor] == nextAncestor)
                        break; 
 
                    nextAncestor = (int)BaseTypeCodes[nextAncestor];
                } 
            }
        }

 
        //-----------------------------------------------
        // ItemType, OccurrenceIndicator Properties 
        //----------------------------------------------- 

        ///  
        /// Static data type code.  The dynamic type is guaranteed to be this type or a subtype of this code.
        /// This type code includes support for XQuery types that are not part of Xsd, such as Item,
        /// Node, AnyAtomicType, and Comment.
        ///  
        public abstract XmlTypeCode TypeCode { get; }
 
        ///  
        /// Set of alowed names for element, document{element}, attribute and PI
        /// Returns XmlQualifiedName.Wildcard for all other types 
        /// 
        public abstract XmlQualifiedNameTest NameTest { get; }

        ///  
        /// Static Xsd schema type.  The dynamic type is guaranteed to be this type or a subtype of this type.
        /// SchemaType will follow these rules: 
        ///   1. If TypeCode is an atomic type code, then SchemaType will be the corresponding non-null simple type 
        ///   2. If TypeCode is Element or Attribute, then SchemaType will be the non-null content type
        ///   3. If TypeCode is Item, Node, Comment, PI, Text, Document, Namespacce, None, then SchemaType will be AnyType 
        /// 
        public abstract XmlSchemaType SchemaType { get; }

        ///  
        /// Permits the element or document{element} node to have the nilled property.
        /// Returns false for all other types 
        ///  
        public abstract bool IsNillable { get; }
 
        /// 
        /// This property is always XmlNodeKindFlags.None unless TypeCode = XmlTypeCode.Node, in which case this
        /// property lists all node kinds that instances of this type may be.
        ///  
        public abstract XmlNodeKindFlags NodeKinds { get; }
 
        ///  
        /// If IsStrict is true, then the dynamic type is guaranteed to be the exact same as the static type, and
        /// will therefore never be a subtype of the static type. 
        /// 
        public abstract bool IsStrict { get; }

        ///  
        /// This property specifies the possible cardinalities that instances of this type may have.
        ///  
        public abstract XmlQueryCardinality Cardinality { get; } 

        ///  
        /// This property returns this type's Prime type, which is always cardinality One.
        /// 
        public abstract XmlQueryType Prime { get; }
 
        /// 
        /// True if dynamic data type of all items in this sequence is guaranteed to be not a subtype of Rtf. 
        ///  
        public abstract bool IsNotRtf { get; }
 
        /// 
        /// True if items in the sequence are guaranteed to be in document order, with no duplicates.
        /// 
        public abstract bool IsDod { get; } 

        ///  
        /// The XmlValueConverter maps each XmlQueryType to various Clr types which are capable of representing it. 
        /// 
        public abstract XmlValueConverter ClrMapping { get; } 


        //-----------------------------------------------
        // Type Operations 
        //-----------------------------------------------
 
        ///  
        /// Returns true if every possible dynamic instance of this type is also an instance of "baseType".
        ///  
        public bool IsSubtypeOf(XmlQueryType baseType) {
            XmlQueryType thisPrime, basePrime;

            // Check cardinality sub-typing rules 
            if (!(Cardinality <= baseType.Cardinality) || (!IsDod && baseType.IsDod))
                return false; 
 
            // Check early for common case that two types are the same object
            thisPrime = Prime; 
            basePrime = baseType.Prime;
            if ((object)thisPrime == (object)basePrime)
                return true;
 
            // Check early for common case that two prime types are item types
            if (thisPrime.Count == 1 && basePrime.Count == 1) 
                return thisPrime.IsSubtypeOfItemType(basePrime); 

            // Check that each item type in this type is a subtype of some item type in "baseType" 
            foreach (XmlQueryType thisItem in thisPrime) {
                bool match = false;

                foreach (XmlQueryType baseItem in basePrime) { 
                    if (thisItem.IsSubtypeOfItemType(baseItem)) {
                        match = true; 
                        break; 
                    }
                } 

                if (match == false)
                    return false;
            } 

            return true; 
        } 

        ///  
        /// Returns true if a dynamic instance (type None never has an instance) of this type can never be a subtype of "baseType".
        /// 
        public bool NeverSubtypeOf(XmlQueryType baseType) {
            // Check cardinalities 
            if (Cardinality.NeverSubset(baseType.Cardinality))
                return true; 
 
            // If both this type and "other" type might be empty, it doesn't matter what the prime types are
            if (MaybeEmpty && baseType.MaybeEmpty) 
                return false;

            // None is subtype of every other type
            if (Count == 0) 
                return false;
 
            // Check item types 
            foreach (XmlQueryType typThis in this) {
                foreach (XmlQueryType typThat in baseType) { 
                    if (typThis.HasIntersectionItemType(typThat))
                        return false;
                }
            } 

            return true; 
        } 

        ///  
        /// Strongly-typed Equals that returns true if this type and "that" type are equivalent.
        /// 
        public bool Equals(XmlQueryType that) {
            if (that == null) 
                return false;
 
            // Check cardinality 
            if (Cardinality != that.Cardinality || IsDod != that.IsDod)
                return false; 

            // Check early for common case that two types are the same object
            XmlQueryType thisPrime = Prime;
            XmlQueryType thatPrime = that.Prime; 
            if ((object)thisPrime == (object)thatPrime)
                return true; 
 
            // Check that count of item types is equal
            if (thisPrime.Count != thatPrime.Count) 
                return false;

            // Check early for common case that two prime types are item types
            if (thisPrime.Count == 1) { 
                return (thisPrime.TypeCode == thatPrime.TypeCode &&
                        thisPrime.NameTest == thatPrime.NameTest && 
                        thisPrime.SchemaType == thatPrime.SchemaType && 
                        thisPrime.IsStrict == thatPrime.IsStrict &&
                        thisPrime.IsNotRtf == thatPrime.IsNotRtf); 
            }


            // Check that each item type in this type is equal to some item type in "baseType" 
            // (string | int) should be the same type as (int | string)
            foreach (XmlQueryType thisItem in this) { 
                bool match = false; 

                foreach (XmlQueryType thatItem in that) { 
                    if (thisItem.TypeCode == thatItem.TypeCode &&
                        thisItem.NameTest == thatItem.NameTest &&
                        thisItem.SchemaType == thatItem.SchemaType &&
                        thisItem.IsStrict == thatItem.IsStrict && 
                        thisItem.IsNotRtf == thatItem.IsNotRtf) {
                        // Found match so proceed to next type 
                        match = true; 
                        break;
                    } 
                }

                if (match == false)
                    return false; 
            }
 
            return true; 
        }
 
        /// 
        /// Overload == operator to call Equals rather than do reference equality.
        /// 
        public static bool operator == (XmlQueryType left, XmlQueryType right) { 
            if ((object) left == null)
                return ((object) right == null); 
 
            return left.Equals(right);
        } 

        /// 
        /// Overload != operator to call Equals rather than do reference inequality.
        ///  
        public static bool operator != (XmlQueryType left, XmlQueryType right) {
            if ((object) left == null) 
                return ((object) right != null); 

           return !left.Equals(right); 
        }


        //----------------------------------------------- 
        // Convenience Properties
        //----------------------------------------------- 
 
        /// 
        /// True if dynamic cardinality of this sequence is guaranteed to be 0. 
        /// 
        public bool IsEmpty {
            get { return Cardinality <= XmlQueryCardinality.Zero; }
        } 

        ///  
        /// True if dynamic cardinality of this sequence is guaranteed to be 1. 
        /// 
        public bool IsSingleton { 
            get { return Cardinality <= XmlQueryCardinality.One; }
        }

        ///  
        /// True if dynamic cardinality of this sequence might be 0.
        ///  
        public bool MaybeEmpty { 
            get { return XmlQueryCardinality.Zero <= Cardinality; }
        } 

        /// 
        /// True if dynamic cardinality of this sequence might be >1.
        ///  
        public bool MaybeMany {
            get { return XmlQueryCardinality.More <= Cardinality; } 
        } 

        ///  
        /// True if dynamic data type of all items in this sequence is guaranteed to be a subtype of Node.
        /// Equivalent to calling IsSubtypeOf(TypeFactory.NodeS).
        /// 
        public bool IsNode { 
            get { return (TypeCodeToFlags[(int)TypeCode] & TypeFlags.IsNode) != 0; }
        } 
 
        /// 
        /// True if dynamic data type of all items in this sequence is guaranteed to be a subtype of AnyAtomicType. 
        /// Equivalent to calling IsSubtypeOf(TypeFactory.AnyAtomicTypeS).
        /// 
        public bool IsAtomicValue {
            get { return (TypeCodeToFlags[(int)TypeCode] & TypeFlags.IsAtomicValue) != 0; } 
        }
 
        ///  
        /// True if dynamic data type of all items in this sequence is guaranteed to be a subtype of Decimal, Double, or Float.
        /// Equivalent to calling IsSubtypeOf(TypeFactory.NumericS). 
        /// 
        public bool IsNumeric {
            get { return (TypeCodeToFlags[(int)TypeCode] & TypeFlags.IsNumeric) != 0; }
        } 

 
        //----------------------------------------------- 
        // System.Object implementation
        //----------------------------------------------- 

        /// 
        /// True if "obj" is an XmlQueryType, and this type is the exact same static type.
        ///  
        public override bool Equals(object obj) {
            XmlQueryType that = obj as XmlQueryType; 
 
            if (that == null)
                return false; 

            return Equals(that);
        }
 
        /// 
        /// Return hash code of this instance. 
        ///  
        public override int GetHashCode() {
            if (this.hashCode == 0) { 
                int hash;
                XmlSchemaType schemaType;

                hash = (int)TypeCode; 

                schemaType = SchemaType; 
                if (schemaType != null) 
                    hash += (hash << 7) ^ schemaType.GetHashCode();
 
                hash += (hash << 7) ^ (int)NodeKinds;
                hash += (hash << 7) ^ Cardinality.GetHashCode();
                hash += (hash << 7) ^ (IsStrict ? 1 : 0);
 
                // Mix hash code a bit more
                hash -= hash >> 17; 
                hash -= hash >> 11; 
                hash -= hash >> 5;
 
                // Save hashcode.  Don't save 0, so that it won't ever be recomputed.
                this.hashCode = (hash == 0) ? 1 : hash;
            }
 
            return this.hashCode;
        } 
 
        /// 
        /// Return a user-friendly string representation of the XmlQueryType. 
        /// 
        public override string ToString() {
            return ToString("G");
        } 

        ///  
        /// Return a string representation of the XmlQueryType using the specified format.  The following formats are 
        /// supported:
        /// 
        ///   "G" (General): This is the default mode, and is used if no other format is recognized.  This format is
        ///                  easier to read than the canonical format, since it excludes redundant information.
        ///                  (e.g. element instead of element(*, xs:anyType))
        /// 
        ///   "X" (XQuery): Return the canonical XQuery representation, which excludes Qil specific information and
        ///                 includes extra, redundant information, such as fully specified types. 
        ///                 (e.g. element(*, xs:anyType) instead of element) 
        ///
        ///   "S" (Serialized): This format is used to serialize parts of the type which can be serialized easily, in 
        ///                     a format that is easy to parse.  Only the cardinality, type code, and strictness flag
        ///                     are serialized.  User-defined type information and element/attribute content types
        ///                     are lost.
        ///                     (e.g. One;Attribute|String|Int;true) 
        ///
        ///  
        public string ToString(string format) { 
            string[] sa;
            StringBuilder sb; 
            bool isXQ;

            if (format == "S") {
                sb = new StringBuilder(); 
                sb.Append(Cardinality.ToString(format));
                sb.Append(';'); 
 
                for (int i = 0; i < Count; i++) {
                    if (i != 0) 
                        sb.Append("|");
                    sb.Append(this[i].TypeCode.ToString());
                }
 
                sb.Append(';');
                sb.Append(IsStrict); 
                return sb.ToString(); 
            }
 
            isXQ = (format == "X");

            if (Cardinality ==  XmlQueryCardinality.None) {
                return "none"; 
            }
            else if (Cardinality == XmlQueryCardinality.Zero) { 
                return "empty"; 
            }
 
            switch (Count) {
                case 0:
                    // This assert depends on the way we are going to represent None
                    // Debug.Assert(false); 
                    return "none" + Cardinality.ToString();
                case 1: 
                    return this[0].ItemTypeToString(isXQ) + Cardinality.ToString(); 
            }
 
            sa = new string[Count];
            for (int i = 0; i < Count; i++)
                sa[i] = this[i].ItemTypeToString(isXQ);
 
            Array.Sort(sa);
 
            sb = new StringBuilder(); 
            sb.Append("(");
            sb.Append(sa[0]); 
            for (int i = 1; i < sa.Length; i++) {
                sb.Append(" | ");
                sb.Append(sa[i]);
            } 

            sb.Append(")"); 
            sb.Append(Cardinality.ToString()); 

            if (!isXQ && IsDod) 
                sb.Append('#');

            return sb.ToString();
        } 

 
        //----------------------------------------------- 
        // Serialization
        //----------------------------------------------- 

        /// 
        /// Serialize the object to BinaryWriter.
        ///  
        public abstract void GetObjectData(BinaryWriter writer);
 
        //----------------------------------------------- 
        // Helpers
        //----------------------------------------------- 

        /// 
        /// Returns true if this item type is a subtype of another item type.
        ///  
        private bool IsSubtypeOfItemType(XmlQueryType baseType) {
            Debug.Assert(Count == 1 && IsSingleton, "This method should only be called for item types."); 
            Debug.Assert(baseType.Count == 1 && baseType.IsSingleton, "This method should only be called for item types."); 
            XmlSchemaType baseSchemaType = baseType.SchemaType;
 
            if (TypeCode != baseType.TypeCode) {
                // If "baseType" is strict, then IsSubtypeOf must be false
                if (baseType.IsStrict)
                    return false; 

                // If type codes are not the same, then IsSubtypeOf can return true *only* if "baseType" is a built-in type 
                XmlSchemaType builtInType = XmlSchemaType.GetBuiltInSimpleType(baseType.TypeCode); 
                if (builtInType != null && baseSchemaType != builtInType)
                    return false; 

                // Now check whether TypeCode is derived from baseType.TypeCode
                return TypeCodeDerivation[TypeCode, baseType.TypeCode];
            } 
            else if (baseType.IsStrict) {
                // only atomic values can be strict 
                Debug.Assert(IsAtomicValue && baseType.IsAtomicValue); 

                // If schema types are not the same, then IsSubtype is false if "baseType" is strict 
                return IsStrict && SchemaType == baseSchemaType;
            }
            else {
                // Otherwise, check derivation tree 
                return (IsNotRtf || !baseType.IsNotRtf) && (IsDod || !baseType.IsDod) && NameTest.IsSubsetOf(baseType.NameTest) &&
                       (baseSchemaType == XmlSchemaComplexType.AnyType || XmlSchemaType.IsDerivedFrom(SchemaType, baseSchemaType, /* exept:*/XmlSchemaDerivationMethod.Empty)) && 
                       (!IsNillable || baseType.IsNillable); 
            }
        } 

        /// 
        /// Returns true if the intersection between this item type and "other" item type is not empty.
        ///  
        private bool HasIntersectionItemType(XmlQueryType other) {
            Debug.Assert(this.Count == 1 && this.IsSingleton, "this should be an item"); 
            Debug.Assert(other.Count == 1 && other.IsSingleton, "other should be an item"); 

            if (this.TypeCode == other.TypeCode && (this.NodeKinds & (XmlNodeKindFlags.Document | XmlNodeKindFlags.Element | XmlNodeKindFlags.Attribute)) != 0) { 
                if (this.TypeCode == XmlTypeCode.Node)
                    return true;

                // Intersect name tests 
                if (!this.NameTest.HasIntersection(other.NameTest))
                    return false; 
 
                if (!XmlSchemaType.IsDerivedFrom(this.SchemaType, other.SchemaType, /* exept:*/XmlSchemaDerivationMethod.Empty) &&
                    !XmlSchemaType.IsDerivedFrom(other.SchemaType, this.SchemaType, /* exept:*/XmlSchemaDerivationMethod.Empty)) { 
                    return false;
                }

                return true; 
            }
            else if (this.IsSubtypeOf(other) || other.IsSubtypeOf(this)) { 
                return true; 
            }
 
            return false;
        }

        ///  
        /// Return the string representation of an item type (cannot be a union or a sequence).
        ///  
        private string ItemTypeToString(bool isXQ) { 
            string s;
            Debug.Assert(Count == 1, "Do not pass a Union type to this method."); 
            Debug.Assert(IsSingleton, "Do not pass a Sequence type to this method.");

            if (IsNode) {
                // Map TypeCode to string 
                s = TypeNames[(int) TypeCode];
 
                switch (TypeCode) { 
                    case XmlTypeCode.Document:
                        if (!isXQ) 
                            goto case XmlTypeCode.Element;

                        s += "{(element" + NameAndType(true) + "?&text?&comment?&processing-instruction?)*}";
                        break; 

                    case XmlTypeCode.Element: 
                    case XmlTypeCode.Attribute: 
                        s += NameAndType(isXQ);
                        break; 
                }
            }
            else if (SchemaType != XmlSchemaComplexType.AnyType) {
                // Get QualifiedName from SchemaType 
                if (SchemaType.QualifiedName.IsEmpty)
                    s = "<:" + TypeNames[(int) TypeCode]; 
                else 
                    s = QNameToString(SchemaType.QualifiedName);
            } 
            else {
                // Map TypeCode to string
                s = TypeNames[(int) TypeCode];
            } 

            if (!isXQ && IsStrict) 
                s += "="; 

            return s; 
        }

        /// 
        /// Return "(name-test, type-name)" for this type.  If isXQ is false, normalize xs:anySimpleType and 
        /// xs:anyType to "*".
        ///  
        private string NameAndType(bool isXQ) { 
            string nodeName = NameTest.ToString();
            string typeName = "*"; 

            if (SchemaType.QualifiedName.IsEmpty) {
                typeName = "typeof(" + nodeName + ")";
            } 
            else {
                if (isXQ || (SchemaType != XmlSchemaComplexType.AnyType && SchemaType != DatatypeImplementation.AnySimpleType)) 
                    typeName = QNameToString(SchemaType.QualifiedName); 
            }
 
            if (IsNillable) {
                typeName += " nillable";
            }
 
            // Normalize "(*, *)" to ""
            if (nodeName == "*" && typeName == "*") 
                return ""; 

            return "(" + nodeName + ", " + typeName + ")"; 
        }

        /// 
        /// Convert an XmlQualifiedName to a string, using somewhat different rules than XmlQualifiedName.ToString(): 
        ///   1. Empty QNames are assumed to be wildcard names, so return "*"
        ///   2. Recognize the built-in xs: and xdt: namespaces and print the short prefix rather than the long namespace 
        ///   3. Use brace characters "{", "}" around the namespace portion of the QName 
        /// 
        private static string QNameToString(XmlQualifiedName name) { 
            if (name.IsEmpty) {
                return "*";
            }
            else if (name.Namespace.Length == 0) { 
                return name.Name;
            } 
            else if (name.Namespace == XmlReservedNs.NsXs) { 
                return "xs:" + name.Name;
            } 
            else if (name.Namespace == XmlReservedNs.NsXQueryDataType) {
                return "xdt:" + name.Name;
            }
            else { 
                return "{" + name.Namespace + "}" + name.Name;
            } 
        } 

        #region TypeFlags 
        private enum TypeFlags {
            None = 0,
            IsNode = 1,
            IsAtomicValue = 2, 
            IsNumeric = 4,
        } 
        #endregion 

        #region  TypeCodeToFlags 
        private static readonly TypeFlags[] TypeCodeToFlags = {
                /* XmlTypeCode.None                  */ TypeFlags.IsNode | TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Item                  */ TypeFlags.None,
                /* XmlTypeCode.Node                  */ TypeFlags.IsNode, 
                /* XmlTypeCode.Document              */ TypeFlags.IsNode,
                /* XmlTypeCode.Element               */ TypeFlags.IsNode, 
                /* XmlTypeCode.Attribute             */ TypeFlags.IsNode, 
                /* XmlTypeCode.Namespace             */ TypeFlags.IsNode,
                /* XmlTypeCode.ProcessingInstruction */ TypeFlags.IsNode, 
                /* XmlTypeCode.Comment               */ TypeFlags.IsNode,
                /* XmlTypeCode.Text                  */ TypeFlags.IsNode,
                /* XmlTypeCode.AnyAtomicType         */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.UntypedAtomic         */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.String                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Boolean               */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Decimal               */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.Float                 */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Double                */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.Duration              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.DateTime              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Time                  */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Date                  */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.GYearMonth            */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.GYear                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.GMonthDay             */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.GDay                  */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.GMonth                */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.HexBinary             */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Base64Binary          */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.AnyUri                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.QName                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Notation              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.NormalizedString      */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Token                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Language              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.NmToken               */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Name                  */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.NCName                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Id                    */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Idref                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Entity                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Integer               */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.NonPositiveInteger    */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.NegativeInteger       */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Long                  */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.Int                   */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Short                 */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Byte                  */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.NonNegativeInteger    */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.UnsignedLong          */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.UnsignedInt           */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.UnsignedShort         */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.UnsignedByte          */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.PositiveInteger       */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.YearMonthDuration     */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.DayTimeDuration       */ TypeFlags.IsAtomicValue,
        };
 
        private static readonly XmlTypeCode[] BaseTypeCodes = {
            /* None                        */ XmlTypeCode.None, 
            /* Item                        */ XmlTypeCode.Item, 
            /* Node                        */ XmlTypeCode.Item,
            /* Document                    */ XmlTypeCode.Node, 
            /* Element                     */ XmlTypeCode.Node,
            /* Attribute                   */ XmlTypeCode.Node,
            /* Namespace                   */ XmlTypeCode.Node,
            /* ProcessingInstruction       */ XmlTypeCode.Node, 
            /* Comment                     */ XmlTypeCode.Node,
            /* Text                        */ XmlTypeCode.Node, 
            /* AnyAtomicType               */ XmlTypeCode.Item, 
            /* UntypedAtomic               */ XmlTypeCode.AnyAtomicType,
            /* String                      */ XmlTypeCode.AnyAtomicType, 
            /* Boolean                     */ XmlTypeCode.AnyAtomicType,
            /* Decimal                     */ XmlTypeCode.AnyAtomicType,
            /* Float                       */ XmlTypeCode.AnyAtomicType,
            /* Double                      */ XmlTypeCode.AnyAtomicType, 
            /* Duration                    */ XmlTypeCode.AnyAtomicType,
            /* DateTime                    */ XmlTypeCode.AnyAtomicType, 
            /* Time                        */ XmlTypeCode.AnyAtomicType, 
            /* Date                        */ XmlTypeCode.AnyAtomicType,
            /* GYearMonth                  */ XmlTypeCode.AnyAtomicType, 
            /* GYear                       */ XmlTypeCode.AnyAtomicType,
            /* GMonthDay                   */ XmlTypeCode.AnyAtomicType,
            /* GDay                        */ XmlTypeCode.AnyAtomicType,
            /* GMonth                      */ XmlTypeCode.AnyAtomicType, 
            /* HexBinary                   */ XmlTypeCode.AnyAtomicType,
            /* Base64Binary                */ XmlTypeCode.AnyAtomicType, 
            /* AnyUri                      */ XmlTypeCode.AnyAtomicType, 
            /* QName                       */ XmlTypeCode.AnyAtomicType,
            /* Notation                    */ XmlTypeCode.AnyAtomicType, 
            /* NormalizedString            */ XmlTypeCode.String,
            /* Token                       */ XmlTypeCode.NormalizedString,
            /* Language                    */ XmlTypeCode.Token,
            /* NmToken                     */ XmlTypeCode.Token, 
            /* Name                        */ XmlTypeCode.Token,
            /* NCName                      */ XmlTypeCode.Name, 
            /* Id                          */ XmlTypeCode.NCName, 
            /* Idref                       */ XmlTypeCode.NCName,
            /* Entity                      */ XmlTypeCode.NCName, 
            /* Integer                     */ XmlTypeCode.Decimal,
            /* NonPositiveInteger          */ XmlTypeCode.Integer,
            /* NegativeInteger             */ XmlTypeCode.NonPositiveInteger,
            /* Long                        */ XmlTypeCode.Integer, 
            /* Int                         */ XmlTypeCode.Long,
            /* Short                       */ XmlTypeCode.Int, 
            /* Byte                        */ XmlTypeCode.Short, 
            /* NonNegativeInteger          */ XmlTypeCode.Integer,
            /* UnsignedLong                */ XmlTypeCode.NonNegativeInteger, 
            /* UnsignedInt                 */ XmlTypeCode.UnsignedLong,
            /* UnsignedShort               */ XmlTypeCode.UnsignedInt,
            /* UnsignedByte                */ XmlTypeCode.UnsignedShort,
            /* PositiveInteger             */ XmlTypeCode.NonNegativeInteger, 
            /* YearMonthDuration           */ XmlTypeCode.Duration,
            /* DayTimeDuration             */ XmlTypeCode.Duration, 
        }; 

        private static readonly string[] TypeNames = { 
            /* None                        */ "none",
            /* Item                        */ "item",
            /* Node                        */ "node",
            /* Document                    */ "document", 
            /* Element                     */ "element",
            /* Attribute                   */ "attribute", 
            /* Namespace                   */ "namespace", 
            /* ProcessingInstruction       */ "processing-instruction",
            /* Comment                     */ "comment", 
            /* Text                        */ "text",
            /* AnyAtomicType               */ "xdt:anyAtomicType",
            /* UntypedAtomic               */ "xdt:untypedAtomic",
            /* String                      */ "xs:string", 
            /* Boolean                     */ "xs:boolean",
            /* Decimal                     */ "xs:decimal", 
            /* Float                       */ "xs:float", 
            /* Double                      */ "xs:double",
            /* Duration                    */ "xs:duration", 
            /* DateTime                    */ "xs:dateTime",
            /* Time                        */ "xs:time",
            /* Date                        */ "xs:date",
            /* GYearMonth                  */ "xs:gYearMonth", 
            /* GYear                       */ "xs:gYear",
            /* GMonthDay                   */ "xs:gMonthDay", 
            /* GDay                        */ "xs:gDay", 
            /* GMonth                      */ "xs:gMonth",
            /* HexBinary                   */ "xs:hexBinary", 
            /* Base64Binary                */ "xs:base64Binary",
            /* AnyUri                      */ "xs:anyUri",
            /* QName                       */ "xs:QName",
            /* Notation                    */ "xs:NOTATION", 
            /* NormalizedString            */ "xs:normalizedString",
            /* Token                       */ "xs:token", 
            /* Language                    */ "xs:language", 
            /* NmToken                     */ "xs:NMTOKEN",
            /* Name                        */ "xs:Name", 
            /* NCName                      */ "xs:NCName",
            /* Id                          */ "xs:ID",
            /* Idref                       */ "xs:IDREF",
            /* Entity                      */ "xs:ENTITY", 
            /* Integer                     */ "xs:integer",
            /* NonPositiveInteger          */ "xs:nonPositiveInteger", 
            /* NegativeInteger             */ "xs:negativeInteger", 
            /* Long                        */ "xs:long",
            /* Int                         */ "xs:int", 
            /* Short                       */ "xs:short",
            /* Byte                        */ "xs:byte",
            /* NonNegativeInteger          */ "xs:nonNegativeInteger",
            /* UnsignedLong                */ "xs:unsignedLong", 
            /* UnsignedInt                 */ "xs:unsignedInt",
            /* UnsignedShort               */ "xs:unsignedShort", 
            /* UnsignedByte                */ "xs:unsignedByte", 
            /* PositiveInteger             */ "xs:positiveInteger",
            /* YearMonthDuration           */ "xdt:yearMonthDuration", 
            /* DayTimeDuration             */ "xdt:dayTimeDuration",
        };
        #endregion
 
        /// 
        /// Implements an NxN bit matrix. 
        ///  
        private sealed class BitMatrix {
            private ulong[] bits; 

            /// 
            /// Create NxN bit matrix, where N = count.
            ///  
            public BitMatrix(int count) {
                Debug.Assert(count < 64, "BitMatrix currently only handles up to 64x64 matrix."); 
                bits = new ulong[count]; 
            }
 
//            /// 
//            /// Return the number of rows and columns in the matrix.
//            /// 
//            public int Size { 
//                get { return bits.Length; }
//            } 
// 
            /// 
            /// Get or set a bit in the matrix at position (index1, index2). 
            /// 
            public bool this[int index1, int index2] {
                get {
                    Debug.Assert(index1 < bits.Length && index2 < bits.Length, "Index out of range."); 
                    return (bits[index1] & ((ulong)1 << index2)) != 0;
                } 
                set { 
                    Debug.Assert(index1 < bits.Length && index2 < bits.Length, "Index out of range.");
                    if (value == true) { 
                        bits[index1] |= (ulong)1 << index2;
                    }
                    else {
                        bits[index1] &= ~((ulong)1 << index2); 
                    }
                } 
            } 

            ///  
            /// Strongly typed indexer.
            /// 
            public bool this[XmlTypeCode index1, XmlTypeCode index2] {
                get { 
                    return this[(int)index1, (int)index2];
                } 
//                set { 
//                    this[(int)index1, (int)index2] = value;
//                } 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
using System.Collections.Generic;
using System.Diagnostics; 
using System.IO;
using System.Text;
using System.Xml.Schema;
 
namespace System.Xml.Xsl {
 
    ///  
    /// XmlQueryType contains static type information that describes the structure and possible values of dynamic
    /// instances of the Xml data model. 
    ///
    /// Every XmlQueryType is composed of a Prime type and a cardinality.  The Prime type itself may be a union
    /// between several item types.  The XmlQueryType IList implementation allows callers
    /// to enumerate the item types.  Other properties expose other information about the type. 
    /// 
    internal abstract class XmlQueryType : ListBase { 
        private static readonly BitMatrix TypeCodeDerivation; 
        private int hashCode;
 

        //-----------------------------------------------
        // Static Constructor
        //----------------------------------------------- 
        static XmlQueryType() {
            TypeCodeDerivation = new BitMatrix(BaseTypeCodes.Length); 
 
            // Build derivation matrix
            for (int i = 0; i < BaseTypeCodes.Length; i++) { 
                int nextAncestor = i;

                while (true) {
                    TypeCodeDerivation[i, nextAncestor] = true; 
                    if ((int)BaseTypeCodes[nextAncestor] == nextAncestor)
                        break; 
 
                    nextAncestor = (int)BaseTypeCodes[nextAncestor];
                } 
            }
        }

 
        //-----------------------------------------------
        // ItemType, OccurrenceIndicator Properties 
        //----------------------------------------------- 

        ///  
        /// Static data type code.  The dynamic type is guaranteed to be this type or a subtype of this code.
        /// This type code includes support for XQuery types that are not part of Xsd, such as Item,
        /// Node, AnyAtomicType, and Comment.
        ///  
        public abstract XmlTypeCode TypeCode { get; }
 
        ///  
        /// Set of alowed names for element, document{element}, attribute and PI
        /// Returns XmlQualifiedName.Wildcard for all other types 
        /// 
        public abstract XmlQualifiedNameTest NameTest { get; }

        ///  
        /// Static Xsd schema type.  The dynamic type is guaranteed to be this type or a subtype of this type.
        /// SchemaType will follow these rules: 
        ///   1. If TypeCode is an atomic type code, then SchemaType will be the corresponding non-null simple type 
        ///   2. If TypeCode is Element or Attribute, then SchemaType will be the non-null content type
        ///   3. If TypeCode is Item, Node, Comment, PI, Text, Document, Namespacce, None, then SchemaType will be AnyType 
        /// 
        public abstract XmlSchemaType SchemaType { get; }

        ///  
        /// Permits the element or document{element} node to have the nilled property.
        /// Returns false for all other types 
        ///  
        public abstract bool IsNillable { get; }
 
        /// 
        /// This property is always XmlNodeKindFlags.None unless TypeCode = XmlTypeCode.Node, in which case this
        /// property lists all node kinds that instances of this type may be.
        ///  
        public abstract XmlNodeKindFlags NodeKinds { get; }
 
        ///  
        /// If IsStrict is true, then the dynamic type is guaranteed to be the exact same as the static type, and
        /// will therefore never be a subtype of the static type. 
        /// 
        public abstract bool IsStrict { get; }

        ///  
        /// This property specifies the possible cardinalities that instances of this type may have.
        ///  
        public abstract XmlQueryCardinality Cardinality { get; } 

        ///  
        /// This property returns this type's Prime type, which is always cardinality One.
        /// 
        public abstract XmlQueryType Prime { get; }
 
        /// 
        /// True if dynamic data type of all items in this sequence is guaranteed to be not a subtype of Rtf. 
        ///  
        public abstract bool IsNotRtf { get; }
 
        /// 
        /// True if items in the sequence are guaranteed to be in document order, with no duplicates.
        /// 
        public abstract bool IsDod { get; } 

        ///  
        /// The XmlValueConverter maps each XmlQueryType to various Clr types which are capable of representing it. 
        /// 
        public abstract XmlValueConverter ClrMapping { get; } 


        //-----------------------------------------------
        // Type Operations 
        //-----------------------------------------------
 
        ///  
        /// Returns true if every possible dynamic instance of this type is also an instance of "baseType".
        ///  
        public bool IsSubtypeOf(XmlQueryType baseType) {
            XmlQueryType thisPrime, basePrime;

            // Check cardinality sub-typing rules 
            if (!(Cardinality <= baseType.Cardinality) || (!IsDod && baseType.IsDod))
                return false; 
 
            // Check early for common case that two types are the same object
            thisPrime = Prime; 
            basePrime = baseType.Prime;
            if ((object)thisPrime == (object)basePrime)
                return true;
 
            // Check early for common case that two prime types are item types
            if (thisPrime.Count == 1 && basePrime.Count == 1) 
                return thisPrime.IsSubtypeOfItemType(basePrime); 

            // Check that each item type in this type is a subtype of some item type in "baseType" 
            foreach (XmlQueryType thisItem in thisPrime) {
                bool match = false;

                foreach (XmlQueryType baseItem in basePrime) { 
                    if (thisItem.IsSubtypeOfItemType(baseItem)) {
                        match = true; 
                        break; 
                    }
                } 

                if (match == false)
                    return false;
            } 

            return true; 
        } 

        ///  
        /// Returns true if a dynamic instance (type None never has an instance) of this type can never be a subtype of "baseType".
        /// 
        public bool NeverSubtypeOf(XmlQueryType baseType) {
            // Check cardinalities 
            if (Cardinality.NeverSubset(baseType.Cardinality))
                return true; 
 
            // If both this type and "other" type might be empty, it doesn't matter what the prime types are
            if (MaybeEmpty && baseType.MaybeEmpty) 
                return false;

            // None is subtype of every other type
            if (Count == 0) 
                return false;
 
            // Check item types 
            foreach (XmlQueryType typThis in this) {
                foreach (XmlQueryType typThat in baseType) { 
                    if (typThis.HasIntersectionItemType(typThat))
                        return false;
                }
            } 

            return true; 
        } 

        ///  
        /// Strongly-typed Equals that returns true if this type and "that" type are equivalent.
        /// 
        public bool Equals(XmlQueryType that) {
            if (that == null) 
                return false;
 
            // Check cardinality 
            if (Cardinality != that.Cardinality || IsDod != that.IsDod)
                return false; 

            // Check early for common case that two types are the same object
            XmlQueryType thisPrime = Prime;
            XmlQueryType thatPrime = that.Prime; 
            if ((object)thisPrime == (object)thatPrime)
                return true; 
 
            // Check that count of item types is equal
            if (thisPrime.Count != thatPrime.Count) 
                return false;

            // Check early for common case that two prime types are item types
            if (thisPrime.Count == 1) { 
                return (thisPrime.TypeCode == thatPrime.TypeCode &&
                        thisPrime.NameTest == thatPrime.NameTest && 
                        thisPrime.SchemaType == thatPrime.SchemaType && 
                        thisPrime.IsStrict == thatPrime.IsStrict &&
                        thisPrime.IsNotRtf == thatPrime.IsNotRtf); 
            }


            // Check that each item type in this type is equal to some item type in "baseType" 
            // (string | int) should be the same type as (int | string)
            foreach (XmlQueryType thisItem in this) { 
                bool match = false; 

                foreach (XmlQueryType thatItem in that) { 
                    if (thisItem.TypeCode == thatItem.TypeCode &&
                        thisItem.NameTest == thatItem.NameTest &&
                        thisItem.SchemaType == thatItem.SchemaType &&
                        thisItem.IsStrict == thatItem.IsStrict && 
                        thisItem.IsNotRtf == thatItem.IsNotRtf) {
                        // Found match so proceed to next type 
                        match = true; 
                        break;
                    } 
                }

                if (match == false)
                    return false; 
            }
 
            return true; 
        }
 
        /// 
        /// Overload == operator to call Equals rather than do reference equality.
        /// 
        public static bool operator == (XmlQueryType left, XmlQueryType right) { 
            if ((object) left == null)
                return ((object) right == null); 
 
            return left.Equals(right);
        } 

        /// 
        /// Overload != operator to call Equals rather than do reference inequality.
        ///  
        public static bool operator != (XmlQueryType left, XmlQueryType right) {
            if ((object) left == null) 
                return ((object) right != null); 

           return !left.Equals(right); 
        }


        //----------------------------------------------- 
        // Convenience Properties
        //----------------------------------------------- 
 
        /// 
        /// True if dynamic cardinality of this sequence is guaranteed to be 0. 
        /// 
        public bool IsEmpty {
            get { return Cardinality <= XmlQueryCardinality.Zero; }
        } 

        ///  
        /// True if dynamic cardinality of this sequence is guaranteed to be 1. 
        /// 
        public bool IsSingleton { 
            get { return Cardinality <= XmlQueryCardinality.One; }
        }

        ///  
        /// True if dynamic cardinality of this sequence might be 0.
        ///  
        public bool MaybeEmpty { 
            get { return XmlQueryCardinality.Zero <= Cardinality; }
        } 

        /// 
        /// True if dynamic cardinality of this sequence might be >1.
        ///  
        public bool MaybeMany {
            get { return XmlQueryCardinality.More <= Cardinality; } 
        } 

        ///  
        /// True if dynamic data type of all items in this sequence is guaranteed to be a subtype of Node.
        /// Equivalent to calling IsSubtypeOf(TypeFactory.NodeS).
        /// 
        public bool IsNode { 
            get { return (TypeCodeToFlags[(int)TypeCode] & TypeFlags.IsNode) != 0; }
        } 
 
        /// 
        /// True if dynamic data type of all items in this sequence is guaranteed to be a subtype of AnyAtomicType. 
        /// Equivalent to calling IsSubtypeOf(TypeFactory.AnyAtomicTypeS).
        /// 
        public bool IsAtomicValue {
            get { return (TypeCodeToFlags[(int)TypeCode] & TypeFlags.IsAtomicValue) != 0; } 
        }
 
        ///  
        /// True if dynamic data type of all items in this sequence is guaranteed to be a subtype of Decimal, Double, or Float.
        /// Equivalent to calling IsSubtypeOf(TypeFactory.NumericS). 
        /// 
        public bool IsNumeric {
            get { return (TypeCodeToFlags[(int)TypeCode] & TypeFlags.IsNumeric) != 0; }
        } 

 
        //----------------------------------------------- 
        // System.Object implementation
        //----------------------------------------------- 

        /// 
        /// True if "obj" is an XmlQueryType, and this type is the exact same static type.
        ///  
        public override bool Equals(object obj) {
            XmlQueryType that = obj as XmlQueryType; 
 
            if (that == null)
                return false; 

            return Equals(that);
        }
 
        /// 
        /// Return hash code of this instance. 
        ///  
        public override int GetHashCode() {
            if (this.hashCode == 0) { 
                int hash;
                XmlSchemaType schemaType;

                hash = (int)TypeCode; 

                schemaType = SchemaType; 
                if (schemaType != null) 
                    hash += (hash << 7) ^ schemaType.GetHashCode();
 
                hash += (hash << 7) ^ (int)NodeKinds;
                hash += (hash << 7) ^ Cardinality.GetHashCode();
                hash += (hash << 7) ^ (IsStrict ? 1 : 0);
 
                // Mix hash code a bit more
                hash -= hash >> 17; 
                hash -= hash >> 11; 
                hash -= hash >> 5;
 
                // Save hashcode.  Don't save 0, so that it won't ever be recomputed.
                this.hashCode = (hash == 0) ? 1 : hash;
            }
 
            return this.hashCode;
        } 
 
        /// 
        /// Return a user-friendly string representation of the XmlQueryType. 
        /// 
        public override string ToString() {
            return ToString("G");
        } 

        ///  
        /// Return a string representation of the XmlQueryType using the specified format.  The following formats are 
        /// supported:
        /// 
        ///   "G" (General): This is the default mode, and is used if no other format is recognized.  This format is
        ///                  easier to read than the canonical format, since it excludes redundant information.
        ///                  (e.g. element instead of element(*, xs:anyType))
        /// 
        ///   "X" (XQuery): Return the canonical XQuery representation, which excludes Qil specific information and
        ///                 includes extra, redundant information, such as fully specified types. 
        ///                 (e.g. element(*, xs:anyType) instead of element) 
        ///
        ///   "S" (Serialized): This format is used to serialize parts of the type which can be serialized easily, in 
        ///                     a format that is easy to parse.  Only the cardinality, type code, and strictness flag
        ///                     are serialized.  User-defined type information and element/attribute content types
        ///                     are lost.
        ///                     (e.g. One;Attribute|String|Int;true) 
        ///
        ///  
        public string ToString(string format) { 
            string[] sa;
            StringBuilder sb; 
            bool isXQ;

            if (format == "S") {
                sb = new StringBuilder(); 
                sb.Append(Cardinality.ToString(format));
                sb.Append(';'); 
 
                for (int i = 0; i < Count; i++) {
                    if (i != 0) 
                        sb.Append("|");
                    sb.Append(this[i].TypeCode.ToString());
                }
 
                sb.Append(';');
                sb.Append(IsStrict); 
                return sb.ToString(); 
            }
 
            isXQ = (format == "X");

            if (Cardinality ==  XmlQueryCardinality.None) {
                return "none"; 
            }
            else if (Cardinality == XmlQueryCardinality.Zero) { 
                return "empty"; 
            }
 
            switch (Count) {
                case 0:
                    // This assert depends on the way we are going to represent None
                    // Debug.Assert(false); 
                    return "none" + Cardinality.ToString();
                case 1: 
                    return this[0].ItemTypeToString(isXQ) + Cardinality.ToString(); 
            }
 
            sa = new string[Count];
            for (int i = 0; i < Count; i++)
                sa[i] = this[i].ItemTypeToString(isXQ);
 
            Array.Sort(sa);
 
            sb = new StringBuilder(); 
            sb.Append("(");
            sb.Append(sa[0]); 
            for (int i = 1; i < sa.Length; i++) {
                sb.Append(" | ");
                sb.Append(sa[i]);
            } 

            sb.Append(")"); 
            sb.Append(Cardinality.ToString()); 

            if (!isXQ && IsDod) 
                sb.Append('#');

            return sb.ToString();
        } 

 
        //----------------------------------------------- 
        // Serialization
        //----------------------------------------------- 

        /// 
        /// Serialize the object to BinaryWriter.
        ///  
        public abstract void GetObjectData(BinaryWriter writer);
 
        //----------------------------------------------- 
        // Helpers
        //----------------------------------------------- 

        /// 
        /// Returns true if this item type is a subtype of another item type.
        ///  
        private bool IsSubtypeOfItemType(XmlQueryType baseType) {
            Debug.Assert(Count == 1 && IsSingleton, "This method should only be called for item types."); 
            Debug.Assert(baseType.Count == 1 && baseType.IsSingleton, "This method should only be called for item types."); 
            XmlSchemaType baseSchemaType = baseType.SchemaType;
 
            if (TypeCode != baseType.TypeCode) {
                // If "baseType" is strict, then IsSubtypeOf must be false
                if (baseType.IsStrict)
                    return false; 

                // If type codes are not the same, then IsSubtypeOf can return true *only* if "baseType" is a built-in type 
                XmlSchemaType builtInType = XmlSchemaType.GetBuiltInSimpleType(baseType.TypeCode); 
                if (builtInType != null && baseSchemaType != builtInType)
                    return false; 

                // Now check whether TypeCode is derived from baseType.TypeCode
                return TypeCodeDerivation[TypeCode, baseType.TypeCode];
            } 
            else if (baseType.IsStrict) {
                // only atomic values can be strict 
                Debug.Assert(IsAtomicValue && baseType.IsAtomicValue); 

                // If schema types are not the same, then IsSubtype is false if "baseType" is strict 
                return IsStrict && SchemaType == baseSchemaType;
            }
            else {
                // Otherwise, check derivation tree 
                return (IsNotRtf || !baseType.IsNotRtf) && (IsDod || !baseType.IsDod) && NameTest.IsSubsetOf(baseType.NameTest) &&
                       (baseSchemaType == XmlSchemaComplexType.AnyType || XmlSchemaType.IsDerivedFrom(SchemaType, baseSchemaType, /* exept:*/XmlSchemaDerivationMethod.Empty)) && 
                       (!IsNillable || baseType.IsNillable); 
            }
        } 

        /// 
        /// Returns true if the intersection between this item type and "other" item type is not empty.
        ///  
        private bool HasIntersectionItemType(XmlQueryType other) {
            Debug.Assert(this.Count == 1 && this.IsSingleton, "this should be an item"); 
            Debug.Assert(other.Count == 1 && other.IsSingleton, "other should be an item"); 

            if (this.TypeCode == other.TypeCode && (this.NodeKinds & (XmlNodeKindFlags.Document | XmlNodeKindFlags.Element | XmlNodeKindFlags.Attribute)) != 0) { 
                if (this.TypeCode == XmlTypeCode.Node)
                    return true;

                // Intersect name tests 
                if (!this.NameTest.HasIntersection(other.NameTest))
                    return false; 
 
                if (!XmlSchemaType.IsDerivedFrom(this.SchemaType, other.SchemaType, /* exept:*/XmlSchemaDerivationMethod.Empty) &&
                    !XmlSchemaType.IsDerivedFrom(other.SchemaType, this.SchemaType, /* exept:*/XmlSchemaDerivationMethod.Empty)) { 
                    return false;
                }

                return true; 
            }
            else if (this.IsSubtypeOf(other) || other.IsSubtypeOf(this)) { 
                return true; 
            }
 
            return false;
        }

        ///  
        /// Return the string representation of an item type (cannot be a union or a sequence).
        ///  
        private string ItemTypeToString(bool isXQ) { 
            string s;
            Debug.Assert(Count == 1, "Do not pass a Union type to this method."); 
            Debug.Assert(IsSingleton, "Do not pass a Sequence type to this method.");

            if (IsNode) {
                // Map TypeCode to string 
                s = TypeNames[(int) TypeCode];
 
                switch (TypeCode) { 
                    case XmlTypeCode.Document:
                        if (!isXQ) 
                            goto case XmlTypeCode.Element;

                        s += "{(element" + NameAndType(true) + "?&text?&comment?&processing-instruction?)*}";
                        break; 

                    case XmlTypeCode.Element: 
                    case XmlTypeCode.Attribute: 
                        s += NameAndType(isXQ);
                        break; 
                }
            }
            else if (SchemaType != XmlSchemaComplexType.AnyType) {
                // Get QualifiedName from SchemaType 
                if (SchemaType.QualifiedName.IsEmpty)
                    s = "<:" + TypeNames[(int) TypeCode]; 
                else 
                    s = QNameToString(SchemaType.QualifiedName);
            } 
            else {
                // Map TypeCode to string
                s = TypeNames[(int) TypeCode];
            } 

            if (!isXQ && IsStrict) 
                s += "="; 

            return s; 
        }

        /// 
        /// Return "(name-test, type-name)" for this type.  If isXQ is false, normalize xs:anySimpleType and 
        /// xs:anyType to "*".
        ///  
        private string NameAndType(bool isXQ) { 
            string nodeName = NameTest.ToString();
            string typeName = "*"; 

            if (SchemaType.QualifiedName.IsEmpty) {
                typeName = "typeof(" + nodeName + ")";
            } 
            else {
                if (isXQ || (SchemaType != XmlSchemaComplexType.AnyType && SchemaType != DatatypeImplementation.AnySimpleType)) 
                    typeName = QNameToString(SchemaType.QualifiedName); 
            }
 
            if (IsNillable) {
                typeName += " nillable";
            }
 
            // Normalize "(*, *)" to ""
            if (nodeName == "*" && typeName == "*") 
                return ""; 

            return "(" + nodeName + ", " + typeName + ")"; 
        }

        /// 
        /// Convert an XmlQualifiedName to a string, using somewhat different rules than XmlQualifiedName.ToString(): 
        ///   1. Empty QNames are assumed to be wildcard names, so return "*"
        ///   2. Recognize the built-in xs: and xdt: namespaces and print the short prefix rather than the long namespace 
        ///   3. Use brace characters "{", "}" around the namespace portion of the QName 
        /// 
        private static string QNameToString(XmlQualifiedName name) { 
            if (name.IsEmpty) {
                return "*";
            }
            else if (name.Namespace.Length == 0) { 
                return name.Name;
            } 
            else if (name.Namespace == XmlReservedNs.NsXs) { 
                return "xs:" + name.Name;
            } 
            else if (name.Namespace == XmlReservedNs.NsXQueryDataType) {
                return "xdt:" + name.Name;
            }
            else { 
                return "{" + name.Namespace + "}" + name.Name;
            } 
        } 

        #region TypeFlags 
        private enum TypeFlags {
            None = 0,
            IsNode = 1,
            IsAtomicValue = 2, 
            IsNumeric = 4,
        } 
        #endregion 

        #region  TypeCodeToFlags 
        private static readonly TypeFlags[] TypeCodeToFlags = {
                /* XmlTypeCode.None                  */ TypeFlags.IsNode | TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Item                  */ TypeFlags.None,
                /* XmlTypeCode.Node                  */ TypeFlags.IsNode, 
                /* XmlTypeCode.Document              */ TypeFlags.IsNode,
                /* XmlTypeCode.Element               */ TypeFlags.IsNode, 
                /* XmlTypeCode.Attribute             */ TypeFlags.IsNode, 
                /* XmlTypeCode.Namespace             */ TypeFlags.IsNode,
                /* XmlTypeCode.ProcessingInstruction */ TypeFlags.IsNode, 
                /* XmlTypeCode.Comment               */ TypeFlags.IsNode,
                /* XmlTypeCode.Text                  */ TypeFlags.IsNode,
                /* XmlTypeCode.AnyAtomicType         */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.UntypedAtomic         */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.String                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Boolean               */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Decimal               */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.Float                 */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Double                */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.Duration              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.DateTime              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Time                  */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Date                  */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.GYearMonth            */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.GYear                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.GMonthDay             */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.GDay                  */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.GMonth                */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.HexBinary             */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Base64Binary          */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.AnyUri                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.QName                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Notation              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.NormalizedString      */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Token                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Language              */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.NmToken               */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Name                  */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.NCName                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Id                    */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Idref                 */ TypeFlags.IsAtomicValue, 
                /* XmlTypeCode.Entity                */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.Integer               */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.NonPositiveInteger    */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.NegativeInteger       */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Long                  */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.Int                   */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Short                 */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.Byte                  */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.NonNegativeInteger    */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.UnsignedLong          */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.UnsignedInt           */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.UnsignedShort         */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.UnsignedByte          */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric,
                /* XmlTypeCode.PositiveInteger       */ TypeFlags.IsAtomicValue | TypeFlags.IsNumeric, 
                /* XmlTypeCode.YearMonthDuration     */ TypeFlags.IsAtomicValue,
                /* XmlTypeCode.DayTimeDuration       */ TypeFlags.IsAtomicValue,
        };
 
        private static readonly XmlTypeCode[] BaseTypeCodes = {
            /* None                        */ XmlTypeCode.None, 
            /* Item                        */ XmlTypeCode.Item, 
            /* Node                        */ XmlTypeCode.Item,
            /* Document                    */ XmlTypeCode.Node, 
            /* Element                     */ XmlTypeCode.Node,
            /* Attribute                   */ XmlTypeCode.Node,
            /* Namespace                   */ XmlTypeCode.Node,
            /* ProcessingInstruction       */ XmlTypeCode.Node, 
            /* Comment                     */ XmlTypeCode.Node,
            /* Text                        */ XmlTypeCode.Node, 
            /* AnyAtomicType               */ XmlTypeCode.Item, 
            /* UntypedAtomic               */ XmlTypeCode.AnyAtomicType,
            /* String                      */ XmlTypeCode.AnyAtomicType, 
            /* Boolean                     */ XmlTypeCode.AnyAtomicType,
            /* Decimal                     */ XmlTypeCode.AnyAtomicType,
            /* Float                       */ XmlTypeCode.AnyAtomicType,
            /* Double                      */ XmlTypeCode.AnyAtomicType, 
            /* Duration                    */ XmlTypeCode.AnyAtomicType,
            /* DateTime                    */ XmlTypeCode.AnyAtomicType, 
            /* Time                        */ XmlTypeCode.AnyAtomicType, 
            /* Date                        */ XmlTypeCode.AnyAtomicType,
            /* GYearMonth                  */ XmlTypeCode.AnyAtomicType, 
            /* GYear                       */ XmlTypeCode.AnyAtomicType,
            /* GMonthDay                   */ XmlTypeCode.AnyAtomicType,
            /* GDay                        */ XmlTypeCode.AnyAtomicType,
            /* GMonth                      */ XmlTypeCode.AnyAtomicType, 
            /* HexBinary                   */ XmlTypeCode.AnyAtomicType,
            /* Base64Binary                */ XmlTypeCode.AnyAtomicType, 
            /* AnyUri                      */ XmlTypeCode.AnyAtomicType, 
            /* QName                       */ XmlTypeCode.AnyAtomicType,
            /* Notation                    */ XmlTypeCode.AnyAtomicType, 
            /* NormalizedString            */ XmlTypeCode.String,
            /* Token                       */ XmlTypeCode.NormalizedString,
            /* Language                    */ XmlTypeCode.Token,
            /* NmToken                     */ XmlTypeCode.Token, 
            /* Name                        */ XmlTypeCode.Token,
            /* NCName                      */ XmlTypeCode.Name, 
            /* Id                          */ XmlTypeCode.NCName, 
            /* Idref                       */ XmlTypeCode.NCName,
            /* Entity                      */ XmlTypeCode.NCName, 
            /* Integer                     */ XmlTypeCode.Decimal,
            /* NonPositiveInteger          */ XmlTypeCode.Integer,
            /* NegativeInteger             */ XmlTypeCode.NonPositiveInteger,
            /* Long                        */ XmlTypeCode.Integer, 
            /* Int                         */ XmlTypeCode.Long,
            /* Short                       */ XmlTypeCode.Int, 
            /* Byte                        */ XmlTypeCode.Short, 
            /* NonNegativeInteger          */ XmlTypeCode.Integer,
            /* UnsignedLong                */ XmlTypeCode.NonNegativeInteger, 
            /* UnsignedInt                 */ XmlTypeCode.UnsignedLong,
            /* UnsignedShort               */ XmlTypeCode.UnsignedInt,
            /* UnsignedByte                */ XmlTypeCode.UnsignedShort,
            /* PositiveInteger             */ XmlTypeCode.NonNegativeInteger, 
            /* YearMonthDuration           */ XmlTypeCode.Duration,
            /* DayTimeDuration             */ XmlTypeCode.Duration, 
        }; 

        private static readonly string[] TypeNames = { 
            /* None                        */ "none",
            /* Item                        */ "item",
            /* Node                        */ "node",
            /* Document                    */ "document", 
            /* Element                     */ "element",
            /* Attribute                   */ "attribute", 
            /* Namespace                   */ "namespace", 
            /* ProcessingInstruction       */ "processing-instruction",
            /* Comment                     */ "comment", 
            /* Text                        */ "text",
            /* AnyAtomicType               */ "xdt:anyAtomicType",
            /* UntypedAtomic               */ "xdt:untypedAtomic",
            /* String                      */ "xs:string", 
            /* Boolean                     */ "xs:boolean",
            /* Decimal                     */ "xs:decimal", 
            /* Float                       */ "xs:float", 
            /* Double                      */ "xs:double",
            /* Duration                    */ "xs:duration", 
            /* DateTime                    */ "xs:dateTime",
            /* Time                        */ "xs:time",
            /* Date                        */ "xs:date",
            /* GYearMonth                  */ "xs:gYearMonth", 
            /* GYear                       */ "xs:gYear",
            /* GMonthDay                   */ "xs:gMonthDay", 
            /* GDay                        */ "xs:gDay", 
            /* GMonth                      */ "xs:gMonth",
            /* HexBinary                   */ "xs:hexBinary", 
            /* Base64Binary                */ "xs:base64Binary",
            /* AnyUri                      */ "xs:anyUri",
            /* QName                       */ "xs:QName",
            /* Notation                    */ "xs:NOTATION", 
            /* NormalizedString            */ "xs:normalizedString",
            /* Token                       */ "xs:token", 
            /* Language                    */ "xs:language", 
            /* NmToken                     */ "xs:NMTOKEN",
            /* Name                        */ "xs:Name", 
            /* NCName                      */ "xs:NCName",
            /* Id                          */ "xs:ID",
            /* Idref                       */ "xs:IDREF",
            /* Entity                      */ "xs:ENTITY", 
            /* Integer                     */ "xs:integer",
            /* NonPositiveInteger          */ "xs:nonPositiveInteger", 
            /* NegativeInteger             */ "xs:negativeInteger", 
            /* Long                        */ "xs:long",
            /* Int                         */ "xs:int", 
            /* Short                       */ "xs:short",
            /* Byte                        */ "xs:byte",
            /* NonNegativeInteger          */ "xs:nonNegativeInteger",
            /* UnsignedLong                */ "xs:unsignedLong", 
            /* UnsignedInt                 */ "xs:unsignedInt",
            /* UnsignedShort               */ "xs:unsignedShort", 
            /* UnsignedByte                */ "xs:unsignedByte", 
            /* PositiveInteger             */ "xs:positiveInteger",
            /* YearMonthDuration           */ "xdt:yearMonthDuration", 
            /* DayTimeDuration             */ "xdt:dayTimeDuration",
        };
        #endregion
 
        /// 
        /// Implements an NxN bit matrix. 
        ///  
        private sealed class BitMatrix {
            private ulong[] bits; 

            /// 
            /// Create NxN bit matrix, where N = count.
            ///  
            public BitMatrix(int count) {
                Debug.Assert(count < 64, "BitMatrix currently only handles up to 64x64 matrix."); 
                bits = new ulong[count]; 
            }
 
//            /// 
//            /// Return the number of rows and columns in the matrix.
//            /// 
//            public int Size { 
//                get { return bits.Length; }
//            } 
// 
            /// 
            /// Get or set a bit in the matrix at position (index1, index2). 
            /// 
            public bool this[int index1, int index2] {
                get {
                    Debug.Assert(index1 < bits.Length && index2 < bits.Length, "Index out of range."); 
                    return (bits[index1] & ((ulong)1 << index2)) != 0;
                } 
                set { 
                    Debug.Assert(index1 < bits.Length && index2 < bits.Length, "Index out of range.");
                    if (value == true) { 
                        bits[index1] |= (ulong)1 << index2;
                    }
                    else {
                        bits[index1] &= ~((ulong)1 << index2); 
                    }
                } 
            } 

            ///  
            /// Strongly typed indexer.
            /// 
            public bool this[XmlTypeCode index1, XmlTypeCode index2] {
                get { 
                    return this[(int)index1, (int)index2];
                } 
//                set { 
//                    this[(int)index1, (int)index2] = value;
//                } 
            }
        }
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

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