The Labs \ Source Viewer \ SSCLI \ System.Xml \ XsdValidatingReader

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XsdValidatingReader.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.IO;
  16. using System.Text;
  17. using System.Xml.Schema;
  18. using System.Xml.XPath;
  19. using System.Diagnostics;
  20. using System.Globalization;
  21. using System.Collections;
  22. using System.Security.Policy;
  23. using System.Collections.Generic;
  24. namespace System.Xml
  25. {
  26.    
  27.     internal delegate void CachingEventHandler(XsdCachingReader cachingReader);
  28.    
  29.     internal class AttributePSVIInfo
  30.     {
  31.         internal string localName;
  32.         internal string namespaceUri;
  33.         internal object typedAttributeValue;
  34.         internal XmlSchemaInfo attributeSchemaInfo;
  35.        
  36.         internal AttributePSVIInfo()
  37.         {
  38.             attributeSchemaInfo = new XmlSchemaInfo();
  39.         }
  40.        
  41.         internal void Reset()
  42.         {
  43.             typedAttributeValue = null;
  44.             localName = string.Empty;
  45.             namespaceUri = string.Empty;
  46.             attributeSchemaInfo.Clear();
  47.         }
  48.     }
  49.    
  50.     internal class XsdValidatingReader : XmlReader, IXmlSchemaInfo, IXmlLineInfo, IXmlNamespaceResolver
  51.     {
  52.        
  53.         private enum ValidatingReaderState
  54.         {
  55.             None = 0,
  56.             Init = 1,
  57.             Read = 2,
  58.             OnDefaultAttribute = -1,
  59.             OnReadAttributeValue = -2,
  60.             OnAttribute = 3,
  61.             ClearAttributes = 4,
  62.             ParseInlineSchema = 5,
  63.             ReadAhead = 6,
  64.             OnReadBinaryContent = 7,
  65.             ReaderClosed = 8,
  66.             EOF = 9,
  67.             Error = 10
  68.         }
  69.         //Validation
  70.         private XmlReader coreReader;
  71.         private IXmlNamespaceResolver coreReaderNSResolver;
  72.         private IXmlNamespaceResolver thisNSResolver;
  73.         private XmlSchemaValidator validator;
  74.         private XmlResolver xmlResolver;
  75.         private ValidationEventHandler validationEvent;
  76.         private ValidatingReaderState validationState;
  77.         private XmlValueGetter valueGetter;
  78.        
  79.         // namespace management
  80.         XmlNamespaceManager nsManager;
  81.         bool manageNamespaces;
  82.         bool processInlineSchema;
  83.         bool replayCache;
  84.        
  85.         //Current Node handling
  86.         private ValidatingReaderNodeData cachedNode;
  87.         //Used to cache current node when looking ahead or default attributes
  88.         private AttributePSVIInfo attributePSVI;
  89.        
  90.         //Attributes
  91.         int attributeCount;
  92.         //Total count of attributes including default
  93.         int coreReaderAttributeCount;
  94.         int currentAttrIndex;
  95.         AttributePSVIInfo[] attributePSVINodes;
  96.         ArrayList defaultAttributes;
  97.        
  98.         //Inline Schema
  99.         private Parser inlineSchemaParser = null;
  100.        
  101.         //Typed Value & PSVI
  102.         private object atomicValue;
  103.         private XmlSchemaInfo xmlSchemaInfo;
  104.        
  105.        
  106.         //cached coreReader information
  107.         private XmlNameTable coreReaderNameTable;
  108.         private XsdCachingReader cachingReader;
  109.        
  110.         //ReadAttributeValue TextNode
  111.         private ValidatingReaderNodeData textNode;
  112.        
  113.         //To avoid SchemaNames creation
  114.         private string NsXmlNs;
  115.         private string NsXs;
  116.         private string NsXsi;
  117.         private string XsiType;
  118.         private string XsiNil;
  119.         private string XsdSchema;
  120.         private string XsiSchemaLocation;
  121.         private string XsiNoNamespaceSchemaLocation;
  122.        
  123.         //XmlCharType instance
  124.         private XmlCharType xmlCharType = XmlCharType.Instance;
  125.        
  126.         //Underlying reader's IXmlLineInfo
  127.         IXmlLineInfo lineInfo;
  128.        
  129.         // helpers for Read[Element]ContentAs{Base64,BinHex} methods
  130.         ReadContentAsBinaryHelper readBinaryHelper;
  131.         ValidatingReaderState savedState;
  132.        
  133.         //Constants
  134.         private const int InitialAttributeCount = 8;
  135.        
  136.         static Type TypeOfString;
  137.        
  138.         //Constructor
  139.         internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings, XmlSchemaObject partialValidationType)
  140.         {
  141.             this.coreReader = reader;
  142.             this.coreReaderNSResolver = reader as IXmlNamespaceResolver;
  143.             this.lineInfo = reader as IXmlLineInfo;
  144.             coreReaderNameTable = coreReader.NameTable;
  145.             if (coreReaderNSResolver == null) {
  146.                 nsManager = new XmlNamespaceManager(coreReaderNameTable);
  147.                 manageNamespaces = true;
  148.             }
  149.             thisNSResolver = this as IXmlNamespaceResolver;
  150.             this.xmlResolver = xmlResolver;
  151.             this.processInlineSchema = (readerSettings.ValidationFlags & XmlSchemaValidationFlags.ProcessInlineSchema) != 0;
  152.             Init();
  153.             SetupValidator(readerSettings, reader, partialValidationType);
  154.             validationEvent = readerSettings.GetEventHandler();
  155.         }
  156.        
  157.         internal XsdValidatingReader(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings) : this(reader, xmlResolver, readerSettings, null)
  158.         {
  159.         }
  160.        
  161.         private void Init()
  162.         {
  163.             validationState = ValidatingReaderState.Init;
  164.             defaultAttributes = new ArrayList();
  165.             currentAttrIndex = -1;
  166.             attributePSVINodes = new AttributePSVIInfo[InitialAttributeCount];
  167.             valueGetter = new XmlValueGetter(GetStringValue);
  168.             TypeOfString = typeof(string);
  169.             xmlSchemaInfo = new XmlSchemaInfo();
  170.            
  171.             //Add common strings to be compared to NameTable
  172.             NsXmlNs = coreReaderNameTable.Add(XmlReservedNs.NsXmlNs);
  173.             NsXs = coreReaderNameTable.Add(XmlReservedNs.NsXs);
  174.             NsXsi = coreReaderNameTable.Add(XmlReservedNs.NsXsi);
  175.             XsiType = coreReaderNameTable.Add("type");
  176.             XsiNil = coreReaderNameTable.Add("nil");
  177.             XsiSchemaLocation = coreReaderNameTable.Add("schemaLocation");
  178.             XsiNoNamespaceSchemaLocation = coreReaderNameTable.Add("noNamespaceSchemaLocation");
  179.             XsdSchema = coreReaderNameTable.Add("schema");
  180.         }
  181.        
  182.         private void SetupValidator(XmlReaderSettings readerSettings, XmlReader reader, XmlSchemaObject partialValidationType)
  183.         {
  184.             validator = new XmlSchemaValidator(coreReaderNameTable, readerSettings.Schemas, thisNSResolver, readerSettings.ValidationFlags);
  185.             validator.XmlResolver = this.xmlResolver;
  186.             validator.SourceUri = XmlConvert.ToUri(reader.BaseURI);
  187.             //Not using XmlResolver.ResolveUri as it checks for relative Uris,reader.BaseURI will be absolute file paths or string.Empty
  188.             validator.ValidationEventSender = this;
  189.             validator.ValidationEventHandler += readerSettings.GetEventHandler();
  190.             validator.LineInfoProvider = this.lineInfo;
  191.             if (validator.ProcessSchemaHints) {
  192.                 validator.SchemaSet.ReaderSettings.ProhibitDtd = readerSettings.ProhibitDtd;
  193.             }
  194.             validator.SetDtdSchemaInfo(XmlReader.GetDtdSchemaInfo(reader));
  195.             if (partialValidationType != null) {
  196.                 validator.Initialize(partialValidationType);
  197.             }
  198.             else {
  199.                 validator.Initialize();
  200.             }
  201.         }
  202.        
  203.         // Settings
  204.         public override XmlReaderSettings Settings {
  205.             get {
  206.                 XmlReaderSettings settings = coreReader.Settings;
  207.                 if (null != settings)
  208.                     settings = settings.Clone();
  209.                 if (settings == null) {
  210.                     settings = new XmlReaderSettings();
  211.                 }
  212.                 settings.Schemas = validator.SchemaSet;
  213.                 settings.ValidationType = ValidationType.Schema;
  214.                 settings.ValidationFlags = validator.ValidationFlags;
  215.                 settings.ReadOnly = true;
  216.                 return settings;
  217.             }
  218.         }
  219.        
  220.         // Node Properties
  221.        
  222.         // Gets the type of the current node.
  223.         public override XmlNodeType NodeType {
  224.             get {
  225.                 if ((int)validationState < 0) {
  226.                     return cachedNode.NodeType;
  227.                 }
  228.                 return coreReader.NodeType;
  229.             }
  230.         }
  231.        
  232.         // Gets the name of the current node, including the namespace prefix.
  233.         public override string Name {
  234.             get {
  235.                 if (validationState == ValidatingReaderState.OnDefaultAttribute) {
  236.                     string prefix = validator.GetDefaultAttributePrefix(cachedNode.Namespace);
  237.                     if (prefix != null && prefix.Length != 0) {
  238.                         return string.Concat(prefix + ":" + cachedNode.LocalName);
  239.                     }
  240.                     return cachedNode.LocalName;
  241.                 }
  242.                 return coreReader.Name;
  243.             }
  244.         }
  245.        
  246.         // Gets the name of the current node without the namespace prefix.
  247.         public override string LocalName {
  248.             get {
  249.                 if ((int)validationState < 0) {
  250.                     return cachedNode.LocalName;
  251.                 }
  252.                 return coreReader.LocalName;
  253.             }
  254.         }
  255.        
  256.         // Gets the namespace URN (as defined in the W3C Namespace Specification) of the current namespace scope.
  257.         public override string NamespaceURI {
  258.             get {
  259.                 if ((int)validationState < 0) {
  260.                     return cachedNode.Namespace;
  261.                 }
  262.                 return coreReader.NamespaceURI;
  263.             }
  264.         }
  265.        
  266.         // Gets the namespace prefix associated with the current node.
  267.         public override string Prefix {
  268.             get {
  269.                 if ((int)validationState < 0) {
  270.                     return cachedNode.Prefix;
  271.                 }
  272.                 return coreReader.Prefix;
  273.             }
  274.         }
  275.        
  276.         // Gets a value indicating whether the current node can have a non-empty Value
  277.         public override bool HasValue {
  278.             get {
  279.                 if ((int)validationState < 0) {
  280.                     return true;
  281.                 }
  282.                 return coreReader.HasValue;
  283.             }
  284.         }
  285.        
  286.         // Gets the text value of the current node.
  287.         public override string Value {
  288.             get {
  289.                 if ((int)validationState < 0) {
  290.                     return cachedNode.RawValue;
  291.                 }
  292.                 return coreReader.Value;
  293.             }
  294.         }
  295.        
  296.         // Gets the depth of the current node in the XML element stack.
  297.         public override int Depth {
  298.             get {
  299.                 if ((int)validationState < 0) {
  300.                     return cachedNode.Depth;
  301.                 }
  302.                 return coreReader.Depth;
  303.             }
  304.         }
  305.        
  306.         // Gets the base URI of the current node.
  307.         public override string BaseURI {
  308.             get { return coreReader.BaseURI; }
  309.         }
  310.        
  311.         // Gets a value indicating whether the current node is an empty element (for example, <MyElement/>).
  312.         public override bool IsEmptyElement {
  313.             get { return coreReader.IsEmptyElement; }
  314.         }
  315.        
  316.         // Gets a value indicating whether the current node is an attribute that was generated from the default value defined
  317.         // in the DTD or schema.
  318.         public override bool IsDefault {
  319.             get {
  320.                 if (validationState == ValidatingReaderState.OnDefaultAttribute) {
  321.                     //XSD default attributes
  322.                     return true;
  323.                 }
  324.                 return coreReader.IsDefault;
  325.                 //This is DTD Default attribute
  326.             }
  327.         }
  328.        
  329.         // Gets the quotation mark character used to enclose the value of an attribute node.
  330.         public override char QuoteChar {
  331.             get { return coreReader.QuoteChar; }
  332.         }
  333.        
  334.         // Gets the current xml:space scope.
  335.         public override XmlSpace XmlSpace {
  336.             get { return coreReader.XmlSpace; }
  337.         }
  338.        
  339.         // Gets the current xml:lang scope.
  340.         public override string XmlLang {
  341.             get { return coreReader.XmlLang; }
  342.         }
  343.        
  344.         public override IXmlSchemaInfo SchemaInfo {
  345.             get { return this as IXmlSchemaInfo; }
  346.         }
  347.        
  348.         public override System.Type ValueType {
  349.             get {
  350.                 switch (NodeType) {
  351.                     case XmlNodeType.Element:
  352.                     case XmlNodeType.EndElement:
  353.                         //TODO Check that context is not popped to parents in the validator
  354.                         if (xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) {
  355.                             return xmlSchemaInfo.SchemaType.Datatype.ValueType;
  356.                         }
  357.                         goto default;
  358.                         break;
  359.                     case XmlNodeType.Attribute:
  360.                        
  361.                         if (attributePSVI != null && AttributeSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) {
  362.                             return AttributeSchemaInfo.SchemaType.Datatype.ValueType;
  363.                         }
  364.                         goto default;
  365.                         break;
  366.                     default:
  367.                        
  368.                         return TypeOfString;
  369.                 }
  370.             }
  371.         }
  372.        
  373.         public override object ReadContentAsObject()
  374.         {
  375.             if (!CanReadContentAs(this.NodeType)) {
  376.                 throw CreateReadContentAsException("ReadContentAsObject");
  377.             }
  378.             return InternalReadContentAsObject(true);
  379.         }
  380.        
  381.         public override bool ReadContentAsBoolean()
  382.         {
  383.             if (!CanReadContentAs(this.NodeType)) {
  384.                 throw CreateReadContentAsException("ReadContentAsBoolean");
  385.             }
  386.             object typedValue = InternalReadContentAsObject();
  387.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  388.             try {
  389.                 if (xmlType != null) {
  390.                     return xmlType.ValueConverter.ToBoolean(typedValue);
  391.                 }
  392.                 else {
  393.                     return XmlUntypedConverter.Untyped.ToBoolean(typedValue);
  394.                 }
  395.             }
  396.             catch (InvalidCastException e) {
  397.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
  398.             }
  399.             catch (FormatException e) {
  400.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
  401.             }
  402.             catch (OverflowException e) {
  403.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
  404.             }
  405.         }
  406.        
  407.         public override DateTime ReadContentAsDateTime()
  408.         {
  409.             if (!CanReadContentAs(this.NodeType)) {
  410.                 throw CreateReadContentAsException("ReadContentAsDateTime");
  411.             }
  412.             object typedValue = InternalReadContentAsObject();
  413.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  414.             try {
  415.                 if (xmlType != null) {
  416.                     return xmlType.ValueConverter.ToDateTime(typedValue);
  417.                 }
  418.                 else {
  419.                     return XmlUntypedConverter.Untyped.ToDateTime(typedValue);
  420.                 }
  421.             }
  422.             catch (InvalidCastException e) {
  423.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
  424.             }
  425.             catch (FormatException e) {
  426.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
  427.             }
  428.             catch (OverflowException e) {
  429.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
  430.             }
  431.         }
  432.        
  433.         public override double ReadContentAsDouble()
  434.         {
  435.             if (!CanReadContentAs(this.NodeType)) {
  436.                 throw CreateReadContentAsException("ReadContentAsDouble");
  437.             }
  438.             object typedValue = InternalReadContentAsObject();
  439.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  440.             try {
  441.                 if (xmlType != null) {
  442.                     return xmlType.ValueConverter.ToDouble(typedValue);
  443.                 }
  444.                 else {
  445.                     return XmlUntypedConverter.Untyped.ToDouble(typedValue);
  446.                 }
  447.             }
  448.             catch (InvalidCastException e) {
  449.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
  450.             }
  451.             catch (FormatException e) {
  452.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
  453.             }
  454.             catch (OverflowException e) {
  455.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
  456.             }
  457.         }
  458.        
  459.         public override float ReadContentAsFloat()
  460.         {
  461.             if (!CanReadContentAs(this.NodeType)) {
  462.                 throw CreateReadContentAsException("ReadContentAsFloat");
  463.             }
  464.             object typedValue = InternalReadContentAsObject();
  465.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  466.             try {
  467.                 if (xmlType != null) {
  468.                     return xmlType.ValueConverter.ToSingle(typedValue);
  469.                 }
  470.                 else {
  471.                     return XmlUntypedConverter.Untyped.ToSingle(typedValue);
  472.                 }
  473.             }
  474.             catch (InvalidCastException e) {
  475.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
  476.             }
  477.             catch (FormatException e) {
  478.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
  479.             }
  480.             catch (OverflowException e) {
  481.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
  482.             }
  483.         }
  484.        
  485.         public override decimal ReadContentAsDecimal()
  486.         {
  487.             if (!CanReadContentAs(this.NodeType)) {
  488.                 throw CreateReadContentAsException("ReadContentAsDecimal");
  489.             }
  490.             object typedValue = InternalReadContentAsObject();
  491.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  492.             try {
  493.                 if (xmlType != null) {
  494.                     return xmlType.ValueConverter.ToDecimal(typedValue);
  495.                 }
  496.                 else {
  497.                     return XmlUntypedConverter.Untyped.ToDecimal(typedValue);
  498.                 }
  499.             }
  500.             catch (InvalidCastException e) {
  501.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
  502.             }
  503.             catch (FormatException e) {
  504.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
  505.             }
  506.             catch (OverflowException e) {
  507.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
  508.             }
  509.         }
  510.        
  511.         public override int ReadContentAsInt()
  512.         {
  513.             if (!CanReadContentAs(this.NodeType)) {
  514.                 throw CreateReadContentAsException("ReadContentAsInt");
  515.             }
  516.             object typedValue = InternalReadContentAsObject();
  517.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  518.             try {
  519.                 if (xmlType != null) {
  520.                     return xmlType.ValueConverter.ToInt32(typedValue);
  521.                 }
  522.                 else {
  523.                     return XmlUntypedConverter.Untyped.ToInt32(typedValue);
  524.                 }
  525.             }
  526.             catch (InvalidCastException e) {
  527.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
  528.             }
  529.             catch (FormatException e) {
  530.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
  531.             }
  532.             catch (OverflowException e) {
  533.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
  534.             }
  535.         }
  536.        
  537.         public override long ReadContentAsLong()
  538.         {
  539.             if (!CanReadContentAs(this.NodeType)) {
  540.                 throw CreateReadContentAsException("ReadContentAsLong");
  541.             }
  542.             object typedValue = InternalReadContentAsObject();
  543.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  544.             try {
  545.                 if (xmlType != null) {
  546.                     return xmlType.ValueConverter.ToInt64(typedValue);
  547.                 }
  548.                 else {
  549.                     return XmlUntypedConverter.Untyped.ToInt64(typedValue);
  550.                 }
  551.             }
  552.             catch (InvalidCastException e) {
  553.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
  554.             }
  555.             catch (FormatException e) {
  556.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
  557.             }
  558.             catch (OverflowException e) {
  559.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
  560.             }
  561.         }
  562.        
  563.         public override string ReadContentAsString()
  564.         {
  565.             if (!CanReadContentAs(this.NodeType)) {
  566.                 throw CreateReadContentAsException("ReadContentAsString");
  567.             }
  568.             object typedValue = InternalReadContentAsObject();
  569.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  570.             try {
  571.                 if (xmlType != null) {
  572.                     return xmlType.ValueConverter.ToString(typedValue);
  573.                 }
  574.                 else {
  575.                     return typedValue as string;
  576.                 }
  577.             }
  578.             catch (InvalidCastException e) {
  579.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "String", e, this as IXmlLineInfo);
  580.             }
  581.             catch (FormatException e) {
  582.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "String", e, this as IXmlLineInfo);
  583.             }
  584.             catch (OverflowException e) {
  585.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "String", e, this as IXmlLineInfo);
  586.             }
  587.         }
  588.        
  589.         public override object ReadContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver)
  590.         {
  591.             if (!CanReadContentAs(this.NodeType)) {
  592.                 throw CreateReadContentAsException("ReadContentAs");
  593.             }
  594.             object typedValue = InternalReadContentAsObject();
  595.             XmlSchemaType xmlType = NodeType == XmlNodeType.Attribute ? AttributeXmlType : ElementXmlType;
  596.             //TODO special case for xsd:duration and xsd:dateTime
  597.             try {
  598.                 if (xmlType != null) {
  599.                     /*if (typedValue.GetType() == typeof(System.TimeSpan)) { //Special case for XsdDuration
  600.                         return xmlType.ValueConverter.ChangeType(validator.GetConcatenatedValue(), type);
  601.                     }*/                   
  602. return xmlType.ValueConverter.ChangeType(typedValue, returnType);
  603.                 }
  604.                 else {
  605.                     return XmlUntypedConverter.Untyped.ChangeType(typedValue, returnType, namespaceResolver);
  606.                 }
  607.             }
  608.             catch (FormatException e) {
  609.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
  610.             }
  611.             catch (InvalidCastException e) {
  612.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
  613.             }
  614.             catch (OverflowException e) {
  615.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
  616.             }
  617.         }
  618.        
  619.         public override object ReadElementContentAsObject()
  620.         {
  621.             if (this.NodeType != XmlNodeType.Element) {
  622.                 throw CreateReadElementContentAsException("ReadElementContentAsObject");
  623.             }
  624.             XmlSchemaType xmlType;
  625.             return InternalReadElementContentAsObject(out xmlType, true);
  626.         }
  627.        
  628.         public override bool ReadElementContentAsBoolean()
  629.         {
  630.             if (this.NodeType != XmlNodeType.Element) {
  631.                 throw CreateReadElementContentAsException("ReadElementContentAsBoolean");
  632.             }
  633.             XmlSchemaType xmlType;
  634.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  635.             try {
  636.                 if (xmlType != null) {
  637.                     return xmlType.ValueConverter.ToBoolean(typedValue);
  638.                 }
  639.                 else {
  640.                     return XmlUntypedConverter.Untyped.ToBoolean(typedValue);
  641.                 }
  642.             }
  643.             catch (FormatException e) {
  644.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
  645.             }
  646.             catch (InvalidCastException e) {
  647.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
  648.             }
  649.             catch (OverflowException e) {
  650.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
  651.             }
  652.         }
  653.        
  654.         public override DateTime ReadElementContentAsDateTime()
  655.         {
  656.             if (this.NodeType != XmlNodeType.Element) {
  657.                 throw CreateReadElementContentAsException("ReadElementContentAsDateTime");
  658.             }
  659.             XmlSchemaType xmlType;
  660.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  661.             try {
  662.                 if (xmlType != null) {
  663.                     return xmlType.ValueConverter.ToDateTime(typedValue);
  664.                 }
  665.                 else {
  666.                     return XmlUntypedConverter.Untyped.ToDateTime(typedValue);
  667.                 }
  668.             }
  669.             catch (FormatException e) {
  670.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
  671.             }
  672.             catch (InvalidCastException e) {
  673.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
  674.             }
  675.             catch (OverflowException e) {
  676.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
  677.             }
  678.         }
  679.        
  680.         public override double ReadElementContentAsDouble()
  681.         {
  682.             if (this.NodeType != XmlNodeType.Element) {
  683.                 throw CreateReadElementContentAsException("ReadElementContentAsDouble");
  684.             }
  685.             XmlSchemaType xmlType;
  686.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  687.             try {
  688.                 if (xmlType != null) {
  689.                     return xmlType.ValueConverter.ToDouble(typedValue);
  690.                 }
  691.                 else {
  692.                     return XmlUntypedConverter.Untyped.ToDouble(typedValue);
  693.                 }
  694.             }
  695.             catch (FormatException e) {
  696.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
  697.             }
  698.             catch (InvalidCastException e) {
  699.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
  700.             }
  701.             catch (OverflowException e) {
  702.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
  703.             }
  704.         }
  705.        
  706.         public override float ReadElementContentAsFloat()
  707.         {
  708.             if (this.NodeType != XmlNodeType.Element) {
  709.                 throw CreateReadElementContentAsException("ReadElementContentAsFloat");
  710.             }
  711.             XmlSchemaType xmlType;
  712.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  713.             try {
  714.                 if (xmlType != null) {
  715.                     return xmlType.ValueConverter.ToSingle(typedValue);
  716.                 }
  717.                 else {
  718.                     return XmlUntypedConverter.Untyped.ToSingle(typedValue);
  719.                 }
  720.             }
  721.             catch (FormatException e) {
  722.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
  723.             }
  724.             catch (InvalidCastException e) {
  725.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
  726.             }
  727.             catch (OverflowException e) {
  728.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
  729.             }
  730.         }
  731.        
  732.         public override decimal ReadElementContentAsDecimal()
  733.         {
  734.             if (this.NodeType != XmlNodeType.Element) {
  735.                 throw CreateReadElementContentAsException("ReadElementContentAsDecimal");
  736.             }
  737.             XmlSchemaType xmlType;
  738.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  739.             try {
  740.                 if (xmlType != null) {
  741.                     return xmlType.ValueConverter.ToDecimal(typedValue);
  742.                 }
  743.                 else {
  744.                     return XmlUntypedConverter.Untyped.ToDecimal(typedValue);
  745.                 }
  746.             }
  747.             catch (FormatException e) {
  748.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
  749.             }
  750.             catch (InvalidCastException e) {
  751.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
  752.             }
  753.             catch (OverflowException e) {
  754.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
  755.             }
  756.         }
  757.        
  758.         public override int ReadElementContentAsInt()
  759.         {
  760.             if (this.NodeType != XmlNodeType.Element) {
  761.                 throw CreateReadElementContentAsException("ReadElementContentAsInt");
  762.             }
  763.             XmlSchemaType xmlType;
  764.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  765.             try {
  766.                 if (xmlType != null) {
  767.                     return xmlType.ValueConverter.ToInt32(typedValue);
  768.                 }
  769.                 else {
  770.                     return XmlUntypedConverter.Untyped.ToInt32(typedValue);
  771.                 }
  772.             }
  773.             catch (FormatException e) {
  774.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
  775.             }
  776.             catch (InvalidCastException e) {
  777.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
  778.             }
  779.             catch (OverflowException e) {
  780.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
  781.             }
  782.         }
  783.        
  784.         public override long ReadElementContentAsLong()
  785.         {
  786.             if (this.NodeType != XmlNodeType.Element) {
  787.                 throw CreateReadElementContentAsException("ReadElementContentAsLong");
  788.             }
  789.             XmlSchemaType xmlType;
  790.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  791.             try {
  792.                 if (xmlType != null) {
  793.                     return xmlType.ValueConverter.ToInt64(typedValue);
  794.                 }
  795.                 else {
  796.                     return XmlUntypedConverter.Untyped.ToInt64(typedValue);
  797.                 }
  798.             }
  799.             catch (FormatException e) {
  800.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
  801.             }
  802.             catch (InvalidCastException e) {
  803.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
  804.             }
  805.             catch (OverflowException e) {
  806.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
  807.             }
  808.         }
  809.        
  810.         public override string ReadElementContentAsString()
  811.         {
  812.             if (this.NodeType != XmlNodeType.Element) {
  813.                 throw CreateReadElementContentAsException("ReadElementContentAsString");
  814.             }
  815.             XmlSchemaType xmlType;
  816.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  817.             try {
  818.                 if (xmlType != null) {
  819.                     return xmlType.ValueConverter.ToString(typedValue);
  820.                 }
  821.                 else {
  822.                     return typedValue as string;
  823.                 }
  824.             }
  825.             catch (InvalidCastException e) {
  826.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "String", e, this as IXmlLineInfo);
  827.             }
  828.             catch (FormatException e) {
  829.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "String", e, this as IXmlLineInfo);
  830.             }
  831.             catch (OverflowException e) {
  832.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, "String", e, this as IXmlLineInfo);
  833.             }
  834.         }
  835.        
  836.         public override object ReadElementContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver)
  837.         {
  838.             if (this.NodeType != XmlNodeType.Element) {
  839.                 throw CreateReadElementContentAsException("ReadElementContentAs");
  840.             }
  841.             XmlSchemaType xmlType;
  842.             object typedValue = InternalReadElementContentAsObject(out xmlType);
  843.             try {
  844.                 if (xmlType != null) {
  845.                     return xmlType.ValueConverter.ChangeType(typedValue, returnType, namespaceResolver);
  846.                 }
  847.                 else {
  848.                     return XmlUntypedConverter.Untyped.ChangeType(typedValue, returnType, namespaceResolver);
  849.                 }
  850.             }
  851.             catch (FormatException e) {
  852.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
  853.             }
  854.             catch (InvalidCastException e) {
  855.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
  856.             }
  857.             catch (OverflowException e) {
  858.                 throw new XmlException(Res.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
  859.             }
  860.         }
  861.        
  862.         // Attribute Accessors
  863.        
  864.         // The number of attributes on the current node.
  865.         public override int AttributeCount {
  866.             get { return attributeCount; }
  867.         }
  868.        
  869.         // Gets the value of the attribute with the specified Name.
  870.         public override string GetAttribute(string name)
  871.         {
  872.             string attValue = coreReader.GetAttribute(name);
  873.            
  874.             if (attValue == null && attributeCount > 0) {
  875.                 //Could be default attribute
  876.                 ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, false);
  877.                 if (defaultNode != null) {
  878.                     //Default found
  879.                     attValue = defaultNode.RawValue;
  880.                 }
  881.             }
  882.             return attValue;
  883.         }
  884.        
  885.         // Gets the value of the attribute with the specified LocalName and NamespaceURI.
  886.         public override string GetAttribute(string name, string namespaceURI)
  887.         {
  888.             string attValue = coreReader.GetAttribute(name, namespaceURI);
  889.            
  890.             if (attValue == null && attributeCount > 0) {
  891.                 //Could be default attribute
  892.                 namespaceURI = (namespaceURI == null) ? string.Empty : coreReaderNameTable.Get(namespaceURI);
  893.                 name = coreReaderNameTable.Get(name);
  894.                 if (name == null || namespaceURI == null) {
  895.                     //Attribute not present since we did not see it
  896.                     return null;
  897.                 }
  898.                 ValidatingReaderNodeData attNode = GetDefaultAttribute(name, namespaceURI, false);
  899.                 if (attNode != null) {
  900.                     return attNode.RawValue;
  901.                 }
  902.             }
  903.             return attValue;
  904.         }
  905.        
  906.         // Gets the value of the attribute with the specified index.
  907.         public override string GetAttribute(int i)
  908.         {
  909.             if (attributeCount == 0) {
  910.                 return null;
  911.             }
  912.            
  913.             if (i < coreReaderAttributeCount) {
  914.                 return coreReader.GetAttribute(i);
  915.             }
  916.             else {
  917.                 int defaultIndex = i - coreReaderAttributeCount;
  918.                 ValidatingReaderNodeData attNode = (ValidatingReaderNodeData)defaultAttributes[defaultIndex];
  919.                 Debug.Assert(attNode != null);
  920.                 return attNode.RawValue;
  921.             }
  922.         }
  923.        
  924.         // Moves to the attribute with the specified Name
  925.         public override bool MoveToAttribute(string name)
  926.         {
  927.            
  928.             if (coreReader.MoveToAttribute(name)) {
  929.                 validationState = ValidatingReaderState.OnAttribute;
  930.                 attributePSVI = GetAttributePSVI(name);
  931.                 goto Found;
  932.             }
  933.             else if (attributeCount > 0) {
  934.                 //Default attribute
  935.                 ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, true);
  936.                 if (defaultNode != null) {
  937.                     validationState = ValidatingReaderState.OnDefaultAttribute;
  938.                     attributePSVI = defaultNode.AttInfo;
  939.                     cachedNode = defaultNode;
  940.                     goto Found;
  941.                 }
  942.             }
  943.             return false;
  944.             Found:
  945.             if (validationState == ValidatingReaderState.OnReadBinaryContent) {
  946.                 readBinaryHelper.Finish();
  947.                 validationState = savedState;
  948.             }
  949.             return true;
  950.         }
  951.        
  952.        
  953.         // Moves to the attribute with the specified LocalName and NamespaceURI
  954.         public override bool MoveToAttribute(string name, string ns)
  955.         {
  956.             //Check atomized local name and ns
  957.             name = coreReaderNameTable.Get(name);
  958.             ns = ns != null ? coreReaderNameTable.Get(ns) : string.Empty;
  959.             if (name == null || ns == null) {
  960.                 //Name or ns not found in the nameTable, then attribute is not found
  961.                 return false;
  962.             }
  963.             if (coreReader.MoveToAttribute(name, ns)) {
  964.                 validationState = ValidatingReaderState.OnAttribute;
  965.                 if (inlineSchemaParser == null) {
  966.                     attributePSVI = GetAttributePSVI(name, ns);
  967.                     Debug.Assert(attributePSVI != null);
  968.                 }
  969.                 else {
  970.                     //Parsing inline schema, no PSVI for schema attributes
  971.                     attributePSVI = null;
  972.                 }
  973.                 goto Found;
  974.             }
  975.             else {
  976.                 //Default attribute
  977.                 ValidatingReaderNodeData defaultNode = GetDefaultAttribute(name, ns, true);
  978.                 if (defaultNode != null) {
  979.                     attributePSVI = defaultNode.AttInfo;
  980.                     cachedNode = defaultNode;
  981.                     validationState = ValidatingReaderState.OnDefaultAttribute;
  982.                     goto Found;
  983.                 }
  984.             }
  985.             return false;
  986.             Found:
  987.             if (validationState == ValidatingReaderState.OnReadBinaryContent) {
  988.                 readBinaryHelper.Finish();
  989.                 validationState = savedState;
  990.             }
  991.             return true;
  992.         }
  993.        
  994.         // Moves to the attribute with the specified index
  995.         public override void MoveToAttribute(int i)
  996.         {
  997.             if (i < 0 || i >= attributeCount) {
  998.                 throw new ArgumentOutOfRangeException("i");
  999.             }
  1000.            
  1001.             if (i < coreReaderAttributeCount) {
  1002.                 //reader attribute
  1003.                 coreReader.MoveToAttribute(i);
  1004.                 if (inlineSchemaParser == null) {
  1005.                     attributePSVI = attributePSVINodes[i];
  1006.                 }
  1007.                 else {
  1008.                     attributePSVI = null;
  1009.                 }
  1010.                 validationState = ValidatingReaderState.OnAttribute;
  1011.             }
  1012.             else {
  1013.                 //default attribute
  1014.                 int defaultIndex = i - coreReaderAttributeCount;
  1015.                 cachedNode = (ValidatingReaderNodeData)defaultAttributes[defaultIndex];
  1016.                 attributePSVI = cachedNode.AttInfo;
  1017.                 validationState = ValidatingReaderState.OnDefaultAttribute;
  1018.             }
  1019.             if (validationState == ValidatingReaderState.OnReadBinaryContent) {
  1020.                 readBinaryHelper.Finish();
  1021.                 validationState = savedState;
  1022.             }
  1023.         }
  1024.        
  1025.         // Moves to the first attribute.
  1026.         public override bool MoveToFirstAttribute()
  1027.         {
  1028.             if (coreReader.MoveToFirstAttribute()) {
  1029.                 currentAttrIndex = 0;
  1030.                 if (inlineSchemaParser == null) {
  1031.                     attributePSVI = attributePSVINodes[0];
  1032.                 }
  1033.                 else {
  1034.                     attributePSVI = null;
  1035.                 }
  1036.                 validationState = ValidatingReaderState.OnAttribute;
  1037.                 goto Found;
  1038.             }
  1039.             else if (defaultAttributes.Count > 0) {
  1040.                 //check for default
  1041.                 cachedNode = (ValidatingReaderNodeData)defaultAttributes[0];
  1042.                 attributePSVI = cachedNode.AttInfo;
  1043.                 currentAttrIndex = 0;
  1044.                 validationState = ValidatingReaderState.OnDefaultAttribute;
  1045.                 goto Found;
  1046.             }
  1047.             return false;
  1048.             Found:
  1049.             if (validationState == ValidatingReaderState.OnReadBinaryContent) {
  1050.                 readBinaryHelper.Finish();
  1051.                 validationState = savedState;
  1052.             }
  1053.             return true;
  1054.         }
  1055.        
  1056.         // Moves to the next attribute.
  1057.         public override bool MoveToNextAttribute()
  1058.         {
  1059.             if (currentAttrIndex + 1 < coreReaderAttributeCount) {
  1060.                 bool moveTo = coreReader.MoveToNextAttribute();
  1061.                 Debug.Assert(moveTo);
  1062.                 currentAttrIndex++;
  1063.                 if (inlineSchemaParser == null) {
  1064.                     attributePSVI = attributePSVINodes[currentAttrIndex];
  1065.                 }
  1066.                 else {
  1067.                     attributePSVI = null;
  1068.                 }
  1069.                 validationState = ValidatingReaderState.OnAttribute;
  1070.                 goto Found;
  1071.             }
  1072.             else if (currentAttrIndex + 1 < attributeCount) {
  1073.                 //default attribute
  1074.                 int defaultIndex = ++currentAttrIndex - coreReaderAttributeCount;
  1075.                 cachedNode = (ValidatingReaderNodeData)defaultAttributes[defaultIndex];
  1076.                 attributePSVI = cachedNode.AttInfo;
  1077.                 validationState = ValidatingReaderState.OnDefaultAttribute;
  1078.                 goto Found;
  1079.             }
  1080.             return false;
  1081.             Found:
  1082.             if (validationState == ValidatingReaderState.OnReadBinaryContent) {
  1083.                 readBinaryHelper.Finish();
  1084.                 validationState = savedState;
  1085.             }
  1086.             return true;
  1087.         }
  1088.        
  1089.         // Moves to the element that contains the current attribute node.
  1090.         public override bool MoveToElement()
  1091.         {
  1092.             if (coreReader.MoveToElement() || (int)validationState < 0) {
  1093.                 //states OnDefaultAttribute or OnReadAttributeValue
  1094.                 currentAttrIndex = -1;
  1095.                 validationState = ValidatingReaderState.ClearAttributes;
  1096.                 return true;
  1097.             }
  1098.             return false;
  1099.         }
  1100.        
  1101.         // Reads the next node from the stream/TextReader.
  1102.         public override bool Read()
  1103.         {
  1104.             switch (validationState) {
  1105.                 case ValidatingReaderState.Read:
  1106.                     if (coreReader.Read()) {
  1107.                         ProcessReaderEvent();
  1108.                         return true;
  1109.                     }
  1110.                     else {
  1111.                         validator.EndValidation();
  1112.                         if (coreReader.EOF) {
  1113.                             validationState = ValidatingReaderState.EOF;
  1114.                         }
  1115.                         return false;
  1116.                     }
  1117.                     break;
  1118.                 case ValidatingReaderState.ParseInlineSchema:
  1119.                    
  1120.                     ProcessInlineSchema();
  1121.                     return true;
  1122.                 case ValidatingReaderState.OnAttribute:
  1123.                 case ValidatingReaderState.OnDefaultAttribute:
  1124.                 case ValidatingReaderState.ClearAttributes:
  1125.                 case ValidatingReaderState.OnReadAttributeValue:
  1126.                    
  1127.                     ClearAttributesInfo();
  1128.                     if (inlineSchemaParser != null) {
  1129.                         validationState = ValidatingReaderState.ParseInlineSchema;
  1130.                         goto case ValidatingReaderState.ParseInlineSchema;
  1131.                     }
  1132.                     else {
  1133.                         validationState = ValidatingReaderState.Read;
  1134.                         goto case ValidatingReaderState.Read;
  1135.                     }
  1136.                     break;
  1137.                 case ValidatingReaderState.ReadAhead:
  1138.                    
  1139.                     //Will enter here on calling Skip()
  1140.                     ClearAttributesInfo();
  1141.                     ProcessReaderEvent();
  1142.                     validationState = ValidatingReaderState.Read;
  1143.                     return true;
  1144.                 case ValidatingReaderState.OnReadBinaryContent:
  1145.                    
  1146.                     validationState = savedState;
  1147.                     readBinaryHelper.Finish();
  1148.                     return Read();
  1149.                 case ValidatingReaderState.Init:
  1150.                    
  1151.                     validationState = ValidatingReaderState.Read;
  1152.                     if (coreReader.ReadState == ReadState.Interactive) {
  1153.                         //If the underlying reader is already positioned on a ndoe, process it
  1154.                         ProcessReaderEvent();
  1155.                         return true;
  1156.                     }
  1157.                     else {
  1158.                         goto case ValidatingReaderState.Read;
  1159.                     }
  1160.                     break;
  1161.                 case ValidatingReaderState.ReaderClosed:
  1162.                 case ValidatingReaderState.EOF:
  1163.                    
  1164.                     return false;
  1165.                 default:
  1166.                    
  1167.                     return false;
  1168.             }
  1169.         }
  1170.        
  1171.         // Gets a value indicating whether XmlReader is positioned at the end of the stream/TextReader.
  1172.         public override bool EOF {
  1173.             get { return coreReader.EOF; }
  1174.         }
  1175.        
  1176.        
  1177.         // Closes the stream, changes the ReadState to Closed, and sets all the properties back to zero.
  1178.         public override void Close()
  1179.         {
  1180.             coreReader.Close();
  1181.             validationState = ValidatingReaderState.ReaderClosed;
  1182.         }
  1183.        
  1184.         // Returns the read state of the XmlReader.
  1185.         public override ReadState ReadState {
  1186.             get { return (validationState == ValidatingReaderState.Init) ? ReadState.Initial : coreReader.ReadState; }
  1187.         }
  1188.        
  1189.         // Skips to the end tag of the current element.
  1190.         public override void Skip()
  1191.         {
  1192.            
  1193.             int startDepth = Depth;
  1194.             switch (NodeType) {
  1195.                 case XmlNodeType.Element:
  1196.                     if (coreReader.IsEmptyElement) {
  1197.                         break;
  1198.                     }
  1199.                     bool callSkipToEndElem = true;
  1200.                     //If union and unionValue has been parsed till EndElement, then validator.ValidateEndElement has been called
  1201.                     //Hence should not call SkipToEndElement as the current context has already been popped in the validator
  1202.                     if ((xmlSchemaInfo.IsUnionType || xmlSchemaInfo.IsDefault) && coreReader is XsdCachingReader) {
  1203.                         callSkipToEndElem = false;
  1204.                     }
  1205.                     coreReader.Skip();
  1206.                     validationState = ValidatingReaderState.ReadAhead;
  1207.                     if (callSkipToEndElem) {
  1208.                         validator.SkipToEndElement(xmlSchemaInfo);
  1209.                     }
  1210.                     break;
  1211.                 case XmlNodeType.Attribute:
  1212.                    
  1213.                     MoveToElement();
  1214.                     goto case XmlNodeType.Element;
  1215.                     break;
  1216.             }
  1217.             //For all other NodeTypes Skip() same as Read()
  1218.             Read();
  1219.             return;
  1220.         }
  1221.        
  1222.         // Gets the XmlNameTable associated with this implementation.
  1223.         public override XmlNameTable NameTable {
  1224.             get { return coreReaderNameTable; }
  1225.         }
  1226.        
  1227.         // Resolves a namespace prefix in the current element's scope.
  1228.         public override string LookupNamespace(string prefix)
  1229.         {
  1230.             return thisNSResolver.LookupNamespace(prefix);
  1231.         }
  1232.        
  1233.         // Resolves the entity reference for nodes of NodeType EntityReference.
  1234.         public override void ResolveEntity()
  1235.         {
  1236.             throw new InvalidOperationException();
  1237.         }
  1238.        
  1239.         // Parses the attribute value into one or more Text and/or EntityReference node types.
  1240.         public override bool ReadAttributeValue()
  1241.         {
  1242.             if (validationState == ValidatingReaderState.OnReadBinaryContent) {
  1243.                 readBinaryHelper.Finish();
  1244.                 validationState = savedState;
  1245.             }
  1246.             if (NodeType == XmlNodeType.Attribute) {
  1247.                 if (validationState == ValidatingReaderState.OnDefaultAttribute) {
  1248.                     cachedNode = CreateDummyTextNode(cachedNode.RawValue, cachedNode.Depth + 1);
  1249.                     validationState = ValidatingReaderState.OnReadAttributeValue;
  1250.                     return true;
  1251.                 }
  1252.                 return coreReader.ReadAttributeValue();
  1253.             }
  1254.             return false;
  1255.         }
  1256.        
  1257.         public override bool CanReadBinaryContent {
  1258.             get { return true; }
  1259.         }
  1260.        
  1261.         public override int ReadContentAsBase64(byte[] buffer, int index, int count)
  1262.         {
  1263.             if (ReadState != ReadState.Interactive) {
  1264.                 return 0;
  1265.             }
  1266.            
  1267.             // init ReadContentAsBinaryHelper when called first time
  1268.             if (validationState != ValidatingReaderState.OnReadBinaryContent) {
  1269.                 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset(readBinaryHelper, this);
  1270.                 savedState = validationState;
  1271.             }
  1272.            
  1273.             // restore original state in order to have a normal Read() behavior when called from readBinaryHelper
  1274.             validationState = savedState;
  1275.            
  1276.             // call to the helper
  1277.             int readCount = readBinaryHelper.ReadContentAsBase64(buffer, index, count);
  1278.            
  1279.             // set OnReadBinaryContent state again and return
  1280.             savedState = validationState;
  1281.             validationState = ValidatingReaderState.OnReadBinaryContent;
  1282.             return readCount;
  1283.         }
  1284.        
  1285.         public override int ReadContentAsBinHex(byte[] buffer, int index, int count)
  1286.         {
  1287.             if (ReadState != ReadState.Interactive) {
  1288.                 return 0;
  1289.             }
  1290.            
  1291.             // init ReadContentAsBinaryHelper when called first time
  1292.             if (validationState != ValidatingReaderState.OnReadBinaryContent) {
  1293.                 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset(readBinaryHelper, this);
  1294.                 savedState = validationState;
  1295.             }
  1296.            
  1297.             // restore original state in order to have a normal Read() behavior when called from readBinaryHelper
  1298.             validationState = savedState;
  1299.            
  1300.             // call to the helper
  1301.             int readCount = readBinaryHelper.ReadContentAsBinHex(buffer, index, count);
  1302.            
  1303.             // set OnReadBinaryContent state again and return
  1304.             savedState = validationState;
  1305.             validationState = ValidatingReaderState.OnReadBinaryContent;
  1306.             return readCount;
  1307.         }
  1308.        
  1309.         public override int ReadElementContentAsBase64(byte[] buffer, int index, int count)
  1310.         {
  1311.             if (ReadState != ReadState.Interactive) {
  1312.                 return 0;
  1313.             }
  1314.            
  1315.             // init ReadContentAsBinaryHelper when called first time
  1316.             if (validationState != ValidatingReaderState.OnReadBinaryContent) {
  1317.                 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset(readBinaryHelper, this);
  1318.                 savedState = validationState;
  1319.             }
  1320.            
  1321.             // restore original state in order to have a normal Read() behavior when called from readBinaryHelper
  1322.             validationState = savedState;
  1323.            
  1324.             // call to the helper
  1325.             int readCount = readBinaryHelper.ReadElementContentAsBase64(buffer, index, count);
  1326.            
  1327.             // set OnReadBinaryContent state again and return
  1328.             savedState = validationState;
  1329.             validationState = ValidatingReaderState.OnReadBinaryContent;
  1330.             return readCount;
  1331.         }
  1332.        
  1333.         public override int ReadElementContentAsBinHex(byte[] buffer, int index, int count)
  1334.         {
  1335.             if (ReadState != ReadState.Interactive) {
  1336.                 return 0;
  1337.             }
  1338.            
  1339.             // init ReadContentAsBinaryHelper when called first time
  1340.             if (validationState != ValidatingReaderState.OnReadBinaryContent) {
  1341.                 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset(readBinaryHelper, this);
  1342.                 savedState = validationState;
  1343.             }
  1344.            
  1345.             // restore original state in order to have a normal Read() behavior when called from readBinaryHelper
  1346.             validationState = savedState;
  1347.            
  1348.             // call to the helper
  1349.             int readCount = readBinaryHelper.ReadElementContentAsBinHex(buffer, index, count);
  1350.            
  1351.             // set OnReadBinaryContent state again and return
  1352.             savedState = validationState;
  1353.             validationState = ValidatingReaderState.OnReadBinaryContent;
  1354.             return readCount;
  1355.         }
  1356.        
  1357.         //
  1358.         // IXmlSchemaInfo interface
  1359.         //
  1360.         bool IXmlSchemaInfo.IsDefault {
  1361.             get {
  1362.                 switch (NodeType) {
  1363.                     case XmlNodeType.Element:
  1364.                         if (!coreReader.IsEmptyElement) {
  1365.                             GetIsDefault();
  1366.                         }
  1367.                         return xmlSchemaInfo.IsDefault;
  1368.                     case XmlNodeType.EndElement:
  1369.                        
  1370.                         return xmlSchemaInfo.IsDefault;
  1371.                     case XmlNodeType.Attribute:
  1372.                        
  1373.                         if (attributePSVI != null) {
  1374.                             return AttributeSchemaInfo.IsDefault;
  1375.                         }
  1376.                         break;
  1377.                     default:
  1378.                        
  1379.                         break;
  1380.                 }
  1381.                 return false;
  1382.             }
  1383.         }
  1384.        
  1385.         bool IXmlSchemaInfo.IsNil {
  1386.             get {
  1387.                 switch (NodeType) {
  1388.                     case XmlNodeType.Element:
  1389.                     case XmlNodeType.EndElement:
  1390.                         return xmlSchemaInfo.IsNil;
  1391.                     default:
  1392.                        
  1393.                         break;
  1394.                 }
  1395.                 return false;
  1396.             }
  1397.         }
  1398.        
  1399.         XmlSchemaValidity IXmlSchemaInfo.Validity {
  1400.             get {
  1401.                 switch (NodeType) {
  1402.                     case XmlNodeType.Element:
  1403.                         if (coreReader.IsEmptyElement) {
  1404.                             return xmlSchemaInfo.Validity;
  1405.                         }
  1406.                         if (xmlSchemaInfo.Validity == XmlSchemaValidity.Valid) {
  1407.                             //It might be valid for unions since we read ahead, but report notknown for consistency
  1408.                             return XmlSchemaValidity.NotKnown;
  1409.                         }
  1410.                         return xmlSchemaInfo.Validity;
  1411.                     case XmlNodeType.EndElement:
  1412.                        
  1413.                         return xmlSchemaInfo.Validity;
  1414.                     case XmlNodeType.Attribute:
  1415.                        
  1416.                         if (attributePSVI != null) {
  1417.                             return AttributeSchemaInfo.Validity;
  1418.                         }
  1419.                         break;
  1420.                 }
  1421.                 return XmlSchemaValidity.NotKnown;
  1422.             }
  1423.         }
  1424.        
  1425.         XmlSchemaSimpleType IXmlSchemaInfo.MemberType {
  1426.             get {
  1427.                 switch (NodeType) {
  1428.                     case XmlNodeType.Element:
  1429.                         if (!coreReader.IsEmptyElement) {
  1430.                             GetMemberType();
  1431.                         }
  1432.                         return xmlSchemaInfo.MemberType;
  1433.                     case XmlNodeType.EndElement:
  1434.                        
  1435.                         return xmlSchemaInfo.MemberType;
  1436.                     case XmlNodeType.Attribute:
  1437.                        
  1438.                         if (attributePSVI != null) {
  1439.                             return AttributeSchemaInfo.MemberType;
  1440.                         }
  1441.                         return null;
  1442.                     default:
  1443.                        
  1444.                         return null;
  1445.                     //Text, PI, Comment etc
  1446.                 }
  1447.             }
  1448.         }
  1449.        
  1450.         XmlSchemaType IXmlSchemaInfo.SchemaType {
  1451.             get {
  1452.                 switch (NodeType) {
  1453.                     case XmlNodeType.Element:
  1454.                     case XmlNodeType.EndElement:
  1455.                         return xmlSchemaInfo.SchemaType;
  1456.                     case XmlNodeType.Attribute:
  1457.                        
  1458.                         if (attributePSVI != null) {
  1459.                             return AttributeSchemaInfo.SchemaType;
  1460.                         }
  1461.                         return null;
  1462.                     default:
  1463.                        
  1464.                         return null;
  1465.                     //Text, PI, Comment etc
  1466.                 }
  1467.             }
  1468.         }
  1469.         XmlSchemaElement IXmlSchemaInfo.SchemaElement {
  1470.             get {
  1471.                 if (NodeType == XmlNodeType.Element || NodeType == XmlNodeType.EndElement) {
  1472.                     return xmlSchemaInfo.SchemaElement;
  1473.                 }
  1474.                 return null;
  1475.             }
  1476.         }
  1477.        
  1478.         XmlSchemaAttribute IXmlSchemaInfo.SchemaAttribute {
  1479.             get {
  1480.                 if (NodeType == XmlNodeType.Attribute) {
  1481.                     if (attributePSVI != null) {
  1482.                         return AttributeSchemaInfo.SchemaAttribute;
  1483.                     }
  1484.                 }
  1485.                 return null;
  1486.             }
  1487.         }
  1488.        
  1489.         //
  1490.         // IXmlLineInfo members
  1491.         //
  1492.        
  1493.         public bool HasLineInfo()
  1494.         {
  1495.             return true;
  1496.         }
  1497.        
  1498.         public int LineNumber {
  1499.             get {
  1500.                 if (lineInfo != null) {
  1501.                     return lineInfo.LineNumber;
  1502.                 }
  1503.                 return 0;
  1504.             }
  1505.         }
  1506.        
  1507.         public int LinePosition {
  1508.             get {
  1509.                 if (lineInfo != null) {
  1510.                     return lineInfo.LinePosition;
  1511.                 }
  1512.                 return 0;
  1513.             }
  1514.         }
  1515.        
  1516.         //
  1517.         // IXmlNamespaceResolver members
  1518.         //
  1519.         IDictionary<string, string> IXmlNamespaceResolver.GetNamespacesInScope(XmlNamespaceScope scope)
  1520.         {
  1521.             if (coreReaderNSResolver != null) {
  1522.                 return coreReaderNSResolver.GetNamespacesInScope(scope);
  1523.             }
  1524.             else {
  1525.                 return nsManager.GetNamespacesInScope(scope);
  1526.             }
  1527.         }
  1528.        
  1529.         string IXmlNamespaceResolver.LookupNamespace(string prefix)
  1530.         {
  1531.             if (coreReaderNSResolver != null) {
  1532.                 return coreReaderNSResolver.LookupNamespace(prefix);
  1533.             }
  1534.             else {
  1535.                 return nsManager.LookupNamespace(prefix);
  1536.             }
  1537.         }
  1538.        
  1539.         string IXmlNamespaceResolver.LookupPrefix(string namespaceName)
  1540.         {
  1541.             if (coreReaderNSResolver != null) {
  1542.                 return coreReaderNSResolver.LookupPrefix(namespaceName);
  1543.             }
  1544.             else {
  1545.                 return nsManager.LookupPrefix(namespaceName);
  1546.             }
  1547.         }
  1548.        
  1549.         //Internal / Private methods
  1550.        
  1551.         private object GetStringValue()
  1552.         {
  1553.             return coreReader.Value;
  1554.         }
  1555.        
  1556.         private XmlSchemaType ElementXmlType {
  1557.             get { return xmlSchemaInfo.XmlType; }
  1558.         }
  1559.        
  1560.         private XmlSchemaType AttributeXmlType {
  1561.             get {
  1562.                 if (attributePSVI != null) {
  1563.                     return AttributeSchemaInfo.XmlType;
  1564.                 }
  1565.                 return null;
  1566.             }
  1567.         }
  1568.        
  1569.         private XmlSchemaInfo AttributeSchemaInfo {
  1570.             get {
  1571.                 Debug.Assert(attributePSVI != null);
  1572.                 return attributePSVI.attributeSchemaInfo;
  1573.             }
  1574.         }
  1575.        
  1576.         private void ProcessReaderEvent()
  1577.         {
  1578.             if (replayCache) {
  1579.                 //if in replay mode, do nothing since nodes have been validated already
  1580.                 //If NodeType == XmlNodeType.EndElement && if manageNamespaces, may need to pop namespace scope, since scope is not popped in ReadAheadForMemberType
  1581.                 return;
  1582.             }
  1583.             switch (coreReader.NodeType) {
  1584.                 case XmlNodeType.Element:
  1585.                     ProcessElementEvent();
  1586.                     break;
  1587.                 case XmlNodeType.Whitespace:
  1588.                 case XmlNodeType.SignificantWhitespace:
  1589.                    
  1590.                     validator.ValidateWhitespace(GetStringValue);
  1591.                     break;
  1592.                 case XmlNodeType.Text:
  1593.                 case XmlNodeType.CDATA:
  1594.                    
  1595.                     // text inside a node
  1596.                     // <![CDATA[...]]>
  1597.                     validator.ValidateText(GetStringValue);
  1598.                     break;
  1599.                 case XmlNodeType.EndElement:
  1600.                    
  1601.                     ProcessEndElementEvent();
  1602.                     break;
  1603.                 case XmlNodeType.EntityReference:
  1604.                    
  1605.                     throw new InvalidOperationException();
  1606.                     break;
  1607.                 case XmlNodeType.DocumentType:
  1608.                    
  1609.                     validator.SetDtdSchemaInfo(XmlReader.GetDtdSchemaInfo(coreReader));
  1610.                     break;
  1611.                 default:
  1612.                    
  1613.                     break;
  1614.             }
  1615.         }
  1616.        
  1617.         private void ProcessElementEvent()
  1618.         {
  1619.             if (this.processInlineSchema && IsXSDRoot(coreReader.LocalName, coreReader.NamespaceURI) && coreReader.Depth > 0) {
  1620.                 xmlSchemaInfo.Clear();
  1621.                 attributeCount = coreReaderAttributeCount = coreReader.AttributeCount;
  1622.                 if (!coreReader.IsEmptyElement) {
  1623.                     //If its not empty schema, then parse else ignore
  1624.                     inlineSchemaParser = new Parser(SchemaType.XSD, coreReaderNameTable, validator.SchemaSet.GetSchemaNames(coreReaderNameTable), validationEvent);
  1625.                     inlineSchemaParser.StartParsing(coreReader, null);
  1626.                     inlineSchemaParser.ParseReaderNode();
  1627.                     validationState = ValidatingReaderState.ParseInlineSchema;
  1628.                 }
  1629.                 else {
  1630.                     validationState = ValidatingReaderState.ClearAttributes;
  1631.                 }
  1632.             }
  1633.             else {
  1634.                 //Validate element
  1635.                 //Clear previous data
  1636.                 atomicValue = null;
  1637.                 xmlSchemaInfo.Clear();
  1638.                
  1639.                 if (manageNamespaces) {
  1640.                     nsManager.PushScope();
  1641.                 }
  1642.                 //Find Xsi attributes that need to be processed before validating the element
  1643.                 string xsiSchemaLocation = null;
  1644.                 string xsiNoNamespaceSL = null;
  1645.                 string xsiNil = null;
  1646.                 string xsiType = null;
  1647.                 if (coreReader.MoveToFirstAttribute()) {
  1648.                     do {
  1649.                         string objectNs = coreReader.NamespaceURI;
  1650.                         string objectName = coreReader.LocalName;
  1651.                         if (Ref.Equal(objectNs, NsXsi)) {
  1652.                             if (Ref.Equal(objectName, XsiSchemaLocation)) {
  1653.                                 xsiSchemaLocation = coreReader.Value;
  1654.                             }
  1655.                             else if (Ref.Equal(objectName, XsiNoNamespaceSchemaLocation)) {
  1656.                                 xsiNoNamespaceSL = coreReader.Value;
  1657.                             }
  1658.                             else if (Ref.Equal(objectName, XsiType)) {
  1659.                                 xsiType = coreReader.Value;
  1660.                             }
  1661.                             else if (Ref.Equal(objectName, XsiNil)) {
  1662.                                 xsiNil = coreReader.Value;
  1663.                             }
  1664.                         }
  1665.                         if (manageNamespaces && Ref.Equal(coreReader.NamespaceURI, NsXmlNs)) {
  1666.                             nsManager.AddNamespace(coreReader.Prefix.Length == 0 ? string.Empty : coreReader.LocalName, coreReader.Value);
  1667.                         }
  1668.                        
  1669.                     }
  1670.                     while (coreReader.MoveToNextAttribute());
  1671.                     coreReader.MoveToElement();
  1672.                 }
  1673.                 validator.ValidateElement(coreReader.LocalName, coreReader.NamespaceURI, xmlSchemaInfo, xsiType, xsiNil, xsiSchemaLocation, xsiNoNamespaceSL);
  1674.                 ValidateAttributes();
  1675.                 validator.ValidateEndOfAttributes(xmlSchemaInfo);
  1676.                 if (coreReader.IsEmptyElement) {
  1677.                     ProcessEndElementEvent();
  1678.                 }
  1679.                 validationState = ValidatingReaderState.ClearAttributes;
  1680.             }
  1681.         }
  1682.        
  1683.         private void ProcessEndElementEvent()
  1684.         {
  1685.             atomicValue = validator.ValidateEndElement(xmlSchemaInfo);
  1686.             if (xmlSchemaInfo.IsDefault) {
  1687.                 //The atomicValue returned is a default value
  1688.                 Debug.Assert(atomicValue != null);
  1689.                 int depth = coreReader.Depth;
  1690.                 coreReader = GetCachingReader();
  1691.                 cachingReader.RecordTextNode(xmlSchemaInfo.XmlType.ValueConverter.ToString(atomicValue), depth + 1, 0, 0);
  1692.                 cachingReader.RecordEndElementNode();
  1693.                 cachingReader.SetToReplayMode();
  1694.                 replayCache = true;
  1695.             }
  1696.             else if (manageNamespaces) {
  1697.                 nsManager.PopScope();
  1698.             }
  1699.         }
  1700.        
  1701.         private void ValidateAttributes()
  1702.         {
  1703.             attributeCount = coreReaderAttributeCount = coreReader.AttributeCount;
  1704.             AttributePSVIInfo attributePSVI;
  1705.             int attIndex = 0;
  1706.             bool attributeInvalid = false;
  1707.             if (coreReader.MoveToFirstAttribute()) {
  1708.                 do {
  1709.                     string localName = coreReader.LocalName;
  1710.                     string ns = coreReader.NamespaceURI;
  1711.                    
  1712.                     attributePSVI = AddAttributePSVI(attIndex);
  1713.                     attributePSVI.localName = localName;
  1714.                     attributePSVI.namespaceUri = ns;
  1715.                    
  1716.                     if ((object)ns == (object)NsXmlNs) {
  1717.                         attIndex++;
  1718.                         continue;
  1719.                     }
  1720.                     attributePSVI.typedAttributeValue = validator.ValidateAttribute(localName, ns, valueGetter, attributePSVI.attributeSchemaInfo);
  1721.                     if (!attributeInvalid) {
  1722.                         attributeInvalid = attributePSVI.attributeSchemaInfo.Validity == XmlSchemaValidity.Invalid;
  1723.                     }
  1724.                     attIndex++;
  1725.                    
  1726.                 }
  1727.                 while (coreReader.MoveToNextAttribute());
  1728.             }
  1729.             coreReader.MoveToElement();
  1730.             if (attributeInvalid) {
  1731.                 //If any of the attributes are invalid, Need to report element's validity as invalid
  1732.                 xmlSchemaInfo.Validity = XmlSchemaValidity.Invalid;
  1733.             }
  1734.             validator.GetUnspecifiedDefaultAttributes(defaultAttributes, true);
  1735.             attributeCount += defaultAttributes.Count;
  1736.         }
  1737.        
  1738.         private void ClearAttributesInfo()
  1739.         {
  1740.             attributeCount = 0;
  1741.             coreReaderAttributeCount = 0;
  1742.             currentAttrIndex = -1;
  1743.             defaultAttributes.Clear();
  1744.             attributePSVI = null;
  1745.         }
  1746.        
  1747.        
  1748.         private AttributePSVIInfo GetAttributePSVI(string name)
  1749.         {
  1750.             if (inlineSchemaParser != null) {
  1751.                 //Parsing inline schema, no PSVI for schema attributes
  1752.                 return null;
  1753.             }
  1754.             string attrLocalName;
  1755.             string attrPrefix;
  1756.             string ns;
  1757.             ValidateNames.SplitQName(name, out attrPrefix, out attrLocalName);
  1758.             attrPrefix = coreReaderNameTable.Add(attrPrefix);
  1759.             attrLocalName = coreReaderNameTable.Add(attrLocalName);
  1760.            
  1761.             if (attrPrefix.Length == 0) {
  1762.                 //empty prefix, not qualified
  1763.                 ns = string.Empty;
  1764.             }
  1765.             else {
  1766.                 ns = thisNSResolver.LookupNamespace(attrPrefix);
  1767.             }
  1768.             return GetAttributePSVI(attrLocalName, ns);
  1769.         }
  1770.        
  1771.         private AttributePSVIInfo GetAttributePSVI(string localName, string ns)
  1772.         {
  1773.             Debug.Assert(coreReaderNameTable.Get(localName) != null);
  1774.             Debug.Assert(coreReaderNameTable.Get(ns) != null);
  1775.             AttributePSVIInfo attInfo = null;
  1776.            
  1777.             for (int i = 0; i < coreReaderAttributeCount; i++) {
  1778.                 attInfo = attributePSVINodes[i];
  1779.                 if (attInfo != null) {
  1780.                     //Will be null for invalid attributes
  1781.                     if (Ref.Equal(localName, attInfo.localName) && Ref.Equal(ns, attInfo.namespaceUri)) {
  1782.                         currentAttrIndex = i;
  1783.                         return attInfo;
  1784.                     }
  1785.                 }
  1786.             }
  1787.             return null;
  1788.         }
  1789.        
  1790.         private ValidatingReaderNodeData GetDefaultAttribute(string name, bool updatePosition)
  1791.         {
  1792.             string attrLocalName;
  1793.             string attrPrefix;
  1794.             ValidateNames.SplitQName(name, out attrPrefix, out attrLocalName);
  1795.            
  1796.             //Atomize
  1797.             attrPrefix = coreReaderNameTable.Add(attrPrefix);
  1798.             attrLocalName = coreReaderNameTable.Add(attrLocalName);
  1799.             string ns;
  1800.             if (attrPrefix.Length == 0) {
  1801.                 ns = string.Empty;
  1802.             }
  1803.             else {
  1804.                 ns = thisNSResolver.LookupNamespace(attrPrefix);
  1805.             }
  1806.             return GetDefaultAttribute(attrLocalName, ns, updatePosition);
  1807.         }
  1808.        
  1809.         private ValidatingReaderNodeData GetDefaultAttribute(string attrLocalName, string ns, bool updatePosition)
  1810.         {
  1811.             Debug.Assert(coreReaderNameTable.Get(attrLocalName) != null);
  1812.             Debug.Assert(coreReaderNameTable.Get(ns) != null);
  1813.             ValidatingReaderNodeData defaultNode = null;
  1814.            
  1815.             for (int i = 0; i < defaultAttributes.Count; i++) {
  1816.                 defaultNode = (ValidatingReaderNodeData)defaultAttributes[i];
  1817.                 if (Ref.Equal(defaultNode.LocalName, attrLocalName) && Ref.Equal(defaultNode.Namespace, ns)) {
  1818.                     if (updatePosition) {
  1819.                         currentAttrIndex = coreReader.AttributeCount + i;
  1820.                     }
  1821.                     return defaultNode;
  1822.                 }
  1823.             }
  1824.             return null;
  1825.         }
  1826.        
  1827.         private AttributePSVIInfo AddAttributePSVI(int attIndex)
  1828.         {
  1829.             Debug.Assert(attIndex <= attributePSVINodes.Length);
  1830.             AttributePSVIInfo attInfo = attributePSVINodes[attIndex];
  1831.             if (attInfo != null) {
  1832.                 attInfo.Reset();
  1833.                 return attInfo;
  1834.             }
  1835.             if (attIndex >= attributePSVINodes.Length - 1) {
  1836.                 //reached capacity of PSVIInfo array, Need to increase capacity to twice the initial
  1837.                 AttributePSVIInfo[] newPSVINodes = new AttributePSVIInfo[attributePSVINodes.Length * 2];
  1838.                 Array.Copy(attributePSVINodes, 0, newPSVINodes, 0, attributePSVINodes.Length);
  1839.                 attributePSVINodes = newPSVINodes;
  1840.             }
  1841.             attInfo = attributePSVINodes[attIndex];
  1842.             if (attInfo == null) {
  1843.                 attInfo = new AttributePSVIInfo();
  1844.                 attributePSVINodes[attIndex] = attInfo;
  1845.             }
  1846.             return attInfo;
  1847.         }
  1848.        
  1849.         private bool IsXSDRoot(string localName, string ns)
  1850.         {
  1851.             return Ref.Equal(ns, NsXs) && Ref.Equal(localName, XsdSchema);
  1852.         }
  1853.        
  1854.         private void ProcessInlineSchema()
  1855.         {
  1856.             Debug.Assert(inlineSchemaParser != null);
  1857.             if (coreReader.Read()) {
  1858.                 if (coreReader.NodeType == XmlNodeType.Element) {
  1859.                     attributeCount = coreReaderAttributeCount = coreReader.AttributeCount;
  1860.                 }
  1861.                 else {
  1862.                     //Clear attributes info if nodeType is not element
  1863.                     ClearAttributesInfo();
  1864.                 }
  1865.                 if (!inlineSchemaParser.ParseReaderNode()) {
  1866.                     inlineSchemaParser.FinishParsing();
  1867.                     XmlSchema schema = inlineSchemaParser.XmlSchema;
  1868.                     validator.AddSchema(schema);
  1869.                     inlineSchemaParser = null;
  1870.                     validationState = ValidatingReaderState.Read;
  1871.                 }
  1872.             }
  1873.         }
  1874.        
  1875.         private object InternalReadContentAsObject()
  1876.         {
  1877.             return InternalReadContentAsObject(false);
  1878.         }
  1879.        
  1880.         private object InternalReadContentAsObject(bool unwrapTypedValue)
  1881.         {
  1882.             XmlNodeType nodeType = this.NodeType;
  1883.             if (nodeType == XmlNodeType.Attribute) {
  1884.                 if (attributePSVI != null && attributePSVI.typedAttributeValue != null) {
  1885.                     return ReturnBoxedValue(attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType, unwrapTypedValue);
  1886.                 }
  1887.                 else {
  1888.                     //return string value
  1889.                     return this.Value;
  1890.                 }
  1891.             }
  1892.             else if (nodeType == XmlNodeType.EndElement) {
  1893.                 if (atomicValue != null) {
  1894.                     return atomicValue;
  1895.                 }
  1896.                 else {
  1897.                     return string.Empty;
  1898.                 }
  1899.             }
  1900.             else {
  1901.                 //Positioned on text, CDATA, PI, Comment etc
  1902.                 if (validator.CurrentContentType == XmlSchemaContentType.TextOnly) {
  1903.                     //if current element is of simple type
  1904.                     return ReturnBoxedValue(ReadTillEndElement(), xmlSchemaInfo.XmlType, unwrapTypedValue);
  1905.                 }
  1906.                 else {
  1907.                     return InternalReadContentAsString();
  1908.                 }
  1909.             }
  1910.         }
  1911.        
  1912.        
  1913.         private object InternalReadElementContentAsObject(out XmlSchemaType xmlType)
  1914.         {
  1915.             return InternalReadElementContentAsObject(out xmlType, false);
  1916.         }
  1917.        
  1918.         private object InternalReadElementContentAsObject(out XmlSchemaType xmlType, bool unwrapTypedValue)
  1919.         {
  1920.             Debug.Assert(this.NodeType == XmlNodeType.Element);
  1921.             object typedValue = null;
  1922.             xmlType = null;
  1923.             //If its an empty element, can have default/fixed value
  1924.             if (this.IsEmptyElement) {
  1925.                 if (xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) {
  1926.                     typedValue = ReturnBoxedValue(atomicValue, xmlSchemaInfo.XmlType, unwrapTypedValue);
  1927.                 }
  1928.                 else {
  1929.                     typedValue = atomicValue;
  1930.                 }
  1931.                 xmlType = ElementXmlType;
  1932.                 //Set this for default values
  1933.                 this.Read();
  1934.                 return typedValue;
  1935.             }
  1936.             // move to content and read typed value
  1937.             this.Read();
  1938.            
  1939.             if (this.NodeType == XmlNodeType.EndElement) {
  1940.                 //If IsDefault is true, the next node will be EndElement
  1941.                 if (xmlSchemaInfo.IsDefault) {
  1942.                     if (xmlSchemaInfo.ContentType == XmlSchemaContentType.TextOnly) {
  1943.                         typedValue = ReturnBoxedValue(atomicValue, xmlSchemaInfo.XmlType, unwrapTypedValue);
  1944.                     }
  1945.                     else {
  1946.                         //anyType has default value
  1947.                         typedValue = atomicValue;
  1948.                     }
  1949.                 }
  1950.                 else {
  1951.                     //Empty content
  1952.                     typedValue = string.Empty;
  1953.                 }
  1954.             }
  1955.             else if (this.NodeType == XmlNodeType.Element) {
  1956.                 //the first child is again element node
  1957.                 throw new XmlException(Res.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo);
  1958.             }
  1959.             else {
  1960.                 typedValue = InternalReadContentAsObject(unwrapTypedValue);
  1961.                 // ReadElementContentAsXXX cannot be called on mixed content, if positioned on node other than EndElement, Error
  1962.                 if (this.NodeType != XmlNodeType.EndElement) {
  1963.                     throw new XmlException(Res.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo);
  1964.                 }
  1965.             }
  1966.             xmlType = ElementXmlType;
  1967.             //Set this as we are moving ahead to the next node
  1968.             // move to next node
  1969.             this.Read();
  1970.             return typedValue;
  1971.         }
  1972.        
  1973.         private object ReadTillEndElement()
  1974.         {
  1975.             if (atomicValue == null) {
  1976.                 while (coreReader.Read()) {
  1977.                     if (replayCache) {
  1978.                         //If replaying nodes in the cache, they have already been validated
  1979.                         continue;
  1980.                     }
  1981.                     switch (coreReader.NodeType) {
  1982.                         case XmlNodeType.Element:
  1983.                             ProcessReaderEvent();
  1984.                             goto breakWhile;
  1985.                             break;
  1986.                         case XmlNodeType.Text:
  1987.                         case XmlNodeType.CDATA:
  1988.                            
  1989.                             validator.ValidateText(GetStringValue);
  1990.                             break;
  1991.                         case XmlNodeType.Whitespace:
  1992.                         case XmlNodeType.SignificantWhitespace:
  1993.                            
  1994.                             validator.ValidateWhitespace(GetStringValue);
  1995.                             break;
  1996.                         case XmlNodeType.Comment:
  1997.                         case XmlNodeType.ProcessingInstruction:
  1998.                            
  1999.                             break;
  2000.                         case XmlNodeType.EndElement:
  2001.                            
  2002.                             atomicValue = validator.ValidateEndElement(xmlSchemaInfo);
  2003.                             if (manageNamespaces) {
  2004.                                 nsManager.PopScope();
  2005.                             }
  2006.                             goto breakWhile;
  2007.                             break;
  2008.                     }
  2009.                     continue;
  2010.                     breakWhile:
  2011.                     break;
  2012.                 }
  2013.             }
  2014.             else {
  2015.                 //atomicValue != null, meaning already read ahead - Switch reader
  2016.                 if (atomicValue == this) {
  2017.                     //switch back invalid marker; dont need it since coreReader moved to endElement
  2018.                     atomicValue = null;
  2019.                 }
  2020.                 SwitchReader();
  2021.             }
  2022.             return atomicValue;
  2023.         }
  2024.        
  2025.         private void SwitchReader()
  2026.         {
  2027.             XsdCachingReader cachingReader = this.coreReader as XsdCachingReader;
  2028.             if (cachingReader != null) {
  2029.                 //Switch back without going over the cached contents again.
  2030.                 this.coreReader = cachingReader.GetCoreReader();
  2031.             }
  2032.             Debug.Assert(coreReader.NodeType == XmlNodeType.EndElement);
  2033.             replayCache = false;
  2034.         }
  2035.        
  2036.         private void ReadAheadForMemberType()
  2037.         {
  2038.             while (coreReader.Read()) {
  2039.                 switch (coreReader.NodeType) {
  2040.                     case XmlNodeType.Element:
  2041.                         Debug.Assert(false);
  2042.                         //Should not happen as the caching reader does not cache elements in simple content
  2043.                         break;
  2044.                     case XmlNodeType.Text:
  2045.                     case XmlNodeType.CDATA:
  2046.                        
  2047.                         validator.ValidateText(GetStringValue);
  2048.                         break;
  2049.                     case XmlNodeType.Whitespace:
  2050.                     case XmlNodeType.SignificantWhitespace:
  2051.                        
  2052.                         validator.ValidateWhitespace(GetStringValue);
  2053.                         break;
  2054.                     case XmlNodeType.Comment:
  2055.                     case XmlNodeType.ProcessingInstruction:
  2056.                        
  2057.                         break;
  2058.                     case XmlNodeType.EndElement:
  2059.                        
  2060.                         atomicValue = validator.ValidateEndElement(xmlSchemaInfo);
  2061.                         //?? pop namespaceManager scope
  2062.                         if (atomicValue == null) {
  2063.                             //Invalid marker
  2064.                             atomicValue = this;
  2065.                         }
  2066.                         else if (xmlSchemaInfo.IsDefault) {
  2067.                             //The atomicValue returned is a default value
  2068.                             cachingReader.SwitchTextNodeAndEndElement(xmlSchemaInfo.XmlType.ValueConverter.ToString(atomicValue));
  2069.                         }
  2070.                         goto breakWhile;
  2071.                         break;
  2072.                 }
  2073.                 continue;
  2074.                 breakWhile:
  2075.                 break;
  2076.             }
  2077.         }
  2078.        
  2079.         private void GetIsDefault()
  2080.         {
  2081.             XsdCachingReader cachedReader = coreReader as XsdCachingReader;
  2082.             if (cachedReader == null && xmlSchemaInfo.HasDefaultValue) {
  2083.                 //Get Isdefault
  2084.                 coreReader = GetCachingReader();
  2085.                 if (xmlSchemaInfo.IsUnionType && !xmlSchemaInfo.IsNil) {
  2086.                     //If it also union, get the memberType as well
  2087.                     ReadAheadForMemberType();
  2088.                 }
  2089.                 else {
  2090.                     if (coreReader.Read()) {
  2091.                         switch (coreReader.NodeType) {
  2092.                             case XmlNodeType.Element:
  2093.                                 Debug.Assert(false);
  2094.                                 //Should not happen as the caching reader does not cache elements in simple content
  2095.                                 break;
  2096.                             case XmlNodeType.Text:
  2097.                             case XmlNodeType.CDATA:
  2098.                                
  2099.                                 validator.ValidateText(GetStringValue);
  2100.                                 break;
  2101.                             case XmlNodeType.Whitespace:
  2102.                             case XmlNodeType.SignificantWhitespace:
  2103.                                
  2104.                                 validator.ValidateWhitespace(GetStringValue);
  2105.                                 break;
  2106.                             case XmlNodeType.Comment:
  2107.                             case XmlNodeType.ProcessingInstruction:
  2108.                                
  2109.                                 break;
  2110.                             case XmlNodeType.EndElement:
  2111.                                
  2112.                                 atomicValue = validator.ValidateEndElement(xmlSchemaInfo);
  2113.                                 //?? pop namespaceManager scope
  2114.                                 if (xmlSchemaInfo.IsDefault) {
  2115.                                     //The atomicValue returned is a default value
  2116.                                     cachingReader.SwitchTextNodeAndEndElement(xmlSchemaInfo.XmlType.ValueConverter.ToString(atomicValue));
  2117.                                 }
  2118.                                 break;
  2119.                             default:
  2120.                                
  2121.                                 break;
  2122.                         }
  2123.                     }
  2124.                 }
  2125.                 cachingReader.SetToReplayMode();
  2126.                 replayCache = true;
  2127.             }
  2128.         }
  2129.        
  2130.         private void GetMemberType()
  2131.         {
  2132.             if (xmlSchemaInfo.MemberType != null || atomicValue == this) {
  2133.                 return;
  2134.             }
  2135.             XsdCachingReader cachedReader = coreReader as XsdCachingReader;
  2136.             if (cachedReader == null && xmlSchemaInfo.IsUnionType && !xmlSchemaInfo.IsNil) {
  2137.                 coreReader = GetCachingReader();
  2138.                 ReadAheadForMemberType();
  2139.                 cachingReader.SetToReplayMode();
  2140.                 replayCache = true;
  2141.             }
  2142.         }
  2143.        
  2144.         private object ReturnBoxedValue(object typedValue, XmlSchemaType xmlType, bool unWrap)
  2145.         {
  2146.             if (typedValue != null) {
  2147.                 if (unWrap) {
  2148.                     //convert XmlAtomicValue[] to object[] for list of unions; The other cases return typed value of the valueType anyway
  2149.                     Debug.Assert(xmlType != null && xmlType.Datatype != null);
  2150.                     if (xmlType.Datatype.Variety == XmlSchemaDatatypeVariety.List) {
  2151.                         Datatype_List listType = xmlType.Datatype as Datatype_List;
  2152.                         if (listType.ItemType.Variety == XmlSchemaDatatypeVariety.Union) {
  2153.                             typedValue = xmlType.ValueConverter.ChangeType(typedValue, xmlType.Datatype.ValueType, thisNSResolver);
  2154.                         }
  2155.                     }
  2156.                 }
  2157.                 return typedValue;
  2158.             }
  2159.             else {
  2160.                 //return the original string value of the element or attribute
  2161.                 Debug.Assert(NodeType != XmlNodeType.Attribute);
  2162.                 typedValue = validator.GetConcatenatedValue();
  2163.             }
  2164.             return typedValue;
  2165.         }
  2166.        
  2167.         private XsdCachingReader GetCachingReader()
  2168.         {
  2169.             if (cachingReader == null) {
  2170.                 cachingReader = new XsdCachingReader(coreReader, lineInfo, new CachingEventHandler(CachingCallBack));
  2171.             }
  2172.             else {
  2173.                 cachingReader.Reset(coreReader);
  2174.             }
  2175.             this.lineInfo = cachingReader as IXmlLineInfo;
  2176.             return cachingReader;
  2177.         }
  2178.        
  2179.         internal ValidatingReaderNodeData CreateDummyTextNode(string attributeValue, int depth)
  2180.         {
  2181.             if (textNode == null) {
  2182.                 textNode = new ValidatingReaderNodeData(XmlNodeType.Text);
  2183.             }
  2184.             textNode.Depth = depth;
  2185.             textNode.RawValue = attributeValue;
  2186.             return textNode;
  2187.         }
  2188.        
  2189.         internal void CachingCallBack(XsdCachingReader cachingReader)
  2190.         {
  2191.             this.coreReader = cachingReader.GetCoreReader();
  2192.             //re-switch the core-reader after caching reader is done
  2193.             this.lineInfo = cachingReader.GetLineInfo();
  2194.             replayCache = false;
  2195.         }
  2196.     }
  2197. }

Developer Fusion