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