The Labs \ Source Viewer \ SSCLI \ System.Xml.Xsl \ XmlQueryCardinality

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlQueryCardinality.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. using System.Diagnostics;
  16. namespace System.Xml.Xsl
  17. {
  18.    
  19.     /// <summary>
  20.     /// Cardinality of part of XmlQueryType
  21.     /// struct is being used because enum doesn't allow members
  22.     /// </summary>
  23.     internal struct XmlQueryCardinality
  24.     {
  25.         private int value;
  26.        
  27.         #region ctor
  28.         /// <summary>
  29.         /// Private constructor
  30.         /// </summary>
  31.         private XmlQueryCardinality(int value)
  32.         {
  33.             Debug.Assert(0 <= value && value <= 7);
  34.             this.value = value;
  35.         }
  36.         #endregion
  37.        
  38.         #region enum
  39.         /// <summary>
  40.         /// exactly zero (empty)
  41.         /// </summary>
  42.         public static XmlQueryCardinality None {
  43.             get { return new XmlQueryCardinality(0); }
  44.         }
  45.        
  46.         /// <summary>
  47.         /// exactly zero (empty)
  48.         /// </summary>
  49.         public static XmlQueryCardinality Zero {
  50.             get { return new XmlQueryCardinality(1); }
  51.         }
  52.        
  53.         /// <summary>
  54.         /// exactly one
  55.         /// </summary>
  56.         public static XmlQueryCardinality One {
  57.             get { return new XmlQueryCardinality(2); }
  58.         }
  59.        
  60.         /// <summary>
  61.         /// zero or one (not more)
  62.         /// </summary>
  63.         public static XmlQueryCardinality ZeroOrOne {
  64.             get { return new XmlQueryCardinality(3); }
  65.         }
  66.        
  67.         /// <summary>
  68.         /// strictly more than one
  69.         /// </summary>
  70.         public static XmlQueryCardinality More {
  71.             get { return new XmlQueryCardinality(4); }
  72.         }
  73.        
  74.         /// <summary>
  75.         /// not one (strictly zero or strictly more)
  76.         /// </summary>
  77.         public static XmlQueryCardinality NotOne {
  78.             get { return new XmlQueryCardinality(5); }
  79.         }
  80.        
  81.         /// <summary>
  82.         /// one or more (not empty)
  83.         /// </summary>
  84.         public static XmlQueryCardinality OneOrMore {
  85.             get { return new XmlQueryCardinality(6); }
  86.         }
  87.        
  88.         /// <summary>
  89.         /// zero or more (any cardinality)
  90.         /// </summary>
  91.         public static XmlQueryCardinality ZeroOrMore {
  92.             get { return new XmlQueryCardinality(7); }
  93.         }
  94.         #endregion
  95.        
  96.         #region ==
  97.         /// <summary>
  98.         /// Strongly-typed Equals that returns true if this type and "other" type are equivalent.
  99.         /// </summary>
  100.         public bool Equals(XmlQueryCardinality other)
  101.         {
  102.             return this.value == other.value;
  103.         }
  104.        
  105.         /// <summary>
  106.         /// Overload == operator to call Equals rather than do reference equality.
  107.         /// </summary>
  108.         public static bool operator ==(XmlQueryCardinality left, XmlQueryCardinality right)
  109.         {
  110.             return left.value == right.value;
  111.         }
  112.        
  113.         /// <summary>
  114.         /// Overload != operator to call Equals rather than do reference inequality.
  115.         /// </summary>
  116.         public static bool operator !=(XmlQueryCardinality left, XmlQueryCardinality right)
  117.         {
  118.             return left.value != right.value;
  119.         }
  120.        
  121.         /// <summary>
  122.         /// True if "other" is an XmlQueryCardinality, and this type is the exact same static type.
  123.         /// </summary>
  124.         public override bool Equals(object other)
  125.         {
  126.             if (other is XmlQueryCardinality) {
  127.                 return Equals((XmlQueryCardinality)other);
  128.             }
  129.             return false;
  130.         }
  131.        
  132.         /// <summary>
  133.         /// Return hash code of this instance.
  134.         /// </summary>
  135.         public override int GetHashCode()
  136.         {
  137.             return value;
  138.         }
  139.         #endregion
  140.        
  141.         #region algebra
  142.         /// <summary>
  143.         /// Return union with other
  144.         /// </summary>
  145.         public static XmlQueryCardinality operator |(XmlQueryCardinality left, XmlQueryCardinality right)
  146.         {
  147.             return new XmlQueryCardinality(left.value | right.value);
  148.         }
  149.        
  150.         /// <summary>
  151.         /// Return intersection with other
  152.         /// </summary>
  153.         public static XmlQueryCardinality operator &(XmlQueryCardinality left, XmlQueryCardinality right)
  154.         {
  155.             return new XmlQueryCardinality(left.value & right.value);
  156.         }
  157.        
  158.         /// <summary>
  159.         /// Return this product other
  160.         /// </summary>
  161.         public static XmlQueryCardinality operator *(XmlQueryCardinality left, XmlQueryCardinality right)
  162.         {
  163.             return cardinalityProduct[left.value, right.value];
  164.         }
  165.        
  166.         /// <summary>
  167.         /// Return sum with other
  168.         /// </summary>
  169.         public static XmlQueryCardinality operator +(XmlQueryCardinality left, XmlQueryCardinality right)
  170.         {
  171.             return cardinalitySum[left.value, right.value];
  172.         }
  173.        
  174.         #if NEVER
  175.         /// <summary>
  176.         /// Returns true if this cardinality is guaranteed to be a subset of "other".
  177.         /// </summary>
  178.         private bool IsSubset(XmlQueryCardinality other)
  179.         {
  180.             return (this.value & ~other.value) == 0;
  181.         }
  182.         #endif
  183.        
  184.         /// <summary>
  185.         /// Returns true is left is subset of right.
  186.         /// </summary>
  187.         public static bool operator <=(XmlQueryCardinality left, XmlQueryCardinality right)
  188.         {
  189.             return (left.value & ~right.value) == 0;
  190.         }
  191.        
  192.         /// <summary>
  193.         /// Returns true is right is subset of left.
  194.         /// </summary>
  195.         public static bool operator >=(XmlQueryCardinality left, XmlQueryCardinality right)
  196.         {
  197.             return (right.value & ~left.value) == 0;
  198.         }
  199.        
  200.         /// <summary>
  201.         /// Compute the cardinality of a subset of a set of the given cardinality.
  202.         /// </summary>
  203.         /// <param name="c">the cardinality of a set</param>
  204.         /// <returns>the cardinality of a subset</returns>
  205.         public XmlQueryCardinality AtMost()
  206.         {
  207.             // Fill downward to zero
  208.             return new XmlQueryCardinality(this.value | (this.value >> 1) | (this.value >> 2));
  209.         }
  210.        
  211.         /// <summary>
  212.         /// Returns true if every non-None subset of this cardinality is disjoint with "other" cardinality.
  213.         /// Here is the behavior for None, which is the inverse of the None behavior for IsSubset:
  214.         /// None op None = false
  215.         /// None op ~None = false
  216.         /// ~None op None = true
  217.         /// </summary>
  218.         public bool NeverSubset(XmlQueryCardinality other)
  219.         {
  220.             return this.value != 0 && (this.value & other.value) == 0;
  221.         }
  222.        
  223.         #endregion
  224.        
  225.         /// <summary>
  226.         /// Return the string representation of a cardinality, normalized to either ?, +, *, or "" (card 1).
  227.         /// </summary>
  228.         public string ToString(string format)
  229.         {
  230.             if (format == "S") {
  231.                 return serialized[this.value];
  232.             }
  233.             else {
  234.                 return ToString();
  235.             }
  236.         }
  237.        
  238.         /// <summary>
  239.         /// Return the string representation of a cardinality, normalized to either ?, +, *, or "" (card 1).
  240.         /// </summary>
  241.         public override string ToString()
  242.         {
  243.             return toString[this.value];
  244.         }
  245.        
  246.         /// <summary>
  247.         /// Table of cardinality products.
  248.         /// </summary>
  249.             // None Zero One ZeroOrOne More NotOne OneOrMore ZeroOrMore
  250.             /* None      */            /* Zero      */            /* One        */            /* ZeroOrOne  */            /* More      */            /* NotOne    */            /* OneOrMore  */            /* ZeroOrMore */        private static readonly XmlQueryCardinality[,] cardinalityProduct = {{None, Zero, None, Zero, None, Zero, None, Zero}, {Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero}, {None, Zero, One, ZeroOrOne, More, NotOne, OneOrMore, ZeroOrMore}, {Zero, Zero, ZeroOrOne, ZeroOrOne, NotOne, NotOne, ZeroOrMore, ZeroOrMore}, {None, Zero, More, NotOne, More, NotOne, More, NotOne}, {Zero, Zero, NotOne, NotOne, NotOne, NotOne, NotOne, NotOne}, {None, Zero, OneOrMore, ZeroOrMore, More, NotOne, OneOrMore, ZeroOrMore}, {Zero, Zero, ZeroOrMore, ZeroOrMore, NotOne, NotOne, ZeroOrMore, ZeroOrMore}};
  251.        
  252.         /// <summary>
  253.         /// Table of cardinality sums.
  254.         /// </summary>
  255.             // None Zero One ZeroOrOne More NotOne OneOrMore ZeroOrMore
  256.             /* None      */            /* Zero      */            /* One        */            /* ZeroOrOne  */            /* More      */            /* NotOne    */            /* OneOrMore  */            /* ZeroOrMore */        private static readonly XmlQueryCardinality[,] cardinalitySum = {{None, Zero, One, ZeroOrOne, More, NotOne, OneOrMore, ZeroOrMore}, {Zero, Zero, One, ZeroOrOne, More, NotOne, OneOrMore, ZeroOrMore}, {One, One, More, OneOrMore, More, OneOrMore, More, OneOrMore}, {ZeroOrOne, ZeroOrOne, OneOrMore, ZeroOrMore, More, ZeroOrMore, OneOrMore, ZeroOrMore}, {More, More, More, More, More, More, More, More}, {NotOne, NotOne, OneOrMore, ZeroOrMore, More, NotOne, OneOrMore, ZeroOrMore}, {OneOrMore, OneOrMore, More, OneOrMore, More, OneOrMore, More, OneOrMore}, {ZeroOrMore, ZeroOrMore, OneOrMore, ZeroOrMore, More, ZeroOrMore, OneOrMore, ZeroOrMore}};
  257.        
  258.         /// <summary>
  259.         /// String representation.
  260.         /// </summary>
  261.             /* None      */            /* Zero      */            /* One        */            /* ZeroOrOne  */            /* More      */            /* NotOne    */            /* OneOrMore  */            /* ZeroOrMore */        private static readonly string[] toString = {"", "?", "", "?", "+", "*", "+", "*"};
  262.        
  263.         /// <summary>
  264.         /// Serialization
  265.         /// </summary>
  266.             /* None      */            /* Zero      */            /* One        */            /* ZeroOrOne  */            /* More      */            /* NotOne    */            /* OneOrMore  */            /* ZeroOrMore */        private static readonly string[] serialized = {"None", "Zero", "One", "ZeroOrOne", "More", "NotOne", "OneOrMore", "ZeroOrMore"};
  267.        
  268.         /// <summary>
  269.         /// Deserialization
  270.         /// </summary>
  271.         public XmlQueryCardinality(string s)
  272.         {
  273.             this.value = 0;
  274.             for (int i = 0; i < serialized.Length; i++) {
  275.                 if (s == serialized[i]) {
  276.                     this.value = i;
  277.                     break;
  278.                 }
  279.             }
  280.         }
  281.     }
  282. }

Developer Fusion