Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / XmlUtils / System / Xml / Xsl / XmlQueryType.cs / 5 / 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataContractSerializerElement.cs
- Crypto.cs
- AccessControlEntry.cs
- BaseTemplateParser.cs
- AuthenticationModuleElement.cs
- ScalarConstant.cs
- PageStatePersister.cs
- WindowAutomationPeer.cs
- OleDbTransaction.cs
- FieldNameLookup.cs
- Semaphore.cs
- NamespaceImport.cs
- CompilerGlobalScopeAttribute.cs
- SafeCryptContextHandle.cs
- IIS7WorkerRequest.cs
- DataGridRow.cs
- DesignParameter.cs
- WebAdminConfigurationHelper.cs
- _CookieModule.cs
- MemberDomainMap.cs
- Opcode.cs
- TdsParserStateObject.cs
- QilInvokeEarlyBound.cs
- EndpointAddress10.cs
- MetadataItemEmitter.cs
- CompilerErrorCollection.cs
- ColumnMapVisitor.cs
- EncodingInfo.cs
- DbSourceCommand.cs
- AutomationPatternInfo.cs
- ScriptReferenceEventArgs.cs
- TrackingParameters.cs
- AssemblyCollection.cs
- UrlParameterWriter.cs
- AnnotationStore.cs
- OleDbMetaDataFactory.cs
- TypedDataSetSchemaImporterExtensionFx35.cs
- ListViewDeletedEventArgs.cs
- Dynamic.cs
- NavigationCommands.cs
- LogLogRecord.cs
- Group.cs
- StreamInfo.cs
- CalendarSelectionChangedEventArgs.cs
- PeerContact.cs
- ActivityDesignerResources.cs
- PkcsMisc.cs
- X509CertificateInitiatorServiceCredential.cs
- MouseGesture.cs
- ComplexBindingPropertiesAttribute.cs
- OdbcError.cs
- PageHandlerFactory.cs
- ConfigurationStrings.cs
- CollectionsUtil.cs
- RepeaterCommandEventArgs.cs
- RequiredAttributeAttribute.cs
- BamlVersionHeader.cs
- MetadataHelper.cs
- StrokeDescriptor.cs
- ConstraintEnumerator.cs
- MemberNameValidator.cs
- Version.cs
- DataTable.cs
- Keywords.cs
- TreeViewItem.cs
- DynamicResourceExtension.cs
- DesignerActionPropertyItem.cs
- SqlNodeTypeOperators.cs
- TdsParserStateObject.cs
- TextBlock.cs
- TrustLevelCollection.cs
- KeyNameIdentifierClause.cs
- Timeline.cs
- DBProviderConfigurationHandler.cs
- WorkflowMarkupSerializationProvider.cs
- ApplicationFileParser.cs
- CodeGeneratorOptions.cs
- ImageAnimator.cs
- CommonXSendMessage.cs
- FrameworkEventSource.cs
- SizeLimitedCache.cs
- ColorBlend.cs
- ViewEventArgs.cs
- WebPartManager.cs
- Trace.cs
- TextTreeObjectNode.cs
- LicenseException.cs
- Operator.cs
- DataTableNameHandler.cs
- FlowDocumentPageViewerAutomationPeer.cs
- PolicyManager.cs
- Marshal.cs
- NameGenerator.cs
- TextTreeTextBlock.cs
- FormViewPageEventArgs.cs
- GridViewRowPresenter.cs
- AnnotationStore.cs
- Queue.cs
- FilteredReadOnlyMetadataCollection.cs
- RequestTimeoutManager.cs