The Labs \ Source Viewer \ SSCLI \ System.Xml.Schema \ Numeric2FacetsChecker

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlSchemaFacet.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. namespace System.Xml.Schema
  16. {
  17.    
  18.     using System;
  19.     using System.ComponentModel;
  20.     using System.Xml.Serialization;
  21.     using System.Xml.Schema;
  22.     using System.Xml.XPath;
  23.     using System.Diagnostics;
  24.     using System.Collections;
  25.     using System.Text;
  26.     using System.Text.RegularExpressions;
  27.     using System.Threading;
  28.     using System.Globalization;
  29.    
  30.     /// <include file='doc\XmlSchemaFacet.uex' path='docs/doc[@for="XmlSchemaFacet"]/*' />
  31.     internal abstract class FacetsChecker
  32.     {
  33.        
  34.         private struct FacetsCompiler
  35.         {
  36.             DatatypeImplementation datatype;
  37.             RestrictionFacets derivedRestriction;
  38.            
  39.             RestrictionFlags baseFlags;
  40.             RestrictionFlags baseFixedFlags;
  41.             RestrictionFlags validRestrictionFlags;
  42.            
  43.             //Helpers
  44.             XmlSchemaDatatype nonNegativeInt;
  45.             XmlSchemaDatatype builtInType;
  46.             XmlTypeCode builtInEnum;
  47.            
  48.             bool firstPattern;
  49.             StringBuilder regStr;
  50.             XmlSchemaPatternFacet pattern_facet;
  51.            
  52.             public FacetsCompiler(DatatypeImplementation baseDatatype, RestrictionFacets restriction)
  53.             {
  54.                 firstPattern = true;
  55.                 regStr = null;
  56.                 pattern_facet = null;
  57.                 datatype = baseDatatype;
  58.                 derivedRestriction = restriction;
  59.                 baseFlags = datatype.Restriction != null ? datatype.Restriction.Flags : 0;
  60.                 baseFixedFlags = datatype.Restriction != null ? datatype.Restriction.FixedFlags : 0;
  61.                 validRestrictionFlags = datatype.ValidRestrictionFlags;
  62.                 nonNegativeInt = DatatypeImplementation.GetSimpleTypeFromTypeCode(XmlTypeCode.NonNegativeInteger).Datatype;
  63.                 builtInEnum = !(datatype is Datatype_union || datatype is Datatype_List) ? datatype.TypeCode : 0;
  64.                 builtInType = (int)builtInEnum > 0 ? DatatypeImplementation.GetSimpleTypeFromTypeCode(builtInEnum).Datatype : datatype;
  65.             }
  66.            
  67.             internal void CompileLengthFacet(XmlSchemaFacet facet)
  68.             {
  69.                 CheckProhibitedFlag(facet, RestrictionFlags.Length, Res.Sch_LengthFacetProhibited);
  70.                 CheckDupFlag(facet, RestrictionFlags.Length, Res.Sch_DupLengthFacet);
  71.                 derivedRestriction.Length = XmlBaseConverter.DecimalToInt32((decimal)ParseFacetValue(nonNegativeInt, facet, Res.Sch_LengthFacetInvalid, null, null));
  72.                
  73.                 if ((baseFixedFlags & RestrictionFlags.Length) != 0) {
  74.                     if (!datatype.IsEqual(datatype.Restriction.Length, derivedRestriction.Length)) {
  75.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  76.                     }
  77.                 }
  78.                 if ((baseFlags & RestrictionFlags.Length) != 0) {
  79.                     if (datatype.Restriction.Length < derivedRestriction.Length) {
  80.                         throw new XmlSchemaException(Res.Sch_LengthGtBaseLength, facet);
  81.                     }
  82.                 }
  83.                 if ((baseFlags & RestrictionFlags.MinLength) != 0 || (baseFlags & RestrictionFlags.MaxLength) != 0) {
  84.                     if (datatype.Restriction.MaxLength < derivedRestriction.Length || datatype.Restriction.MinLength > derivedRestriction.Length) {
  85.                         throw new XmlSchemaException(Res.Sch_MaxMinLengthBaseLength, facet);
  86.                     }
  87.                 }
  88.                 SetFlag(facet, RestrictionFlags.Length);
  89.             }
  90.            
  91.             internal void CompileMinLengthFacet(XmlSchemaFacet facet)
  92.             {
  93.                 CheckProhibitedFlag(facet, RestrictionFlags.MinLength, Res.Sch_MinLengthFacetProhibited);
  94.                 CheckDupFlag(facet, RestrictionFlags.MinLength, Res.Sch_DupMinLengthFacet);
  95.                 derivedRestriction.MinLength = XmlBaseConverter.DecimalToInt32((decimal)ParseFacetValue(nonNegativeInt, facet, Res.Sch_MinLengthFacetInvalid, null, null));
  96.                
  97.                 if ((baseFixedFlags & RestrictionFlags.MinLength) != 0) {
  98.                     if (!datatype.IsEqual(datatype.Restriction.MinLength, derivedRestriction.MinLength)) {
  99.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  100.                     }
  101.                 }
  102.                 if ((baseFlags & RestrictionFlags.MinLength) != 0) {
  103.                     if (datatype.Restriction.MinLength > derivedRestriction.MinLength) {
  104.                         throw new XmlSchemaException(Res.Sch_MinLengthGtBaseMinLength, facet);
  105.                     }
  106.                 }
  107.                 if ((baseFlags & RestrictionFlags.Length) != 0) {
  108.                     if (datatype.Restriction.Length < derivedRestriction.MinLength) {
  109.                         throw new XmlSchemaException(Res.Sch_MaxMinLengthBaseLength, facet);
  110.                     }
  111.                 }
  112.                 SetFlag(facet, RestrictionFlags.MinLength);
  113.             }
  114.            
  115.             internal void CompileMaxLengthFacet(XmlSchemaFacet facet)
  116.             {
  117.                 CheckProhibitedFlag(facet, RestrictionFlags.MaxLength, Res.Sch_MaxLengthFacetProhibited);
  118.                 CheckDupFlag(facet, RestrictionFlags.MaxLength, Res.Sch_DupMaxLengthFacet);
  119.                 derivedRestriction.MaxLength = XmlBaseConverter.DecimalToInt32((decimal)ParseFacetValue(nonNegativeInt, facet, Res.Sch_MaxLengthFacetInvalid, null, null));
  120.                
  121.                 if ((baseFixedFlags & RestrictionFlags.MaxLength) != 0) {
  122.                     if (!datatype.IsEqual(datatype.Restriction.MaxLength, derivedRestriction.MaxLength)) {
  123.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  124.                     }
  125.                 }
  126.                 if ((baseFlags & RestrictionFlags.MaxLength) != 0) {
  127.                     if (datatype.Restriction.MaxLength < derivedRestriction.MaxLength) {
  128.                         throw new XmlSchemaException(Res.Sch_MaxLengthGtBaseMaxLength, facet);
  129.                     }
  130.                 }
  131.                 if ((baseFlags & RestrictionFlags.Length) != 0) {
  132.                     if (datatype.Restriction.Length > derivedRestriction.MaxLength) {
  133.                         throw new XmlSchemaException(Res.Sch_MaxMinLengthBaseLength, facet);
  134.                     }
  135.                 }
  136.                 SetFlag(facet, RestrictionFlags.MaxLength);
  137.             }
  138.            
  139.             internal void CompilePatternFacet(XmlSchemaPatternFacet facet)
  140.             {
  141.                 CheckProhibitedFlag(facet, RestrictionFlags.Pattern, Res.Sch_PatternFacetProhibited);
  142.                 if (firstPattern == true) {
  143.                     regStr = new StringBuilder();
  144.                     regStr.Append("(");
  145.                     regStr.Append(facet.Value);
  146.                     pattern_facet = new XmlSchemaPatternFacet();
  147.                     pattern_facet = facet;
  148.                     firstPattern = false;
  149.                 }
  150.                 else {
  151.                     regStr.Append(")|(");
  152.                     regStr.Append(facet.Value);
  153.                 }
  154.                 SetFlag(facet, RestrictionFlags.Pattern);
  155.             }
  156.            
  157.             internal void CompileEnumerationFacet(XmlSchemaFacet facet, IXmlNamespaceResolver nsmgr, XmlNameTable nameTable)
  158.             {
  159.                 CheckProhibitedFlag(facet, RestrictionFlags.Enumeration, Res.Sch_EnumerationFacetProhibited);
  160.                 if (derivedRestriction.Enumeration == null) {
  161.                     derivedRestriction.Enumeration = new ArrayList();
  162.                 }
  163.                 derivedRestriction.Enumeration.Add(ParseFacetValue(datatype, facet, Res.Sch_EnumerationFacetInvalid, nsmgr, nameTable));
  164.                 SetFlag(facet, RestrictionFlags.Enumeration);
  165.             }
  166.            
  167.             internal void CompileWhitespaceFacet(XmlSchemaFacet facet)
  168.             {
  169.                 CheckProhibitedFlag(facet, RestrictionFlags.WhiteSpace, Res.Sch_WhiteSpaceFacetProhibited);
  170.                 CheckDupFlag(facet, RestrictionFlags.WhiteSpace, Res.Sch_DupWhiteSpaceFacet);
  171.                 if (facet.Value == "preserve") {
  172.                     derivedRestriction.WhiteSpace = XmlSchemaWhiteSpace.Preserve;
  173.                 }
  174.                 else if (facet.Value == "replace") {
  175.                     derivedRestriction.WhiteSpace = XmlSchemaWhiteSpace.Replace;
  176.                 }
  177.                 else if (facet.Value == "collapse") {
  178.                     derivedRestriction.WhiteSpace = XmlSchemaWhiteSpace.Collapse;
  179.                 }
  180.                 else {
  181.                     throw new XmlSchemaException(Res.Sch_InvalidWhiteSpace, facet.Value, facet);
  182.                 }
  183.                 if ((baseFixedFlags & RestrictionFlags.WhiteSpace) != 0) {
  184.                     if (!datatype.IsEqual(datatype.Restriction.WhiteSpace, derivedRestriction.WhiteSpace)) {
  185.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  186.                     }
  187.                 }
  188.                 //Check base and derived whitespace facets
  189.                 XmlSchemaWhiteSpace baseWhitespace;
  190.                 if ((baseFlags & RestrictionFlags.WhiteSpace) != 0) {
  191.                     baseWhitespace = datatype.Restriction.WhiteSpace;
  192.                 }
  193.                 else {
  194.                     baseWhitespace = datatype.BuiltInWhitespaceFacet;
  195.                 }
  196.                 if (baseWhitespace == XmlSchemaWhiteSpace.Collapse && (derivedRestriction.WhiteSpace == XmlSchemaWhiteSpace.Replace || derivedRestriction.WhiteSpace == XmlSchemaWhiteSpace.Preserve)) {
  197.                     throw new XmlSchemaException(Res.Sch_WhiteSpaceRestriction1, facet);
  198.                 }
  199.                 if (baseWhitespace == XmlSchemaWhiteSpace.Replace && derivedRestriction.WhiteSpace == XmlSchemaWhiteSpace.Preserve) {
  200.                     throw new XmlSchemaException(Res.Sch_WhiteSpaceRestriction2, facet);
  201.                 }
  202.                 SetFlag(facet, RestrictionFlags.WhiteSpace);
  203.             }
  204.            
  205.             internal void CompileMaxInclusiveFacet(XmlSchemaFacet facet)
  206.             {
  207.                 CheckProhibitedFlag(facet, RestrictionFlags.MaxInclusive, Res.Sch_MaxInclusiveFacetProhibited);
  208.                 CheckDupFlag(facet, RestrictionFlags.MaxInclusive, Res.Sch_DupMaxInclusiveFacet);
  209.                 derivedRestriction.MaxInclusive = ParseFacetValue(builtInType, facet, Res.Sch_MaxInclusiveFacetInvalid, null, null);
  210.                
  211.                 if ((baseFixedFlags & RestrictionFlags.MaxInclusive) != 0) {
  212.                     if (!datatype.IsEqual(datatype.Restriction.MaxInclusive, derivedRestriction.MaxInclusive)) {
  213.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  214.                     }
  215.                 }
  216.                 CheckValue(derivedRestriction.MaxInclusive, facet);
  217.                 SetFlag(facet, RestrictionFlags.MaxInclusive);
  218.             }
  219.            
  220.             internal void CompileMaxExclusiveFacet(XmlSchemaFacet facet)
  221.             {
  222.                 CheckProhibitedFlag(facet, RestrictionFlags.MaxExclusive, Res.Sch_MaxExclusiveFacetProhibited);
  223.                 CheckDupFlag(facet, RestrictionFlags.MaxExclusive, Res.Sch_DupMaxExclusiveFacet);
  224.                 derivedRestriction.MaxExclusive = ParseFacetValue(builtInType, facet, Res.Sch_MaxExclusiveFacetInvalid, null, null);
  225.                
  226.                 if ((baseFixedFlags & RestrictionFlags.MaxExclusive) != 0) {
  227.                     if (!datatype.IsEqual(datatype.Restriction.MaxExclusive, derivedRestriction.MaxExclusive)) {
  228.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  229.                     }
  230.                 }
  231.                 CheckValue(derivedRestriction.MaxExclusive, facet);
  232.                 SetFlag(facet, RestrictionFlags.MaxExclusive);
  233.             }
  234.            
  235.             internal void CompileMinInclusiveFacet(XmlSchemaFacet facet)
  236.             {
  237.                 CheckProhibitedFlag(facet, RestrictionFlags.MinInclusive, Res.Sch_MinInclusiveFacetProhibited);
  238.                 CheckDupFlag(facet, RestrictionFlags.MinInclusive, Res.Sch_DupMinInclusiveFacet);
  239.                 derivedRestriction.MinInclusive = ParseFacetValue(builtInType, facet, Res.Sch_MinInclusiveFacetInvalid, null, null);
  240.                
  241.                 if ((baseFixedFlags & RestrictionFlags.MinInclusive) != 0) {
  242.                     if (!datatype.IsEqual(datatype.Restriction.MinInclusive, derivedRestriction.MinInclusive)) {
  243.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  244.                     }
  245.                 }
  246.                 CheckValue(derivedRestriction.MinInclusive, facet);
  247.                 SetFlag(facet, RestrictionFlags.MinInclusive);
  248.             }
  249.            
  250.             internal void CompileMinExclusiveFacet(XmlSchemaFacet facet)
  251.             {
  252.                 CheckProhibitedFlag(facet, RestrictionFlags.MinExclusive, Res.Sch_MinExclusiveFacetProhibited);
  253.                 CheckDupFlag(facet, RestrictionFlags.MinExclusive, Res.Sch_DupMinExclusiveFacet);
  254.                 derivedRestriction.MinExclusive = ParseFacetValue(builtInType, facet, Res.Sch_MinExclusiveFacetInvalid, null, null);
  255.                
  256.                 if ((baseFixedFlags & RestrictionFlags.MinExclusive) != 0) {
  257.                     if (!datatype.IsEqual(datatype.Restriction.MinExclusive, derivedRestriction.MinExclusive)) {
  258.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  259.                     }
  260.                 }
  261.                 CheckValue(derivedRestriction.MinExclusive, facet);
  262.                 SetFlag(facet, RestrictionFlags.MinExclusive);
  263.             }
  264.            
  265.             internal void CompileTotalDigitsFacet(XmlSchemaFacet facet)
  266.             {
  267.                 CheckProhibitedFlag(facet, RestrictionFlags.TotalDigits, Res.Sch_TotalDigitsFacetProhibited);
  268.                 CheckDupFlag(facet, RestrictionFlags.TotalDigits, Res.Sch_DupTotalDigitsFacet);
  269.                 XmlSchemaDatatype positiveInt = DatatypeImplementation.GetSimpleTypeFromTypeCode(XmlTypeCode.PositiveInteger).Datatype;
  270.                 derivedRestriction.TotalDigits = XmlBaseConverter.DecimalToInt32((decimal)ParseFacetValue(positiveInt, facet, Res.Sch_TotalDigitsFacetInvalid, null, null));
  271.                
  272.                 if ((baseFixedFlags & RestrictionFlags.TotalDigits) != 0) {
  273.                     if (!datatype.IsEqual(datatype.Restriction.TotalDigits, derivedRestriction.TotalDigits)) {
  274.                         throw new XmlSchemaException(Res.Sch_FacetBaseFixed, facet);
  275.                     }
  276.                 }
  277.                 if ((baseFlags & RestrictionFlags.TotalDigits) != 0) {
  278.                     if (derivedRestriction.TotalDigits > datatype.Restriction.TotalDigits) {
  279.                         throw new XmlSchemaException(Res.Sch_TotalDigitsMismatch, string.Empty);
  280.                     }
  281.                 }
  282.                 SetFlag(facet, RestrictionFlags.TotalDigits);
  283.             }
  284.            
  285.             internal void CompileFractionDigitsFacet(XmlSchemaFacet facet)
  286.             {
  287.                 CheckProhibitedFlag(facet, RestrictionFlags.FractionDigits, Res.Sch_FractionDigitsFacetProhibited);
  288.                 CheckDupFlag(facet, RestrictionFlags.FractionDigits, Res.Sch_DupFractionDigitsFacet);
  289.                 derivedRestriction.FractionDigits = XmlBaseConverter.DecimalToInt32((decimal)ParseFacetValue(nonNegativeInt, facet, Res.Sch_FractionDigitsFacetInvalid, null, null));
  290.                
  291.                 if ((derivedRestriction.FractionDigits != 0) && (datatype.TypeCode != XmlTypeCode.Decimal)) {
  292.                     throw new XmlSchemaException(Res.Sch_FractionDigitsFacetInvalid, Res.GetString(Res.Sch_FractionDigitsNotOnDecimal), facet);
  293.                 }
  294.                 if ((baseFlags & RestrictionFlags.FractionDigits) != 0) {
  295.                     if (derivedRestriction.FractionDigits > datatype.Restriction.FractionDigits) {
  296.                         throw new XmlSchemaException(Res.Sch_TotalDigitsMismatch, string.Empty);
  297.                     }
  298.                 }
  299.                 SetFlag(facet, RestrictionFlags.FractionDigits);
  300.             }
  301.            
  302.             internal void FinishFacetCompile()
  303.             {
  304.                 //Additional check for pattern facet
  305.                 //If facet is XMLSchemaPattern, then the String built inside the loop
  306.                 //needs to be converted to a RegEx
  307.                 if (firstPattern == false) {
  308.                     if (derivedRestriction.Patterns == null) {
  309.                         derivedRestriction.Patterns = new ArrayList();
  310.                     }
  311.                     try {
  312.                         regStr.Append(")");
  313.                         string tempStr = regStr.ToString();
  314.                         if (tempStr.IndexOf('|') != -1) {
  315.                             // ordinal compare
  316.                             regStr.Insert(0, "(");
  317.                             regStr.Append(")");
  318.                         }
  319.                         derivedRestriction.Patterns.Add(new Regex(Preprocess(regStr.ToString()), RegexOptions.None));
  320.                        
  321.                     }
  322.                     catch (Exception e) {
  323.                         throw new XmlSchemaException(Res.Sch_PatternFacetInvalid, e.Message, pattern_facet);
  324.                     }
  325.                 }
  326.             }
  327.            
  328.             private void CheckValue(object value, XmlSchemaFacet facet)
  329.             {
  330.                 RestrictionFacets restriction = datatype.Restriction;
  331.                 switch (facet.FacetType) {
  332.                     case FacetType.MaxInclusive:
  333.                         if ((baseFlags & RestrictionFlags.MaxInclusive) != 0) {
  334.                             //Base facet has maxInclusive
  335.                             if (datatype.Compare(value, restriction.MaxInclusive) > 0) {
  336.                                 throw new XmlSchemaException(Res.Sch_MaxInclusiveMismatch, string.Empty);
  337.                             }
  338.                         }
  339.                         if ((baseFlags & RestrictionFlags.MaxExclusive) != 0) {
  340.                             //Base facet has maxExclusive
  341.                             if (datatype.Compare(value, restriction.MaxExclusive) >= 0) {
  342.                                 throw new XmlSchemaException(Res.Sch_MaxIncExlMismatch, string.Empty);
  343.                             }
  344.                         }
  345.                         break;
  346.                     case FacetType.MaxExclusive:
  347.                        
  348.                         if ((baseFlags & RestrictionFlags.MaxExclusive) != 0) {
  349.                             //Base facet has maxExclusive
  350.                             if (datatype.Compare(value, restriction.MaxExclusive) > 0) {
  351.                                 throw new XmlSchemaException(Res.Sch_MaxExclusiveMismatch, string.Empty);
  352.                             }
  353.                         }
  354.                         if ((baseFlags & RestrictionFlags.MaxInclusive) != 0) {
  355.                             //Base facet has maxInclusive
  356.                             if (datatype.Compare(value, restriction.MaxInclusive) > 0) {
  357.                                 throw new XmlSchemaException(Res.Sch_MaxExlIncMismatch, string.Empty);
  358.                             }
  359.                         }
  360.                         break;
  361.                     case FacetType.MinInclusive:
  362.                        
  363.                         if ((baseFlags & RestrictionFlags.MinInclusive) != 0) {
  364.                             //Base facet has minInclusive
  365.                             if (datatype.Compare(value, restriction.MinInclusive) < 0) {
  366.                                 throw new XmlSchemaException(Res.Sch_MinInclusiveMismatch, string.Empty);
  367.                             }
  368.                         }
  369.                         if ((baseFlags & RestrictionFlags.MinExclusive) != 0) {
  370.                             //Base facet has minExclusive
  371.                             if (datatype.Compare(value, restriction.MinExclusive) < 0) {
  372.                                 throw new XmlSchemaException(Res.Sch_MinIncExlMismatch, string.Empty);
  373.                             }
  374.                         }
  375.                         if ((baseFlags & RestrictionFlags.MaxExclusive) != 0) {
  376.                             //Base facet has maxExclusive
  377.                             if (datatype.Compare(value, restriction.MaxExclusive) >= 0) {
  378.                                 throw new XmlSchemaException(Res.Sch_MinIncMaxExlMismatch, string.Empty);
  379.                             }
  380.                         }
  381.                         break;
  382.                     case FacetType.MinExclusive:
  383.                        
  384.                         if ((baseFlags & RestrictionFlags.MinExclusive) != 0) {
  385.                             //Base facet has minExclusive
  386.                             if (datatype.Compare(value, restriction.MinExclusive) < 0) {
  387.                                 throw new XmlSchemaException(Res.Sch_MinExclusiveMismatch, string.Empty);
  388.                             }
  389.                         }
  390.                         if ((baseFlags & RestrictionFlags.MinInclusive) != 0) {
  391.                             //Base facet has minInclusive
  392.                             if (datatype.Compare(value, restriction.MinInclusive) < 0) {
  393.                                 throw new XmlSchemaException(Res.Sch_MinExlIncMismatch, string.Empty);
  394.                             }
  395.                         }
  396.                         if ((baseFlags & RestrictionFlags.MaxExclusive) != 0) {
  397.                             //Base facet has maxExclusive
  398.                             if (datatype.Compare(value, restriction.MaxExclusive) >= 0) {
  399.                                 throw new XmlSchemaException(Res.Sch_MinExlMaxExlMismatch, string.Empty);
  400.                             }
  401.                         }
  402.                         break;
  403.                     default:
  404.                        
  405.                         Debug.Assert(false);
  406.                         break;
  407.                 }
  408.             }
  409.            
  410.             internal void CompileFacetCombinations()
  411.             {
  412.                 RestrictionFacets baseRestriction = datatype.Restriction;
  413.                 //They are not allowed on the same type but allowed on derived types.
  414.                 if ((derivedRestriction.Flags & RestrictionFlags.MaxInclusive) != 0 && (derivedRestriction.Flags & RestrictionFlags.MaxExclusive) != 0) {
  415.                     throw new XmlSchemaException(Res.Sch_MaxInclusiveExclusive, string.Empty);
  416.                 }
  417.                 if ((derivedRestriction.Flags & RestrictionFlags.MinInclusive) != 0 && (derivedRestriction.Flags & RestrictionFlags.MinExclusive) != 0) {
  418.                     throw new XmlSchemaException(Res.Sch_MinInclusiveExclusive, string.Empty);
  419.                 }
  420.                 if ((derivedRestriction.Flags & RestrictionFlags.Length) != 0 && (derivedRestriction.Flags & (RestrictionFlags.MinLength | RestrictionFlags.MaxLength)) != 0) {
  421.                     throw new XmlSchemaException(Res.Sch_LengthAndMinMax, string.Empty);
  422.                 }
  423.                
  424.                 CopyFacetsFromBaseType();
  425.                
  426.                 // Check combinations
  427.                 if ((derivedRestriction.Flags & RestrictionFlags.MinLength) != 0 && (derivedRestriction.Flags & RestrictionFlags.MaxLength) != 0) {
  428.                     if (derivedRestriction.MinLength > derivedRestriction.MaxLength) {
  429.                         throw new XmlSchemaException(Res.Sch_MinLengthGtMaxLength, string.Empty);
  430.                     }
  431.                 }
  432.                
  433.                 //TODO MinInc /MinExc /MaxInc / MaxExc checked in derived types
  434.                 if ((derivedRestriction.Flags & RestrictionFlags.MinInclusive) != 0 && (derivedRestriction.Flags & RestrictionFlags.MaxInclusive) != 0) {
  435.                     if (datatype.Compare(derivedRestriction.MinInclusive, derivedRestriction.MaxInclusive) > 0) {
  436.                         throw new XmlSchemaException(Res.Sch_MinInclusiveGtMaxInclusive, string.Empty);
  437.                     }
  438.                 }
  439.                 if ((derivedRestriction.Flags & RestrictionFlags.MinInclusive) != 0 && (derivedRestriction.Flags & RestrictionFlags.MaxExclusive) != 0) {
  440.                     if (datatype.Compare(derivedRestriction.MinInclusive, derivedRestriction.MaxExclusive) > 0) {
  441.                         throw new XmlSchemaException(Res.Sch_MinInclusiveGtMaxExclusive, string.Empty);
  442.                     }
  443.                 }
  444.                 if ((derivedRestriction.Flags & RestrictionFlags.MinExclusive) != 0 && (derivedRestriction.Flags & RestrictionFlags.MaxExclusive) != 0) {
  445.                     if (datatype.Compare(derivedRestriction.MinExclusive, derivedRestriction.MaxExclusive) > 0) {
  446.                         throw new XmlSchemaException(Res.Sch_MinExclusiveGtMaxExclusive, string.Empty);
  447.                     }
  448.                 }
  449.                 if ((derivedRestriction.Flags & RestrictionFlags.MinExclusive) != 0 && (derivedRestriction.Flags & RestrictionFlags.MaxInclusive) != 0) {
  450.                     if (datatype.Compare(derivedRestriction.MinExclusive, derivedRestriction.MaxInclusive) > 0) {
  451.                         throw new XmlSchemaException(Res.Sch_MinExclusiveGtMaxInclusive, string.Empty);
  452.                     }
  453.                 }
  454.                 if ((derivedRestriction.Flags & (RestrictionFlags.TotalDigits | RestrictionFlags.FractionDigits)) == (RestrictionFlags.TotalDigits | RestrictionFlags.FractionDigits)) {
  455.                     if (derivedRestriction.FractionDigits > derivedRestriction.TotalDigits) {
  456.                         throw new XmlSchemaException(Res.Sch_FractionDigitsGtTotalDigits, string.Empty);
  457.                     }
  458.                 }
  459.             }
  460.            
  461.             private void CopyFacetsFromBaseType()
  462.             {
  463.                 RestrictionFacets baseRestriction = datatype.Restriction;
  464.                 // Copy additional facets from the base type
  465.                 if ((derivedRestriction.Flags & RestrictionFlags.Length) == 0 && (baseFlags & RestrictionFlags.Length) != 0) {
  466.                     derivedRestriction.Length = baseRestriction.Length;
  467.                     SetFlag(RestrictionFlags.Length);
  468.                 }
  469.                 if ((derivedRestriction.Flags & RestrictionFlags.MinLength) == 0 && (baseFlags & RestrictionFlags.MinLength) != 0) {
  470.                     derivedRestriction.MinLength = baseRestriction.MinLength;
  471.                     SetFlag(RestrictionFlags.MinLength);
  472.                 }
  473.                 if ((derivedRestriction.Flags & RestrictionFlags.MaxLength) == 0 && (baseFlags & RestrictionFlags.MaxLength) != 0) {
  474.                     derivedRestriction.MaxLength = baseRestriction.MaxLength;
  475.                     SetFlag(RestrictionFlags.MaxLength);
  476.                 }
  477.                 if ((baseFlags & RestrictionFlags.Pattern) != 0) {
  478.                     if (derivedRestriction.Patterns == null) {
  479.                         derivedRestriction.Patterns = baseRestriction.Patterns;
  480.                     }
  481.                     else {
  482.                         derivedRestriction.Patterns.AddRange(baseRestriction.Patterns);
  483.                     }
  484.                     SetFlag(RestrictionFlags.Pattern);
  485.                 }
  486.                
  487.                 if ((baseFlags & RestrictionFlags.Enumeration) != 0) {
  488.                     if (derivedRestriction.Enumeration == null) {
  489.                         derivedRestriction.Enumeration = baseRestriction.Enumeration;
  490.                     }
  491.                     SetFlag(RestrictionFlags.Enumeration);
  492.                 }
  493.                
  494.                 if ((derivedRestriction.Flags & RestrictionFlags.WhiteSpace) == 0 && (baseFlags & RestrictionFlags.WhiteSpace) != 0) {
  495.                     derivedRestriction.WhiteSpace = baseRestriction.WhiteSpace;
  496.                     SetFlag(RestrictionFlags.WhiteSpace);
  497.                 }
  498.                 if ((derivedRestriction.Flags & RestrictionFlags.MaxInclusive) == 0 && (baseFlags & RestrictionFlags.MaxInclusive) != 0) {
  499.                     derivedRestriction.MaxInclusive = baseRestriction.MaxInclusive;
  500.                     SetFlag(RestrictionFlags.MaxInclusive);
  501.                 }
  502.                 if ((derivedRestriction.Flags & RestrictionFlags.MaxExclusive) == 0 && (baseFlags & RestrictionFlags.MaxExclusive) != 0) {
  503.                     derivedRestriction.MaxExclusive = baseRestriction.MaxExclusive;
  504.                     SetFlag(RestrictionFlags.MaxExclusive);
  505.                 }
  506.                 if ((derivedRestriction.Flags & RestrictionFlags.MinInclusive) == 0 && (baseFlags & RestrictionFlags.MinInclusive) != 0) {
  507.                     derivedRestriction.MinInclusive = baseRestriction.MinInclusive;
  508.                     SetFlag(RestrictionFlags.MinInclusive);
  509.                 }
  510.                 if ((derivedRestriction.Flags & RestrictionFlags.MinExclusive) == 0 && (baseFlags & RestrictionFlags.MinExclusive) != 0) {
  511.                     derivedRestriction.MinExclusive = baseRestriction.MinExclusive;
  512.                     SetFlag(RestrictionFlags.MinExclusive);
  513.                 }
  514.                 if ((derivedRestriction.Flags & RestrictionFlags.TotalDigits) == 0 && (baseFlags & RestrictionFlags.TotalDigits) != 0) {
  515.                     derivedRestriction.TotalDigits = baseRestriction.TotalDigits;
  516.                     SetFlag(RestrictionFlags.TotalDigits);
  517.                 }
  518.                 if ((derivedRestriction.Flags & RestrictionFlags.FractionDigits) == 0 && (baseFlags & RestrictionFlags.FractionDigits) != 0) {
  519.                     derivedRestriction.FractionDigits = baseRestriction.FractionDigits;
  520.                     SetFlag(RestrictionFlags.FractionDigits);
  521.                 }
  522.             }
  523.            
  524.             private object ParseFacetValue(XmlSchemaDatatype datatype, XmlSchemaFacet facet, string code, IXmlNamespaceResolver nsmgr, XmlNameTable nameTable)
  525.             {
  526.                 object typedValue;
  527.                 Exception ex = datatype.TryParseValue(facet.Value, nameTable, nsmgr, out typedValue);
  528.                 if (ex == null) {
  529.                     return typedValue;
  530.                 }
  531.                 else {
  532.                     throw new XmlSchemaException(code, new string[] {ex.Message}, ex, facet.SourceUri, facet.LineNumber, facet.LinePosition, facet);
  533.                 }
  534.             }
  535.            
  536.             private struct Map
  537.             {
  538.                 internal Map(char m, string r)
  539.                 {
  540.                     match = m;
  541.                     replacement = r;
  542.                 }
  543.                 internal char match;
  544.                 internal string replacement;
  545.             }
  546.            
  547.             private static readonly Map[] c_map = {new Map('c', "\\p{_xmlC}"), new Map('C', "\\P{_xmlC}"), new Map('d', "\\p{_xmlD}"), new Map('D', "\\P{_xmlD}"), new Map('i', "\\p{_xmlI}"), new Map('I', "\\P{_xmlI}"), new Map('w', "\\p{_xmlW}"), new Map('W', "\\P{_xmlW}")};
  548.             private static string Preprocess(string pattern)
  549.             {
  550.                 StringBuilder bufBld = new StringBuilder();
  551.                 bufBld.Append("^");
  552.                
  553.                 char[] source = pattern.ToCharArray();
  554.                 int length = pattern.Length;
  555.                 int copyPosition = 0;
  556.                 for (int position = 0; position < length - 2; position++) {
  557.                     if (source[position] == '\\') {
  558.                         if (source[position + 1] == '\\') {
  559.                             position++;
  560.                             // skip it
  561.                         }
  562.                         else {
  563.                             char ch = source[position + 1];
  564.                             for (int i = 0; i < c_map.Length; i++) {
  565.                                 if (c_map[i].match == ch) {
  566.                                     if (copyPosition < position) {
  567.                                         bufBld.Append(source, copyPosition, position - copyPosition);
  568.                                     }
  569.                                     bufBld.Append(c_map[i].replacement);
  570.                                     position++;
  571.                                     copyPosition = position + 1;
  572.                                     break;
  573.                                 }
  574.                             }
  575.                         }
  576.                     }
  577.                 }
  578.                 if (copyPosition < length) {
  579.                     bufBld.Append(source, copyPosition, length - copyPosition);
  580.                 }
  581.                
  582.                 bufBld.Append("$");
  583.                 return bufBld.ToString();
  584.             }
  585.            
  586.             private void CheckProhibitedFlag(XmlSchemaFacet facet, RestrictionFlags flag, string errorCode)
  587.             {
  588.                 if ((validRestrictionFlags & flag) == 0) {
  589.                     throw new XmlSchemaException(errorCode, datatype.TypeCodeString, facet);
  590.                 }
  591.             }
  592.            
  593.             private void CheckDupFlag(XmlSchemaFacet facet, RestrictionFlags flag, string errorCode)
  594.             {
  595.                 if ((derivedRestriction.Flags & flag) != 0) {
  596.                     throw new XmlSchemaException(errorCode, facet);
  597.                 }
  598.             }
  599.            
  600.             private void SetFlag(XmlSchemaFacet facet, RestrictionFlags flag)
  601.             {
  602.                 derivedRestriction.Flags |= flag;
  603.                 if (facet.IsFixed) {
  604.                     derivedRestriction.FixedFlags |= flag;
  605.                 }
  606.             }
  607.            
  608.             private void SetFlag(RestrictionFlags flag)
  609.             {
  610.                 derivedRestriction.Flags |= flag;
  611.                 if ((baseFixedFlags & flag) != 0) {
  612.                     derivedRestriction.FixedFlags |= flag;
  613.                 }
  614.             }
  615.            
  616.         }
  617.        
  618.         internal virtual Exception CheckLexicalFacets(ref string parseString, XmlSchemaDatatype datatype)
  619.         {
  620.             CheckWhitespaceFacets(ref parseString, datatype);
  621.             return CheckPatternFacets(datatype.Restriction, parseString);
  622.         }
  623.         internal virtual Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  624.         {
  625.             return null;
  626.         }
  627.         internal virtual Exception CheckValueFacets(decimal value, XmlSchemaDatatype datatype)
  628.         {
  629.             return null;
  630.         }
  631.         internal virtual Exception CheckValueFacets(Int64 value, XmlSchemaDatatype datatype)
  632.         {
  633.             return null;
  634.         }
  635.         internal virtual Exception CheckValueFacets(Int32 value, XmlSchemaDatatype datatype)
  636.         {
  637.             return null;
  638.         }
  639.         internal virtual Exception CheckValueFacets(Int16 value, XmlSchemaDatatype datatype)
  640.         {
  641.             return null;
  642.         }
  643.         internal virtual Exception CheckValueFacets(byte value, XmlSchemaDatatype datatype)
  644.         {
  645.             return null;
  646.         }
  647.         internal virtual Exception CheckValueFacets(DateTime value, XmlSchemaDatatype datatype)
  648.         {
  649.             return null;
  650.         }
  651.         internal virtual Exception CheckValueFacets(double value, XmlSchemaDatatype datatype)
  652.         {
  653.             return null;
  654.         }
  655.         internal virtual Exception CheckValueFacets(float value, XmlSchemaDatatype datatype)
  656.         {
  657.             return null;
  658.         }
  659.         internal virtual Exception CheckValueFacets(string value, XmlSchemaDatatype datatype)
  660.         {
  661.             return null;
  662.         }
  663.         internal virtual Exception CheckValueFacets(byte[] value, XmlSchemaDatatype datatype)
  664.         {
  665.             return null;
  666.         }
  667.         internal virtual Exception CheckValueFacets(TimeSpan value, XmlSchemaDatatype datatype)
  668.         {
  669.             return null;
  670.         }
  671.         internal virtual Exception CheckValueFacets(XmlQualifiedName value, XmlSchemaDatatype datatype)
  672.         {
  673.             return null;
  674.         }
  675.        
  676.         internal void CheckWhitespaceFacets(ref string s, XmlSchemaDatatype datatype)
  677.         {
  678.             // before parsing, check whitespace facet
  679.             RestrictionFacets restriction = datatype.Restriction;
  680.            
  681.             switch (datatype.Variety) {
  682.                 case XmlSchemaDatatypeVariety.List:
  683.                     s = s.Trim();
  684.                     break;
  685.                 case XmlSchemaDatatypeVariety.Atomic:
  686.                    
  687.                     if (datatype.BuiltInWhitespaceFacet == XmlSchemaWhiteSpace.Collapse) {
  688.                         s = XmlComplianceUtil.NonCDataNormalize(s);
  689.                     }
  690.                     else if (datatype.BuiltInWhitespaceFacet == XmlSchemaWhiteSpace.Replace) {
  691.                         s = XmlComplianceUtil.CDataNormalize(s);
  692.                     }
  693.                     else if (restriction != null && (restriction.Flags & RestrictionFlags.WhiteSpace) != 0) {
  694.                         //Restriction has whitespace facet specified
  695.                         if (restriction.WhiteSpace == XmlSchemaWhiteSpace.Replace) {
  696.                             s = XmlComplianceUtil.CDataNormalize(s);
  697.                         }
  698.                         else if (restriction.WhiteSpace == XmlSchemaWhiteSpace.Collapse) {
  699.                             s = XmlComplianceUtil.NonCDataNormalize(s);
  700.                         }
  701.                     }
  702.                     break;
  703.                 default:
  704.                    
  705.                     break;
  706.                
  707.             }
  708.         }
  709.         internal Exception CheckPatternFacets(RestrictionFacets restriction, string value)
  710.         {
  711.             if (restriction != null && (restriction.Flags & RestrictionFlags.Pattern) != 0) {
  712.                 foreach (Regex regex in restriction.Patterns) {
  713.                     if (!regex.IsMatch(value)) {
  714.                         return new XmlSchemaException(Res.Sch_PatternConstraintFailed, string.Empty);
  715.                     }
  716.                 }
  717.             }
  718.             return null;
  719.         }
  720.        
  721.         internal virtual bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  722.         {
  723.             return false;
  724.         }
  725.        
  726.         //Compile-time Facet Checking
  727.         internal virtual RestrictionFacets ConstructRestriction(DatatypeImplementation datatype, XmlSchemaObjectCollection facets, XmlNameTable nameTable)
  728.         {
  729.             //Datatype is the type on which this method is called
  730.             RestrictionFacets derivedRestriction = new RestrictionFacets();
  731.             FacetsCompiler facetCompiler = new FacetsCompiler(datatype, derivedRestriction);
  732.            
  733.             foreach (XmlSchemaFacet facet in facets) {
  734.                 if (facet.Value == null) {
  735.                     throw new XmlSchemaException(Res.Sch_InvalidFacet, facet);
  736.                 }
  737.                 IXmlNamespaceResolver nsmgr = new SchemaNamespaceManager(facet);
  738.                 switch (facet.FacetType) {
  739.                     case FacetType.Length:
  740.                         facetCompiler.CompileLengthFacet(facet);
  741.                         break;
  742.                     case FacetType.MinLength:
  743.                        
  744.                         facetCompiler.CompileMinLengthFacet(facet);
  745.                         break;
  746.                     case FacetType.MaxLength:
  747.                        
  748.                         facetCompiler.CompileMaxLengthFacet(facet);
  749.                         break;
  750.                     case FacetType.Pattern:
  751.                        
  752.                         facetCompiler.CompilePatternFacet(facet as XmlSchemaPatternFacet);
  753.                         break;
  754.                     case FacetType.Enumeration:
  755.                        
  756.                         facetCompiler.CompileEnumerationFacet(facet, nsmgr, nameTable);
  757.                         break;
  758.                     case FacetType.Whitespace:
  759.                        
  760.                         facetCompiler.CompileWhitespaceFacet(facet);
  761.                         break;
  762.                     case FacetType.MinInclusive:
  763.                        
  764.                         facetCompiler.CompileMinInclusiveFacet(facet);
  765.                         break;
  766.                     case FacetType.MinExclusive:
  767.                        
  768.                         facetCompiler.CompileMinExclusiveFacet(facet);
  769.                         break;
  770.                     case FacetType.MaxInclusive:
  771.                        
  772.                         facetCompiler.CompileMaxInclusiveFacet(facet);
  773.                         break;
  774.                     case FacetType.MaxExclusive:
  775.                        
  776.                         facetCompiler.CompileMaxExclusiveFacet(facet);
  777.                         break;
  778.                     case FacetType.TotalDigits:
  779.                        
  780.                         facetCompiler.CompileTotalDigitsFacet(facet);
  781.                         break;
  782.                     case FacetType.FractionDigits:
  783.                        
  784.                         facetCompiler.CompileFractionDigitsFacet(facet);
  785.                         break;
  786.                     default:
  787.                        
  788.                         throw new XmlSchemaException(Res.Sch_UnknownFacet, facet);
  789.                         break;
  790.                 }
  791.             }
  792.             facetCompiler.FinishFacetCompile();
  793.             facetCompiler.CompileFacetCombinations();
  794.             return derivedRestriction;
  795.         }
  796.        
  797.        
  798.        
  799.        
  800.        
  801.         static internal decimal Power(int x, int y)
  802.         {
  803.             //Returns X raised to the power Y
  804.             decimal returnValue = 1m;
  805.             decimal decimalValue = (decimal)x;
  806.             if (y > 28) {
  807.                 //CLR decimal cannot handle more than 29 digits (10 power 28.)
  808.                 return decimal.MaxValue;
  809.             }
  810.             for (int i = 0; i < y; i++) {
  811.                 returnValue = returnValue * decimalValue;
  812.             }
  813.             return returnValue;
  814.         }
  815.     }
  816.    
  817.    
  818.     internal class Numeric10FacetsChecker : FacetsChecker
  819.     {
  820.         static readonly char[] signs = new char[] {'+', '-'};
  821.         decimal maxValue;
  822.         decimal minValue;
  823.        
  824.         internal Numeric10FacetsChecker(decimal minVal, decimal maxVal)
  825.         {
  826.             minValue = minVal;
  827.             maxValue = maxVal;
  828.         }
  829.        
  830.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  831.         {
  832.            
  833.             decimal decimalValue = datatype.ValueConverter.ToDecimal(value);
  834.             return CheckValueFacets(decimalValue, datatype);
  835.         }
  836.        
  837.         internal override Exception CheckValueFacets(decimal value, XmlSchemaDatatype datatype)
  838.         {
  839.             RestrictionFacets restriction = datatype.Restriction;
  840.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  841.             XmlValueConverter valueConverter = datatype.ValueConverter;
  842.            
  843.             //Check built-in facets
  844.             if (value > maxValue || value < minValue) {
  845.                 return new OverflowException(Res.GetString(Res.XmlConvert_Overflow, value.ToString(CultureInfo.InvariantCulture), datatype.TypeCodeString));
  846.             }
  847.             //Check user-defined facets
  848.             if (flags != 0) {
  849.                 if ((flags & RestrictionFlags.MaxInclusive) != 0) {
  850.                     if (value > valueConverter.ToDecimal(restriction.MaxInclusive)) {
  851.                         return new XmlSchemaException(Res.Sch_MaxInclusiveConstraintFailed, string.Empty);
  852.                     }
  853.                 }
  854.                
  855.                 if ((flags & RestrictionFlags.MaxExclusive) != 0) {
  856.                     if (value >= valueConverter.ToDecimal(restriction.MaxExclusive)) {
  857.                         return new XmlSchemaException(Res.Sch_MaxExclusiveConstraintFailed, string.Empty);
  858.                     }
  859.                 }
  860.                
  861.                 if ((flags & RestrictionFlags.MinInclusive) != 0) {
  862.                     if (value < valueConverter.ToDecimal(restriction.MinInclusive)) {
  863.                         return new XmlSchemaException(Res.Sch_MinInclusiveConstraintFailed, string.Empty);
  864.                     }
  865.                 }
  866.                
  867.                 if ((flags & RestrictionFlags.MinExclusive) != 0) {
  868.                     if (value <= valueConverter.ToDecimal(restriction.MinExclusive)) {
  869.                         return new XmlSchemaException(Res.Sch_MinExclusiveConstraintFailed, string.Empty);
  870.                     }
  871.                 }
  872.                 if ((flags & RestrictionFlags.Enumeration) != 0) {
  873.                     if (!MatchEnumeration(value, restriction.Enumeration, valueConverter)) {
  874.                         return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  875.                     }
  876.                 }
  877.                 return CheckTotalAndFractionDigits(value, restriction.TotalDigits, restriction.FractionDigits, ((flags & RestrictionFlags.TotalDigits) != 0), ((flags & RestrictionFlags.FractionDigits) != 0));
  878.             }
  879.             return null;
  880.         }
  881.        
  882.         internal override Exception CheckValueFacets(Int64 value, XmlSchemaDatatype datatype)
  883.         {
  884.             decimal decimalValue = (decimal)value;
  885.             return CheckValueFacets(decimalValue, datatype);
  886.         }
  887.        
  888.         internal override Exception CheckValueFacets(Int32 value, XmlSchemaDatatype datatype)
  889.         {
  890.             decimal decimalValue = (decimal)value;
  891.             return CheckValueFacets(decimalValue, datatype);
  892.         }
  893.         internal override Exception CheckValueFacets(Int16 value, XmlSchemaDatatype datatype)
  894.         {
  895.             decimal decimalValue = (decimal)value;
  896.             return CheckValueFacets(decimalValue, datatype);
  897.         }
  898.         internal override Exception CheckValueFacets(byte value, XmlSchemaDatatype datatype)
  899.         {
  900.             decimal decimalValue = (decimal)value;
  901.             return CheckValueFacets(decimalValue, datatype);
  902.         }
  903.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  904.         {
  905.             return MatchEnumeration(datatype.ValueConverter.ToDecimal(value), enumeration, datatype.ValueConverter);
  906.         }
  907.        
  908.         internal bool MatchEnumeration(decimal value, ArrayList enumeration, XmlValueConverter valueConverter)
  909.         {
  910.             foreach (object correctValue in enumeration) {
  911.                 if (value == valueConverter.ToDecimal(correctValue)) {
  912.                     return true;
  913.                 }
  914.             }
  915.             return false;
  916.         }
  917.         internal Exception CheckTotalAndFractionDigits(decimal value, int totalDigits, int fractionDigits, bool checkTotal, bool checkFraction)
  918.         {
  919.             decimal maxValue = FacetsChecker.Power(10, totalDigits) - 1;
  920.             //(decimal)Math.Pow(10, totalDigits) - 1 ;
  921.             int powerCnt = 0;
  922.             if (value < 0) {
  923.                 value = Decimal.Negate(value);
  924.                 //Need to compare maxValue allowed against the absolute value
  925.             }
  926.             while (Decimal.Truncate(value) != value) {
  927.                 //Till it has a fraction
  928.                 value = value * 10;
  929.                 powerCnt++;
  930.             }
  931.            
  932.             if (checkTotal && (value > maxValue || powerCnt > totalDigits)) {
  933.                 return new XmlSchemaException(Res.Sch_TotalDigitsConstraintFailed, string.Empty);
  934.             }
  935.             if (checkFraction && powerCnt > fractionDigits) {
  936.                 return new XmlSchemaException(Res.Sch_FractionDigitsConstraintFailed, string.Empty);
  937.             }
  938.             return null;
  939.         }
  940.     }
  941.    
  942.    
  943.     internal class Numeric2FacetsChecker : FacetsChecker
  944.     {
  945.        
  946.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  947.         {
  948.             double doubleValue = datatype.ValueConverter.ToDouble(value);
  949.             return CheckValueFacets(doubleValue, datatype);
  950.         }
  951.        
  952.         internal override Exception CheckValueFacets(double value, XmlSchemaDatatype datatype)
  953.         {
  954.             RestrictionFacets restriction = datatype.Restriction;
  955.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  956.             XmlValueConverter valueConverter = datatype.ValueConverter;
  957.            
  958.             if ((flags & RestrictionFlags.MaxInclusive) != 0) {
  959.                 if (value > valueConverter.ToDouble(restriction.MaxInclusive)) {
  960.                     return new XmlSchemaException(Res.Sch_MaxInclusiveConstraintFailed, string.Empty);
  961.                 }
  962.             }
  963.             if ((flags & RestrictionFlags.MaxExclusive) != 0) {
  964.                 if (value >= valueConverter.ToDouble(restriction.MaxExclusive)) {
  965.                     return new XmlSchemaException(Res.Sch_MaxExclusiveConstraintFailed, string.Empty);
  966.                 }
  967.             }
  968.            
  969.             if ((flags & RestrictionFlags.MinInclusive) != 0) {
  970.                 if (value < (valueConverter.ToDouble(restriction.MinInclusive))) {
  971.                     return new XmlSchemaException(Res.Sch_MinInclusiveConstraintFailed, string.Empty);
  972.                 }
  973.             }
  974.            
  975.             if ((flags & RestrictionFlags.MinExclusive) != 0) {
  976.                 if (value <= valueConverter.ToDouble(restriction.MinExclusive)) {
  977.                     return new XmlSchemaException(Res.Sch_MinExclusiveConstraintFailed, string.Empty);
  978.                 }
  979.             }
  980.             if ((flags & RestrictionFlags.Enumeration) != 0) {
  981.                 if (!MatchEnumeration(value, restriction.Enumeration, valueConverter)) {
  982.                     return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  983.                 }
  984.             }
  985.             return null;
  986.         }
  987.        
  988.         internal override Exception CheckValueFacets(float value, XmlSchemaDatatype datatype)
  989.         {
  990.             double doubleValue = (double)value;
  991.             return CheckValueFacets(doubleValue, datatype);
  992.         }
  993.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  994.         {
  995.             return MatchEnumeration(datatype.ValueConverter.ToDouble(value), enumeration, datatype.ValueConverter);
  996.         }
  997.         private bool MatchEnumeration(double value, ArrayList enumeration, XmlValueConverter valueConverter)
  998.         {
  999.             foreach (object correctValue in enumeration) {
  1000.                 if (value == valueConverter.ToDouble(correctValue)) {
  1001.                     return true;
  1002.                 }
  1003.             }
  1004.             return false;
  1005.         }
  1006.     }
  1007.    
  1008.     internal class DurationFacetsChecker : FacetsChecker
  1009.     {
  1010.        
  1011.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1012.         {
  1013.             TimeSpan timeSpanValue = (TimeSpan)datatype.ValueConverter.ChangeType(value, typeof(TimeSpan));
  1014.             return CheckValueFacets(timeSpanValue, datatype);
  1015.         }
  1016.        
  1017.         internal override Exception CheckValueFacets(TimeSpan value, XmlSchemaDatatype datatype)
  1018.         {
  1019.             RestrictionFacets restriction = datatype.Restriction;
  1020.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1021.            
  1022.             if ((flags & RestrictionFlags.MaxInclusive) != 0) {
  1023.                 if (TimeSpan.Compare(value, (TimeSpan)restriction.MaxInclusive) > 0) {
  1024.                     return new XmlSchemaException(Res.Sch_MaxInclusiveConstraintFailed, string.Empty);
  1025.                 }
  1026.             }
  1027.            
  1028.             if ((flags & RestrictionFlags.MaxExclusive) != 0) {
  1029.                 if (TimeSpan.Compare(value, (TimeSpan)restriction.MaxExclusive) >= 0) {
  1030.                     return new XmlSchemaException(Res.Sch_MaxExclusiveConstraintFailed, string.Empty);
  1031.                 }
  1032.             }
  1033.            
  1034.             if ((flags & RestrictionFlags.MinInclusive) != 0) {
  1035.                 if (TimeSpan.Compare(value, (TimeSpan)restriction.MinInclusive) < 0) {
  1036.                     return new XmlSchemaException(Res.Sch_MinInclusiveConstraintFailed, string.Empty);
  1037.                 }
  1038.             }
  1039.            
  1040.             if ((flags & RestrictionFlags.MinExclusive) != 0) {
  1041.                 if (TimeSpan.Compare(value, (TimeSpan)restriction.MinExclusive) <= 0) {
  1042.                     return new XmlSchemaException(Res.Sch_MinExclusiveConstraintFailed, string.Empty);
  1043.                 }
  1044.             }
  1045.             if ((flags & RestrictionFlags.Enumeration) != 0) {
  1046.                 if (!MatchEnumeration(value, restriction.Enumeration)) {
  1047.                     return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1048.                 }
  1049.             }
  1050.             return null;
  1051.         }
  1052.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1053.         {
  1054.             return MatchEnumeration((TimeSpan)value, enumeration);
  1055.         }
  1056.        
  1057.         private bool MatchEnumeration(TimeSpan value, ArrayList enumeration)
  1058.         {
  1059.             foreach (TimeSpan correctValue in enumeration) {
  1060.                 if (TimeSpan.Compare(value, correctValue) == 0) {
  1061.                     return true;
  1062.                 }
  1063.             }
  1064.             return false;
  1065.         }
  1066.     }
  1067.    
  1068.     internal class DateTimeFacetsChecker : FacetsChecker
  1069.     {
  1070.        
  1071.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1072.         {
  1073.             DateTime dateTimeValue = datatype.ValueConverter.ToDateTime(value);
  1074.             return CheckValueFacets(dateTimeValue, datatype);
  1075.         }
  1076.        
  1077.         internal override Exception CheckValueFacets(DateTime value, XmlSchemaDatatype datatype)
  1078.         {
  1079.             RestrictionFacets restriction = datatype.Restriction;
  1080.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1081.            
  1082.             if ((flags & RestrictionFlags.MaxInclusive) != 0) {
  1083.                 if (datatype.Compare(value, (DateTime)restriction.MaxInclusive) > 0) {
  1084.                     return new XmlSchemaException(Res.Sch_MaxInclusiveConstraintFailed, string.Empty);
  1085.                 }
  1086.             }
  1087.            
  1088.             if ((flags & RestrictionFlags.MaxExclusive) != 0) {
  1089.                 if (datatype.Compare(value, (DateTime)restriction.MaxExclusive) >= 0) {
  1090.                     return new XmlSchemaException(Res.Sch_MaxExclusiveConstraintFailed, string.Empty);
  1091.                 }
  1092.             }
  1093.            
  1094.             if ((flags & RestrictionFlags.MinInclusive) != 0) {
  1095.                 if (datatype.Compare(value, (DateTime)restriction.MinInclusive) < 0) {
  1096.                     return new XmlSchemaException(Res.Sch_MinInclusiveConstraintFailed, string.Empty);
  1097.                 }
  1098.             }
  1099.            
  1100.             if ((flags & RestrictionFlags.MinExclusive) != 0) {
  1101.                 if (datatype.Compare(value, (DateTime)restriction.MinExclusive) <= 0) {
  1102.                     return new XmlSchemaException(Res.Sch_MinExclusiveConstraintFailed, string.Empty);
  1103.                 }
  1104.             }
  1105.             if ((flags & RestrictionFlags.Enumeration) != 0) {
  1106.                 if (!MatchEnumeration(value, restriction.Enumeration, datatype)) {
  1107.                     return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1108.                 }
  1109.             }
  1110.             return null;
  1111.         }
  1112.        
  1113.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1114.         {
  1115.             return MatchEnumeration(datatype.ValueConverter.ToDateTime(value), enumeration, datatype);
  1116.         }
  1117.        
  1118.         private bool MatchEnumeration(DateTime value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1119.         {
  1120.             foreach (DateTime correctValue in enumeration) {
  1121.                 if (datatype.Compare(value, correctValue) == 0) {
  1122.                     return true;
  1123.                 }
  1124.             }
  1125.             return false;
  1126.         }
  1127.     }
  1128.    
  1129.     internal class StringFacetsChecker : FacetsChecker
  1130.     {
  1131.         //All types derived from string & anyURI
  1132.         static Regex languagePattern;
  1133.        
  1134.         static Regex LanguagePattern {
  1135.             get {
  1136.                 if (languagePattern == null) {
  1137.                     Regex langRegex = new Regex("^([a-zA-Z]{1,8})(-[a-zA-Z0-9]{1,8})*$", RegexOptions.None);
  1138.                     Interlocked.CompareExchange(ref languagePattern, langRegex, null);
  1139.                 }
  1140.                 return languagePattern;
  1141.             }
  1142.         }
  1143.        
  1144.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1145.         {
  1146.             string stringValue = datatype.ValueConverter.ToString(value);
  1147.             return CheckValueFacets(stringValue, datatype, true);
  1148.         }
  1149.        
  1150.         internal override Exception CheckValueFacets(string value, XmlSchemaDatatype datatype)
  1151.         {
  1152.             return CheckValueFacets(value, datatype, true);
  1153.         }
  1154.        
  1155.         internal Exception CheckValueFacets(string value, XmlSchemaDatatype datatype, bool verifyUri)
  1156.         {
  1157.             //Length, MinLength, MaxLength
  1158.             int length = value.Length;
  1159.             RestrictionFacets restriction = datatype.Restriction;
  1160.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1161.             Exception exception;
  1162.            
  1163.             exception = CheckBuiltInFacets(value, datatype.TypeCode, verifyUri);
  1164.             if (exception != null)
  1165.                 return exception;
  1166.            
  1167.             if (flags != 0) {
  1168.                 if ((flags & RestrictionFlags.Length) != 0) {
  1169.                     if (restriction.Length != length) {
  1170.                         return new XmlSchemaException(Res.Sch_LengthConstraintFailed, string.Empty);
  1171.                     }
  1172.                 }
  1173.                 if ((flags & RestrictionFlags.MinLength) != 0) {
  1174.                     if (length < restriction.MinLength) {
  1175.                         return new XmlSchemaException(Res.Sch_MinLengthConstraintFailed, string.Empty);
  1176.                     }
  1177.                 }
  1178.                 if ((flags & RestrictionFlags.MaxLength) != 0) {
  1179.                     if (restriction.MaxLength < length) {
  1180.                         return new XmlSchemaException(Res.Sch_MaxLengthConstraintFailed, string.Empty);
  1181.                     }
  1182.                 }
  1183.                 if ((flags & RestrictionFlags.Enumeration) != 0) {
  1184.                     if (!MatchEnumeration(value, restriction.Enumeration, datatype)) {
  1185.                         return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1186.                     }
  1187.                 }
  1188.             }
  1189.             return null;
  1190.         }
  1191.        
  1192.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1193.         {
  1194.             return MatchEnumeration(datatype.ValueConverter.ToString(value), enumeration, datatype);
  1195.         }
  1196.        
  1197.         private bool MatchEnumeration(string value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1198.         {
  1199.             if (datatype.TypeCode == XmlTypeCode.AnyUri) {
  1200.                 foreach (Uri correctValue in enumeration) {
  1201.                     if (value.Equals(correctValue.OriginalString)) {
  1202.                         return true;
  1203.                     }
  1204.                 }
  1205.             }
  1206.             else {
  1207.                 foreach (string correctValue in enumeration) {
  1208.                     if (value.Equals(correctValue)) {
  1209.                         return true;
  1210.                     }
  1211.                 }
  1212.             }
  1213.             return false;
  1214.         }
  1215.        
  1216.         private Exception CheckBuiltInFacets(string s, XmlTypeCode typeCode, bool verifyUri)
  1217.         {
  1218.             Exception exception = null;
  1219.            
  1220.             switch (typeCode) {
  1221.                 case XmlTypeCode.AnyUri:
  1222.                    
  1223.                     if (verifyUri) {
  1224.                         Uri uri;
  1225.                         exception = XmlConvert.TryToUri(s, out uri);
  1226.                     }
  1227.                     break;
  1228.                 case XmlTypeCode.NormalizedString:
  1229.                    
  1230.                     exception = XmlConvert.TryVerifyNormalizedString(s);
  1231.                     break;
  1232.                 case XmlTypeCode.Token:
  1233.                    
  1234.                     exception = XmlConvert.TryVerifyTOKEN(s);
  1235.                     break;
  1236.                 case XmlTypeCode.Language:
  1237.                    
  1238.                     if (s == null || s.Length == 0) {
  1239.                         return new XmlSchemaException(Res.Sch_EmptyAttributeValue, string.Empty);
  1240.                     }
  1241.                     if (!LanguagePattern.IsMatch(s)) {
  1242.                         return new XmlSchemaException(Res.Sch_InvalidLanguageId, string.Empty);
  1243.                     }
  1244.                     break;
  1245.                 case XmlTypeCode.NmToken:
  1246.                    
  1247.                     exception = XmlConvert.TryVerifyNMTOKEN(s);
  1248.                     break;
  1249.                 case XmlTypeCode.Name:
  1250.                    
  1251.                     exception = XmlConvert.TryVerifyName(s);
  1252.                     break;
  1253.                 case XmlTypeCode.NCName:
  1254.                 case XmlTypeCode.Id:
  1255.                 case XmlTypeCode.Idref:
  1256.                 case XmlTypeCode.Entity:
  1257.                    
  1258.                     exception = XmlConvert.TryVerifyNCName(s);
  1259.                     break;
  1260.                 default:
  1261.                     break;
  1262.             }
  1263.             return exception;
  1264.         }
  1265.     }
  1266.    
  1267.     internal class QNameFacetsChecker : FacetsChecker
  1268.     {
  1269.        
  1270.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1271.         {
  1272.             XmlQualifiedName qualifiedNameValue = (XmlQualifiedName)datatype.ValueConverter.ChangeType(value, typeof(XmlQualifiedName));
  1273.             return CheckValueFacets(qualifiedNameValue, datatype);
  1274.         }
  1275.        
  1276.         internal override Exception CheckValueFacets(XmlQualifiedName value, XmlSchemaDatatype datatype)
  1277.         {
  1278.             RestrictionFacets restriction = datatype.Restriction;
  1279.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1280.             if (flags != 0) {
  1281.                 //If there are facets defined
  1282.                 string strValue = value.ToString();
  1283.                 int length = strValue.Length;
  1284.                 if ((flags & RestrictionFlags.Length) != 0) {
  1285.                     if (restriction.Length != length) {
  1286.                         return new XmlSchemaException(Res.Sch_LengthConstraintFailed, string.Empty);
  1287.                     }
  1288.                 }
  1289.                 if ((flags & RestrictionFlags.MinLength) != 0) {
  1290.                     if (length < restriction.MinLength) {
  1291.                         return new XmlSchemaException(Res.Sch_MinLengthConstraintFailed, string.Empty);
  1292.                     }
  1293.                 }
  1294.                 if ((flags & RestrictionFlags.MaxLength) != 0) {
  1295.                     if (restriction.MaxLength < length) {
  1296.                         return new XmlSchemaException(Res.Sch_MaxLengthConstraintFailed, string.Empty);
  1297.                     }
  1298.                 }
  1299.                 if ((flags & RestrictionFlags.Enumeration) != 0) {
  1300.                     if (!MatchEnumeration(value, restriction.Enumeration)) {
  1301.                         return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1302.                     }
  1303.                 }
  1304.             }
  1305.             return null;
  1306.         }
  1307.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1308.         {
  1309.             return MatchEnumeration((XmlQualifiedName)datatype.ValueConverter.ChangeType(value, typeof(XmlQualifiedName)), enumeration);
  1310.         }
  1311.        
  1312.         private bool MatchEnumeration(XmlQualifiedName value, ArrayList enumeration)
  1313.         {
  1314.             foreach (XmlQualifiedName correctValue in enumeration) {
  1315.                 if (value.Equals(correctValue)) {
  1316.                     return true;
  1317.                 }
  1318.             }
  1319.             return false;
  1320.         }
  1321.     }
  1322.    
  1323.     internal class MiscFacetsChecker : FacetsChecker
  1324.     {
  1325.         //For bool, anySimpleType
  1326.     }
  1327.    
  1328.     internal class BinaryFacetsChecker : FacetsChecker
  1329.     {
  1330.         //hexBinary & Base64Binary
  1331.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1332.         {
  1333.             byte[] byteArrayValue = (byte[])value;
  1334.             return CheckValueFacets(byteArrayValue, datatype);
  1335.         }
  1336.        
  1337.         internal override Exception CheckValueFacets(byte[] value, XmlSchemaDatatype datatype)
  1338.         {
  1339.             //Length, MinLength, MaxLength
  1340.             RestrictionFacets restriction = datatype.Restriction;
  1341.             int length = value.Length;
  1342.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1343.             if (flags != 0) {
  1344.                 //if it has facets defined
  1345.                 if ((flags & RestrictionFlags.Length) != 0) {
  1346.                     if (restriction.Length != length) {
  1347.                         return new XmlSchemaException(Res.Sch_LengthConstraintFailed, string.Empty);
  1348.                     }
  1349.                 }
  1350.                 if ((flags & RestrictionFlags.MinLength) != 0) {
  1351.                     if (length < restriction.MinLength) {
  1352.                         return new XmlSchemaException(Res.Sch_MinLengthConstraintFailed, string.Empty);
  1353.                     }
  1354.                 }
  1355.                 if ((flags & RestrictionFlags.MaxLength) != 0) {
  1356.                     if (restriction.MaxLength < length) {
  1357.                         return new XmlSchemaException(Res.Sch_MaxLengthConstraintFailed, string.Empty);
  1358.                     }
  1359.                 }
  1360.                 if ((flags & RestrictionFlags.Enumeration) != 0) {
  1361.                     if (!MatchEnumeration(value, restriction.Enumeration, datatype)) {
  1362.                         return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1363.                     }
  1364.                 }
  1365.             }
  1366.             return null;
  1367.         }
  1368.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1369.         {
  1370.             return MatchEnumeration((byte[])value, enumeration, datatype);
  1371.         }
  1372.        
  1373.         private bool MatchEnumeration(byte[] value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1374.         {
  1375.             foreach (byte[] correctValue in enumeration) {
  1376.                 if (datatype.Compare(value, correctValue) == 0) {
  1377.                     return true;
  1378.                 }
  1379.             }
  1380.             return false;
  1381.         }
  1382.     }
  1383.    
  1384.     internal class ListFacetsChecker : FacetsChecker
  1385.     {
  1386.        
  1387.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1388.         {
  1389.             //Check for facets allowed on lists - Length, MinLength, MaxLength
  1390.             Array values = value as Array;
  1391.             Debug.Assert(values != null);
  1392.            
  1393.             RestrictionFacets restriction = datatype.Restriction;
  1394.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1395.            
  1396.             if ((flags & (RestrictionFlags.Length | RestrictionFlags.MinLength | RestrictionFlags.MaxLength)) != 0) {
  1397.                 int length = values.Length;
  1398.                 if ((flags & RestrictionFlags.Length) != 0) {
  1399.                     if (restriction.Length != length) {
  1400.                         return new XmlSchemaException(Res.Sch_LengthConstraintFailed, string.Empty);
  1401.                     }
  1402.                 }
  1403.                
  1404.                 if ((flags & RestrictionFlags.MinLength) != 0) {
  1405.                     if (length < restriction.MinLength) {
  1406.                         return new XmlSchemaException(Res.Sch_MinLengthConstraintFailed, string.Empty);
  1407.                     }
  1408.                 }
  1409.                
  1410.                 if ((flags & RestrictionFlags.MaxLength) != 0) {
  1411.                     if (restriction.MaxLength < length) {
  1412.                         return new XmlSchemaException(Res.Sch_MaxLengthConstraintFailed, string.Empty);
  1413.                     }
  1414.                 }
  1415.             }
  1416.             if ((flags & RestrictionFlags.Enumeration) != 0) {
  1417.                 if (!MatchEnumeration(value, restriction.Enumeration, datatype)) {
  1418.                     return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1419.                 }
  1420.             }
  1421.             return null;
  1422.         }
  1423.        
  1424.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1425.         {
  1426.             foreach (object correctArray in enumeration) {
  1427.                 if (datatype.Compare(value, correctArray) == 0) {
  1428.                     return true;
  1429.                 }
  1430.             }
  1431.             return false;
  1432.         }
  1433.     }
  1434.    
  1435.     internal class UnionFacetsChecker : FacetsChecker
  1436.     {
  1437.        
  1438.         internal override Exception CheckValueFacets(object value, XmlSchemaDatatype datatype)
  1439.         {
  1440.             RestrictionFacets restriction = datatype.Restriction;
  1441.             RestrictionFlags flags = restriction != null ? restriction.Flags : 0;
  1442.            
  1443.             if ((flags & RestrictionFlags.Enumeration) != 0) {
  1444.                 if (!MatchEnumeration(value, restriction.Enumeration, datatype)) {
  1445.                     return new XmlSchemaException(Res.Sch_EnumerationConstraintFailed, string.Empty);
  1446.                 }
  1447.             }
  1448.             return null;
  1449.         }
  1450.        
  1451.         internal override bool MatchEnumeration(object value, ArrayList enumeration, XmlSchemaDatatype datatype)
  1452.         {
  1453.             foreach (object correctValue in enumeration) {
  1454.                 if (datatype.Compare(value, correctValue) == 0) {
  1455.                     //Compare on Datatype_union will compare two XsdSimpleValue
  1456.                     return true;
  1457.                 }
  1458.             }
  1459.             return false;
  1460.         }
  1461.     }
  1462. }

Developer Fusion