Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Xml / System / Xml / Core / XmlValidatingReaderImpl.cs
blob55d380288025730f00c460fb9209f421c62b358a
2 //------------------------------------------------------------------------------
3 // <copyright file="XmlValidatingReaderImpl.cs" company="Microsoft">
4 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // </copyright>
6 // <owner current="true" primary="true">Microsoft</owner>
7 //------------------------------------------------------------------------------
9 using System;
10 using System.IO;
11 using System.Text;
12 using System.Xml.Schema;
13 using System.Collections;
14 using System.Diagnostics;
15 using System.Globalization;
16 using System.Security.Policy;
17 using System.Collections.Generic;
18 using System.Security.Permissions;
19 using System.Runtime.Versioning;
21 namespace System.Xml
23 internal sealed partial class XmlValidatingReaderImpl : XmlReader, IXmlLineInfo, IXmlNamespaceResolver {
26 // Private helper types
28 // ParsingFunction = what should the reader do when the next Read() is called
29 enum ParsingFunction {
30 Read = 0,
31 Init,
32 ParseDtdFromContext,
33 ResolveEntityInternally,
34 InReadBinaryContent,
35 ReaderClosed,
36 Error,
37 None,
40 internal class ValidationEventHandling : IValidationEventHandling {
41 // Fields
42 XmlValidatingReaderImpl reader;
43 ValidationEventHandler eventHandler;
45 // Constructor
46 internal ValidationEventHandling(XmlValidatingReaderImpl reader) {
47 this.reader = reader;
50 // IValidationEventHandling interface
51 #region IValidationEventHandling interface
52 object IValidationEventHandling.EventHandler {
53 get { return eventHandler; }
56 void IValidationEventHandling.SendEvent(Exception /*XmlSchemaException*/ exception, XmlSeverityType severity) {
57 if (eventHandler != null) {
58 eventHandler(reader, new ValidationEventArgs((XmlSchemaException)exception, severity));
60 else if (reader.ValidationType != ValidationType.None && severity == XmlSeverityType.Error) {
61 throw exception;
64 #endregion
66 // XmlValidatingReaderImpl helper methods
67 internal void AddHandler(ValidationEventHandler handler) {
68 eventHandler += handler;
71 internal void RemoveHandler(ValidationEventHandler handler) {
72 eventHandler -= handler;
77 // Fields
79 // core text reader
80 XmlReader coreReader;
81 XmlTextReaderImpl coreReaderImpl;
82 IXmlNamespaceResolver coreReaderNSResolver;
84 // validation
85 ValidationType validationType;
86 BaseValidator validator;
88 #pragma warning disable 618
89 XmlSchemaCollection schemaCollection;
90 #pragma warning restore 618
91 bool processIdentityConstraints;
93 // parsing function (state)
94 ParsingFunction parsingFunction = ParsingFunction.Init;
96 // event handling
97 ValidationEventHandling eventHandling;
99 // misc
100 XmlParserContext parserContext;
102 // helper for Read[Element]ContentAs{Base64,BinHex} methods
103 ReadContentAsBinaryHelper readBinaryHelper;
105 // Outer XmlReader exposed to the user - either XmlValidatingReader or XmlValidatingReaderImpl (when created via XmlReader.Create).
106 // Virtual methods called from within XmlValidatingReaderImpl must be called on the outer reader so in case the user overrides
107 // some of the XmlValidatingReader methods we will call the overriden version.
108 XmlReader outerReader;
111 // Constructors
113 // Initializes a new instance of XmlValidatingReaderImpl class with the specified XmlReader.
114 // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader
115 internal XmlValidatingReaderImpl( XmlReader reader ) {
116 XmlAsyncCheckReader asyncCheckReader = reader as XmlAsyncCheckReader;
117 if (asyncCheckReader != null) {
118 reader = asyncCheckReader.CoreReader;
120 outerReader = this;
121 coreReader = reader;
122 coreReaderNSResolver = reader as IXmlNamespaceResolver;
123 coreReaderImpl = reader as XmlTextReaderImpl;
124 if ( coreReaderImpl == null ) {
125 XmlTextReader tr = reader as XmlTextReader;
126 if ( tr != null ) {
127 coreReaderImpl = tr.Impl;
130 if ( coreReaderImpl == null ) {
131 throw new ArgumentException( Res.GetString( Res.Arg_ExpectingXmlTextReader ), "reader" );
133 coreReaderImpl.EntityHandling = EntityHandling.ExpandEntities;
134 coreReaderImpl.XmlValidatingReaderCompatibilityMode = true;
135 this.processIdentityConstraints = true;
137 #pragma warning disable 618
138 schemaCollection = new XmlSchemaCollection( coreReader.NameTable );
139 schemaCollection.XmlResolver = GetResolver();
141 eventHandling = new ValidationEventHandling(this);
142 coreReaderImpl.ValidationEventHandling = eventHandling;
143 coreReaderImpl.OnDefaultAttributeUse = new XmlTextReaderImpl.OnDefaultAttributeUseDelegate(ValidateDefaultAttributeOnUse);
145 validationType = ValidationType.Auto;
146 SetupValidation( ValidationType.Auto );
147 #pragma warning restore 618
151 // Initializes a new instance of XmlValidatingReaderImpl class for parsing fragments with the specified string, fragment type and parser context
152 // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader
153 // SxS: This method resolves an Uri but does not expose it to the caller. It's OK to suppress the SxS warning.
154 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
155 [ResourceExposure(ResourceScope.None)]
156 internal XmlValidatingReaderImpl( string xmlFragment, XmlNodeType fragType, XmlParserContext context )
157 : this( new XmlTextReader( xmlFragment, fragType, context ) )
159 if ( coreReader.BaseURI.Length > 0 ) {
160 validator.BaseUri = GetResolver().ResolveUri( null, coreReader.BaseURI );
163 if ( context != null ) {
164 parsingFunction = ParsingFunction.ParseDtdFromContext;
165 parserContext = context;
169 // Initializes a new instance of XmlValidatingReaderImpl class for parsing fragments with the specified stream, fragment type and parser context
170 // This constructor is used when creating XmlValidatingReaderImpl for V1 XmlValidatingReader
171 // SxS: This method resolves an Uri but does not expose it to the caller. It's OK to suppress the SxS warning.
172 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
173 [ResourceExposure(ResourceScope.None)]
174 internal XmlValidatingReaderImpl( Stream xmlFragment, XmlNodeType fragType, XmlParserContext context )
175 : this( new XmlTextReader( xmlFragment, fragType, context ) )
177 if ( coreReader.BaseURI.Length > 0 ) {
178 validator.BaseUri = GetResolver().ResolveUri( null, coreReader.BaseURI );
181 if ( context != null ) {
182 parsingFunction = ParsingFunction.ParseDtdFromContext;
183 parserContext = context;
187 // Initializes a new instance of XmlValidatingReaderImpl class with the specified arguments.
188 // This constructor is used when creating XmlValidatingReaderImpl reader via "XmlReader.Create(..)"
189 internal XmlValidatingReaderImpl( XmlReader reader, ValidationEventHandler settingsEventHandler, bool processIdentityConstraints) {
190 XmlAsyncCheckReader asyncCheckReader = reader as XmlAsyncCheckReader;
191 if (asyncCheckReader != null) {
192 reader = asyncCheckReader.CoreReader;
194 outerReader = this;
195 coreReader = reader;
196 coreReaderImpl = reader as XmlTextReaderImpl;
197 if ( coreReaderImpl == null ) {
198 XmlTextReader tr = reader as XmlTextReader;
199 if ( tr != null ) {
200 coreReaderImpl = tr.Impl;
203 if ( coreReaderImpl == null ) {
204 throw new ArgumentException( Res.GetString( Res.Arg_ExpectingXmlTextReader ), "reader" );
206 coreReaderImpl.XmlValidatingReaderCompatibilityMode = true;
207 coreReaderNSResolver = reader as IXmlNamespaceResolver;
208 this.processIdentityConstraints = processIdentityConstraints;
210 #pragma warning disable 618
212 schemaCollection = new XmlSchemaCollection( coreReader.NameTable );
214 #pragma warning restore 618
216 schemaCollection.XmlResolver = GetResolver();
218 eventHandling = new ValidationEventHandling(this);
219 if (settingsEventHandler != null) {
220 eventHandling.AddHandler(settingsEventHandler);
222 coreReaderImpl.ValidationEventHandling = eventHandling;
223 coreReaderImpl.OnDefaultAttributeUse = new XmlTextReaderImpl.OnDefaultAttributeUseDelegate(ValidateDefaultAttributeOnUse);
225 validationType = ValidationType.DTD;
226 SetupValidation( ValidationType.DTD );
230 // XmlReader members
232 // Returns the current settings of the reader
233 public override XmlReaderSettings Settings {
234 get {
235 XmlReaderSettings settings;
236 if (coreReaderImpl.V1Compat) {
237 settings = null;
239 else {
240 settings = coreReader.Settings;
242 if (settings != null) {
243 settings = settings.Clone();
245 else {
246 settings = new XmlReaderSettings();
248 settings.ValidationType = ValidationType.DTD;
249 if (!processIdentityConstraints) {
250 settings.ValidationFlags &= ~XmlSchemaValidationFlags.ProcessIdentityConstraints;
252 settings.ReadOnly = true;
253 return settings;
257 // Returns the type of the current node.
258 public override XmlNodeType NodeType {
259 get {
260 return coreReader.NodeType;
264 // Returns the name of the current node, including prefix.
265 public override string Name {
266 get {
267 return coreReader.Name;
271 // Returns local name of the current node (without prefix)
272 public override string LocalName {
273 get {
274 return coreReader.LocalName;
278 // Returns namespace name of the current node.
279 public override string NamespaceURI {
280 get {
281 return coreReader.NamespaceURI;
285 // Returns prefix associated with the current node.
286 public override string Prefix {
287 get {
288 return coreReader.Prefix;
292 // Returns true if the current node can have Value property != string.Empty.
293 public override bool HasValue {
294 get {
295 return coreReader.HasValue;
299 // Returns the text value of the current node.
300 public override string Value {
301 get {
302 return coreReader.Value;
306 // Returns the depth of the current node in the XML element stack
307 public override int Depth {
308 get {
309 return coreReader.Depth;
313 // Returns the base URI of the current node.
314 public override string BaseURI {
315 get {
316 return coreReader.BaseURI;
320 // Returns true if the current node is an empty element (for example, <MyElement/>).
321 public override bool IsEmptyElement {
322 get {
323 return coreReader.IsEmptyElement;
327 // Returns true of the current node is a default attribute declared in DTD.
328 public override bool IsDefault {
329 get {
330 return coreReader.IsDefault;
334 // Returns the quote character used in the current attribute declaration
335 public override char QuoteChar {
336 get {
337 return coreReader.QuoteChar;
341 // Returns the current xml:space scope.
342 public override XmlSpace XmlSpace {
343 get {
344 return coreReader.XmlSpace;
348 // Returns the current xml:lang scope.</para>
349 public override string XmlLang {
350 get {
351 return coreReader.XmlLang;
355 // Returns the current read state of the reader
356 public override ReadState ReadState {
357 get {
358 return ( parsingFunction == ParsingFunction.Init ) ? ReadState.Initial : coreReader.ReadState;
362 // Returns true if the reader reached end of the input data
363 public override bool EOF {
364 get {
365 return coreReader.EOF;
369 // Returns the XmlNameTable associated with this XmlReader
370 public override XmlNameTable NameTable {
371 get {
372 return coreReader.NameTable;
376 // Returns encoding of the XML document
377 internal Encoding Encoding {
378 get {
379 return coreReaderImpl.Encoding;
383 // Returns the number of attributes on the current node.
384 public override int AttributeCount {
385 get {
386 return coreReader.AttributeCount;
390 // Returns value of an attribute with the specified Name
391 public override string GetAttribute( string name ) {
392 return coreReader.GetAttribute( name );
395 // Returns value of an attribute with the specified LocalName and NamespaceURI
396 public override string GetAttribute( string localName, string namespaceURI ) {
397 return coreReader.GetAttribute( localName, namespaceURI );
400 // Returns value of an attribute at the specified index (position)
401 public override string GetAttribute( int i ) {
402 return coreReader.GetAttribute( i );
405 // Moves to an attribute with the specified Name
406 public override bool MoveToAttribute( string name ) {
407 if ( !coreReader.MoveToAttribute( name ) ) {
408 return false;
410 parsingFunction = ParsingFunction.Read;
411 return true;
414 // Moves to an attribute with the specified LocalName and NamespceURI
415 public override bool MoveToAttribute( string localName, string namespaceURI ) {
416 if ( !coreReader.MoveToAttribute( localName, namespaceURI ) ) {
417 return false;
419 parsingFunction = ParsingFunction.Read;
420 return true;
423 // Moves to an attribute at the specified index (position)
424 public override void MoveToAttribute( int i ) {
425 coreReader.MoveToAttribute( i );
426 parsingFunction = ParsingFunction.Read;
429 // Moves to the first attribute of the current node
430 public override bool MoveToFirstAttribute() {
431 if ( !coreReader.MoveToFirstAttribute() ) {
432 return false;
434 parsingFunction = ParsingFunction.Read;
435 return true;
438 // Moves to the next attribute of the current node
439 public override bool MoveToNextAttribute() {
440 if ( !coreReader.MoveToNextAttribute() ) {
441 return false;
443 parsingFunction = ParsingFunction.Read;
444 return true;
447 // If on attribute, moves to the element that contains the attribute node
448 public override bool MoveToElement() {
449 if ( !coreReader.MoveToElement() ) {
450 return false;
452 parsingFunction = ParsingFunction.Read;
453 return true;
456 // Reads and validated next node from the input data
457 public override bool Read() {
458 switch ( parsingFunction ) {
459 case ParsingFunction.Read:
460 if ( coreReader.Read() ) {
461 ProcessCoreReaderEvent();
462 return true;
464 else {
465 validator.CompleteValidation();
466 return false;
468 case ParsingFunction.ParseDtdFromContext:
469 parsingFunction = ParsingFunction.Read;
470 ParseDtdFromParserContext();
471 goto case ParsingFunction.Read;
472 case ParsingFunction.Error:
473 case ParsingFunction.ReaderClosed:
474 return false;
475 case ParsingFunction.Init:
476 parsingFunction = ParsingFunction.Read; // this changes the value returned by ReadState
477 if ( coreReader.ReadState == ReadState.Interactive ) {
478 ProcessCoreReaderEvent();
479 return true;
481 else {
482 goto case ParsingFunction.Read;
484 case ParsingFunction.ResolveEntityInternally:
485 parsingFunction = ParsingFunction.Read;
486 ResolveEntityInternally();
487 goto case ParsingFunction.Read;
488 case ParsingFunction.InReadBinaryContent:
489 parsingFunction = ParsingFunction.Read;
490 readBinaryHelper.Finish();
491 goto case ParsingFunction.Read;
492 default:
493 Debug.Assert( false );
494 return false;
498 // Closes the input stream ot TextReader, changes the ReadState to Closed and sets all properties to zero/string.Empty
499 public override void Close() {
500 coreReader.Close();
501 parsingFunction = ParsingFunction.ReaderClosed;
504 // Returns NamespaceURI associated with the specified prefix in the current namespace scope.
505 public override String LookupNamespace( String prefix ) {
506 return coreReaderImpl.LookupNamespace( prefix );
509 // Iterates through the current attribute value's text and entity references chunks.
510 public override bool ReadAttributeValue() {
511 if ( parsingFunction == ParsingFunction.InReadBinaryContent ) {
512 parsingFunction = ParsingFunction.Read;
513 readBinaryHelper.Finish();
515 if (!coreReader.ReadAttributeValue()) {
516 return false;
518 parsingFunction = ParsingFunction.Read;
519 return true;
522 public override bool CanReadBinaryContent {
523 get {
524 return true;
528 public override int ReadContentAsBase64( byte[] buffer, int index, int count ) {
529 if ( ReadState != ReadState.Interactive ) {
530 return 0;
533 // init ReadChunkHelper if called the first time
534 if ( parsingFunction != ParsingFunction.InReadBinaryContent ) {
535 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, outerReader );
538 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
539 parsingFunction = ParsingFunction.Read;
541 // call to the helper
542 int readCount = readBinaryHelper.ReadContentAsBase64( buffer, index, count );
544 // setup parsingFunction
545 parsingFunction = ParsingFunction.InReadBinaryContent;
546 return readCount;
549 public override int ReadContentAsBinHex( byte[] buffer, int index, int count ) {
550 if ( ReadState != ReadState.Interactive ) {
551 return 0;
554 // init ReadChunkHelper when called first time
555 if ( parsingFunction != ParsingFunction.InReadBinaryContent ) {
556 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, outerReader );
559 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
560 parsingFunction = ParsingFunction.Read;
562 // call to the helper
563 int readCount = readBinaryHelper.ReadContentAsBinHex( buffer, index, count );
565 // setup parsingFunction
566 parsingFunction = ParsingFunction.InReadBinaryContent;
567 return readCount;
570 public override int ReadElementContentAsBase64( byte[] buffer, int index, int count ) {
571 if ( ReadState != ReadState.Interactive ) {
572 return 0;
575 // init ReadChunkHelper if called the first time
576 if ( parsingFunction != ParsingFunction.InReadBinaryContent ) {
577 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, outerReader );
580 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
581 parsingFunction = ParsingFunction.Read;
583 // call to the helper
584 int readCount = readBinaryHelper.ReadElementContentAsBase64( buffer, index, count );
586 // setup parsingFunction
587 parsingFunction = ParsingFunction.InReadBinaryContent;
588 return readCount;
591 public override int ReadElementContentAsBinHex( byte[] buffer, int index, int count ) {
592 if ( ReadState != ReadState.Interactive ) {
593 return 0;
596 // init ReadChunkHelper when called first time
597 if ( parsingFunction != ParsingFunction.InReadBinaryContent ) {
598 readBinaryHelper = ReadContentAsBinaryHelper.CreateOrReset( readBinaryHelper, outerReader );
601 // set parsingFunction to Read state in order to have a normal Read() behavior when called from readBinaryHelper
602 parsingFunction = ParsingFunction.Read;
604 // call to the helper
605 int readCount = readBinaryHelper.ReadElementContentAsBinHex( buffer, index, count );
607 // setup parsingFunction
608 parsingFunction = ParsingFunction.InReadBinaryContent;
609 return readCount;
612 // Returns true if the XmlReader knows how to resolve general entities
613 public override bool CanResolveEntity {
614 get {
615 return true;
619 // Resolves the current entity reference node
620 public override void ResolveEntity() {
621 if ( parsingFunction == ParsingFunction.ResolveEntityInternally ) {
622 parsingFunction = ParsingFunction.Read;
624 coreReader.ResolveEntity();
627 internal XmlReader OuterReader {
628 get {
629 return outerReader;
631 set {
632 #pragma warning disable 618
633 Debug.Assert( value is XmlValidatingReader );
634 #pragma warning restore 618
635 outerReader = value;
639 internal void MoveOffEntityReference() {
640 if ( outerReader.NodeType == XmlNodeType.EntityReference && parsingFunction != ParsingFunction.ResolveEntityInternally ) {
641 if ( !outerReader.Read() ) {
642 throw new InvalidOperationException( Res.GetString(Res.Xml_InvalidOperation ) );
647 public override string ReadString() {
648 MoveOffEntityReference();
649 return base.ReadString();
653 // IXmlLineInfo members
655 public bool HasLineInfo() {
656 return true;
659 // Returns the line number of the current node
660 public int LineNumber {
661 get {
662 return ((IXmlLineInfo)coreReader).LineNumber;
666 // Returns the line number of the current node
667 public int LinePosition {
668 get {
669 return ((IXmlLineInfo)coreReader).LinePosition;
674 // IXmlNamespaceResolver members
676 IDictionary<string,string> IXmlNamespaceResolver.GetNamespacesInScope( XmlNamespaceScope scope ) {
677 return this.GetNamespacesInScope( scope );
680 string IXmlNamespaceResolver.LookupNamespace(string prefix) {
681 return this.LookupNamespace( prefix );
684 string IXmlNamespaceResolver.LookupPrefix( string namespaceName ) {
685 return this.LookupPrefix( namespaceName );
688 // Internal IXmlNamespaceResolver methods
689 internal IDictionary<string,string> GetNamespacesInScope( XmlNamespaceScope scope ) {
690 return coreReaderNSResolver.GetNamespacesInScope( scope );
693 internal string LookupPrefix( string namespaceName ) {
694 return coreReaderNSResolver.LookupPrefix( namespaceName );
698 // XmlValidatingReader members
700 // Specufies the validation event handler that wil get warnings and errors related to validation
701 internal event ValidationEventHandler ValidationEventHandler {
702 add {
703 eventHandling.AddHandler(value);
705 remove {
706 eventHandling.RemoveHandler(value); ;
710 // returns the schema type of the current node
711 internal object SchemaType {
712 get {
713 if ( validationType != ValidationType.None ) {
714 XmlSchemaType schemaTypeObj = coreReaderImpl.InternalSchemaType as XmlSchemaType;
715 if ( schemaTypeObj != null && schemaTypeObj.QualifiedName.Namespace == XmlReservedNs.NsXs ) {
716 return schemaTypeObj.Datatype;
718 return coreReaderImpl.InternalSchemaType;
720 else
721 return null;
725 // returns the underlying XmlTextReader or XmlTextReaderImpl
726 internal XmlReader Reader {
727 get {
728 return (XmlReader) coreReader;
732 // returns the underlying XmlTextReaderImpl
733 internal XmlTextReaderImpl ReaderImpl {
734 get {
735 return coreReaderImpl;
739 // specifies the validation type (None, DDT, XSD, XDR, Auto)
740 internal ValidationType ValidationType {
741 get {
742 return validationType;
744 set {
745 if ( ReadState != ReadState.Initial ) {
746 throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
748 validationType = value;
749 SetupValidation( value );
753 // current schema collection used for validationg
754 #pragma warning disable 618
755 internal XmlSchemaCollection Schemas {
756 get {
757 return schemaCollection;
760 #pragma warning restore 618
762 // Spefifies whether general entities should be automatically expanded or not
763 internal EntityHandling EntityHandling {
764 get {
765 return coreReaderImpl.EntityHandling;
767 set {
768 coreReaderImpl.EntityHandling = value;
772 // Specifies XmlResolver used for opening the XML document and other external references
773 internal XmlResolver XmlResolver {
774 set {
775 coreReaderImpl.XmlResolver = value;
776 validator.XmlResolver = value;
777 schemaCollection.XmlResolver = value;
781 // Disables or enables support of W3C XML 1.0 Namespaces
782 internal bool Namespaces {
783 get {
784 return coreReaderImpl.Namespaces;
786 set {
787 coreReaderImpl.Namespaces = value;
791 // Returns typed value of the current node (based on the type specified by schema)
792 public object ReadTypedValue() {
793 if ( validationType == ValidationType.None ) {
794 return null;
797 switch ( outerReader.NodeType ) {
798 case XmlNodeType.Attribute:
799 return coreReaderImpl.InternalTypedValue;
800 case XmlNodeType.Element:
801 if ( SchemaType == null ) {
802 return null;
804 XmlSchemaDatatype dtype = ( SchemaType is XmlSchemaDatatype ) ? (XmlSchemaDatatype)SchemaType : ((XmlSchemaType)SchemaType).Datatype;
805 if ( dtype != null ) {
806 if ( !outerReader.IsEmptyElement ) {
807 for (;;) {
808 if ( !outerReader.Read() ) {
809 throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
811 XmlNodeType type = outerReader.NodeType;
812 if ( type != XmlNodeType.CDATA && type != XmlNodeType.Text &&
813 type != XmlNodeType.Whitespace && type != XmlNodeType.SignificantWhitespace &&
814 type != XmlNodeType.Comment && type != XmlNodeType.ProcessingInstruction ) {
815 break;
818 if ( outerReader.NodeType != XmlNodeType.EndElement ) {
819 throw new XmlException( Res.Xml_InvalidNodeType, outerReader.NodeType.ToString());
822 return coreReaderImpl.InternalTypedValue;
824 return null;
826 case XmlNodeType.EndElement:
827 return null;
829 default:
830 if ( coreReaderImpl.V1Compat ) { //If v1 XmlValidatingReader return null
831 return null;
833 else {
834 return Value;
840 // Private implementation methods
843 private void ParseDtdFromParserContext()
845 Debug.Assert( parserContext != null );
846 Debug.Assert( coreReaderImpl.DtdInfo == null );
848 if ( parserContext.DocTypeName == null || parserContext.DocTypeName.Length == 0 ) {
849 return;
852 IDtdParser dtdParser = DtdParser.Create();
853 XmlTextReaderImpl.DtdParserProxy proxy = new XmlTextReaderImpl.DtdParserProxy(coreReaderImpl);
854 IDtdInfo dtdInfo = dtdParser.ParseFreeFloatingDtd( parserContext.BaseURI, parserContext.DocTypeName, parserContext.PublicId,
855 parserContext.SystemId, parserContext.InternalSubset, proxy );
856 coreReaderImpl.SetDtdInfo( dtdInfo);
858 ValidateDtd();
861 private void ValidateDtd() {
862 IDtdInfo dtdInfo = coreReaderImpl.DtdInfo;
863 if (dtdInfo != null) {
864 switch ( validationType ) {
865 #pragma warning disable 618
866 case ValidationType.Auto:
867 SetupValidation( ValidationType.DTD );
868 goto case ValidationType.DTD;
869 #pragma warning restore 618
870 case ValidationType.DTD:
871 case ValidationType.None:
872 validator.DtdInfo = dtdInfo;
873 break;
878 private void ResolveEntityInternally() {
879 Debug.Assert( coreReader.NodeType == XmlNodeType.EntityReference );
880 int initialDepth = coreReader.Depth;
881 outerReader.ResolveEntity();
882 while ( outerReader.Read() && coreReader.Depth > initialDepth );
885 // SxS: This method resolves an Uri but does not expose it to caller. It's OK to suppress the SxS warning.
886 [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
887 [ResourceExposure(ResourceScope.None)]
888 private void SetupValidation( ValidationType valType ) {
889 validator = BaseValidator.CreateInstance( valType, this, schemaCollection, eventHandling , processIdentityConstraints);
891 XmlResolver resolver = GetResolver();
892 validator.XmlResolver = resolver;
894 if ( outerReader.BaseURI.Length > 0 ) {
895 validator.BaseUri = ( resolver == null ) ? new Uri( outerReader.BaseURI, UriKind.RelativeOrAbsolute ) : resolver.ResolveUri( null, outerReader.BaseURI );
897 coreReaderImpl.ValidationEventHandling = (validationType == ValidationType.None) ? null : eventHandling;
900 static XmlResolver s_tempResolver;
902 // This is needed because we can't have the setter for XmlResolver public and with internal getter.
903 private XmlResolver GetResolver() {
904 XmlResolver tempResolver = coreReaderImpl.GetResolver();
906 if (tempResolver == null && !coreReaderImpl.IsResolverSet &&
907 !System.Xml.XmlReaderSettings.EnableLegacyXmlSettings())
909 // it is safe to return valid resolver as it'll be used in the schema validation
910 if (s_tempResolver == null)
911 s_tempResolver = new XmlUrlResolver();
912 return s_tempResolver;
915 return tempResolver;
919 // Internal methods for validators, DOM, XPathDocument etc.
921 private void ProcessCoreReaderEvent() {
922 switch ( coreReader.NodeType ) {
923 case XmlNodeType.Whitespace:
924 if ( coreReader.Depth > 0 || coreReaderImpl.FragmentType != XmlNodeType.Document ) {
925 if ( validator.PreserveWhitespace ) {
926 coreReaderImpl.ChangeCurrentNodeType( XmlNodeType.SignificantWhitespace );
929 goto default;
930 case XmlNodeType.DocumentType:
931 ValidateDtd();
932 break;
933 case XmlNodeType.EntityReference:
934 parsingFunction = ParsingFunction.ResolveEntityInternally;
935 goto default;
936 default:
937 coreReaderImpl.InternalSchemaType = null;
938 coreReaderImpl.InternalTypedValue = null;
939 validator.Validate();
940 break;
944 internal void Close( bool closeStream ) {
945 coreReaderImpl.Close( closeStream );
946 parsingFunction = ParsingFunction.ReaderClosed;
949 internal BaseValidator Validator {
950 get {
951 return validator;
953 set {
954 validator = value;
958 internal override XmlNamespaceManager NamespaceManager {
959 get {
960 return coreReaderImpl.NamespaceManager;
964 internal bool StandAlone {
965 get {
966 return coreReaderImpl.StandAlone;
970 internal object SchemaTypeObject {
971 set {
972 coreReaderImpl.InternalSchemaType = value;
976 internal object TypedValueObject {
977 get {
978 return coreReaderImpl.InternalTypedValue;
980 set {
981 coreReaderImpl.InternalTypedValue = value;
985 internal bool Normalization {
986 get {
987 return coreReaderImpl.Normalization;
991 internal bool AddDefaultAttribute( SchemaAttDef attdef ) {
992 return coreReaderImpl.AddDefaultAttributeNonDtd( attdef );
995 internal override IDtdInfo DtdInfo {
996 get { return coreReaderImpl.DtdInfo; }
999 internal void ValidateDefaultAttributeOnUse(IDtdDefaultAttributeInfo defaultAttribute, XmlTextReaderImpl coreReader) {
1000 SchemaAttDef attdef = defaultAttribute as SchemaAttDef;
1001 if (attdef == null) {
1002 return;
1005 if (!attdef.DefaultValueChecked) {
1006 SchemaInfo schemaInfo = coreReader.DtdInfo as SchemaInfo;
1007 if (schemaInfo == null) {
1008 return;
1010 DtdValidator.CheckDefaultValue(attdef, schemaInfo, eventHandling, coreReader.BaseURI);