1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.IO;
6 using System.Text;
7 using System.Security;
8 using System.Diagnostics;
9 using System.Collections;
10 using System.Globalization;
11 using System.Xml.Schema;
12 using System.Runtime.Versioning;
13 
14 namespace System.Xml
15 {
16     // Represents a reader that provides fast, non-cached forward only stream access to XML data.
17     [DebuggerDisplay("{debuggerDisplayProxy}")]
18     public abstract partial class XmlReader : IDisposable
19     {
20         private static uint s_isTextualNodeBitmap = 0x6018; // 00 0110 0000 0001 1000
21         // 0 None,
22         // 0 Element,
23         // 0 Attribute,
24         // 1 Text,
25         // 1 CDATA,
26         // 0 EntityReference,
27         // 0 Entity,
28         // 0 ProcessingInstruction,
29         // 0 Comment,
30         // 0 Document,
31         // 0 DocumentType,
32         // 0 DocumentFragment,
33         // 0 Notation,
34         // 1 Whitespace,
35         // 1 SignificantWhitespace,
36         // 0 EndElement,
37         // 0 EndEntity,
38         // 0 XmlDeclaration
39 
40         private static uint s_canReadContentAsBitmap = 0x1E1BC; // 01 1110 0001 1011 1100
41         // 0 None,
42         // 0 Element,
43         // 1 Attribute,
44         // 1 Text,
45         // 1 CDATA,
46         // 1 EntityReference,
47         // 0 Entity,
48         // 1 ProcessingInstruction,
49         // 1 Comment,
50         // 0 Document,
51         // 0 DocumentType,
52         // 0 DocumentFragment,
53         // 0 Notation,
54         // 1 Whitespace,
55         // 1 SignificantWhitespace,
56         // 1 EndElement,
57         // 1 EndEntity,
58         // 0 XmlDeclaration
59 
60         private static uint s_hasValueBitmap = 0x2659C; // 10 0110 0101 1001 1100
61         // 0 None,
62         // 0 Element,
63         // 1 Attribute,
64         // 1 Text,
65         // 1 CDATA,
66         // 0 EntityReference,
67         // 0 Entity,
68         // 1 ProcessingInstruction,
69         // 1 Comment,
70         // 0 Document,
71         // 1 DocumentType,
72         // 0 DocumentFragment,
73         // 0 Notation,
74         // 1 Whitespace,
75         // 1 SignificantWhitespace,
76         // 0 EndElement,
77         // 0 EndEntity,
78         // 1 XmlDeclaration
79 
80         //
81         // Constants
82         //
83         internal const int DefaultBufferSize = 4096;
84         internal const int BiggerBufferSize = 8192;
85         internal const int MaxStreamLengthForDefaultBufferSize = 64 * 1024; // 64kB
86 
87         internal const int AsyncBufferSize = 64 * 1024; //64KB
88 
89         // Settings
90         public virtual XmlReaderSettings Settings
91         {
92             get
93             {
94                 return null;
95             }
96         }
97 
98         // Node Properties
99         // Get the type of the current node.
100         public abstract XmlNodeType NodeType { get; }
101 
102         // Gets the name of the current node, including the namespace prefix.
103         public virtual string Name
104         {
105             get
106             {
107                 if (Prefix.Length == 0)
108                 {
109                     return LocalName;
110                 }
111                 else
112                 {
113                     return NameTable.Add(string.Concat(Prefix, ":", LocalName));
114                 }
115             }
116         }
117 
118         // Gets the name of the current node without the namespace prefix.
119         public abstract string LocalName { get; }
120 
121         // Gets the namespace URN (as defined in the W3C Namespace Specification) of the current namespace scope.
122         public abstract string NamespaceURI { get; }
123 
124         // Gets the namespace prefix associated with the current node.
125         public abstract string Prefix { get; }
126 
127         // Gets a value indicating whether
128         public virtual bool HasValue
129         {
130             get
131             {
132                 return HasValueInternal(this.NodeType);
133             }
134         }
135 
136         // Gets the text value of the current node.
137         public abstract string Value { get; }
138 
139         // Gets the depth of the current node in the XML element stack.
140         public abstract int Depth { get; }
141 
142         // Gets the base URI of the current node.
143         public abstract string BaseURI { get; }
144 
145         // Gets a value indicating whether the current node is an empty element (for example, <MyElement/>).
146         public abstract bool IsEmptyElement { get; }
147 
148         // Gets a value indicating whether the current node is an attribute that was generated from the default value defined
149         // in the DTD or schema.
150         public virtual bool IsDefault
151         {
152             get
153             {
154                 return false;
155             }
156         }
157 
158         // Gets the quotation mark character used to enclose the value of an attribute node.
159         public virtual char QuoteChar
160         {
161             get
162             {
163                 return '"';
164             }
165         }
166 
167         // Gets the current xml:space scope.
168         public virtual XmlSpace XmlSpace
169         {
170             get
171             {
172                 return XmlSpace.None;
173             }
174         }
175 
176         // Gets the current xml:lang scope.
177         public virtual string XmlLang
178         {
179             get
180             {
181                 return string.Empty;
182             }
183         }
184 
185         // returns the schema info interface of the reader
186         public virtual IXmlSchemaInfo SchemaInfo
187         {
188             get
189             {
190                 return this as IXmlSchemaInfo;
191             }
192         }
193 
194         // returns the type of the current node
195         public virtual System.Type ValueType
196         {
197             get
198             {
199                 return typeof(string);
200             }
201         }
202 
203         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
204         // and returns the content as the most appropriate type (by default as string). Stops at start tags and end tags.
ReadContentAsObject()205         public virtual object ReadContentAsObject()
206         {
207             if (!CanReadContentAs())
208             {
209                 throw CreateReadContentAsException(nameof(ReadContentAsObject));
210             }
211             return InternalReadContentAsString();
212         }
213 
214         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
215         // and converts the content to a boolean. Stops at start tags and end tags.
ReadContentAsBoolean()216         public virtual bool ReadContentAsBoolean()
217         {
218             if (!CanReadContentAs())
219             {
220                 throw CreateReadContentAsException(nameof(ReadContentAsBoolean));
221             }
222             try
223             {
224                 return XmlConvert.ToBoolean(InternalReadContentAsString());
225             }
226             catch (FormatException e)
227             {
228                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "Boolean", e, this as IXmlLineInfo);
229             }
230         }
231 
232         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
233         // and converts the content to a DateTime. Stops at start tags and end tags.
ReadContentAsDateTime()234         public virtual DateTime ReadContentAsDateTime()
235         {
236             if (!CanReadContentAs())
237             {
238                 throw CreateReadContentAsException(nameof(ReadContentAsDateTime));
239             }
240             try
241             {
242                 return XmlConvert.ToDateTime(InternalReadContentAsString(), XmlDateTimeSerializationMode.RoundtripKind);
243             }
244             catch (FormatException e)
245             {
246                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "DateTime", e, this as IXmlLineInfo);
247             }
248         }
249 
250         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
251         // and converts the content to a DateTimeOffset. Stops at start tags and end tags.
ReadContentAsDateTimeOffset()252         public virtual DateTimeOffset ReadContentAsDateTimeOffset()
253         {
254             if (!CanReadContentAs())
255             {
256                 throw CreateReadContentAsException(nameof(ReadContentAsDateTimeOffset));
257             }
258             try
259             {
260                 return XmlConvert.ToDateTimeOffset(InternalReadContentAsString());
261             }
262             catch (FormatException e)
263             {
264                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "DateTimeOffset", e, this as IXmlLineInfo);
265             }
266         }
267 
268         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
269         // and converts the content to a double. Stops at start tags and end tags.
ReadContentAsDouble()270         public virtual double ReadContentAsDouble()
271         {
272             if (!CanReadContentAs())
273             {
274                 throw CreateReadContentAsException(nameof(ReadContentAsDouble));
275             }
276             try
277             {
278                 return XmlConvert.ToDouble(InternalReadContentAsString());
279             }
280             catch (FormatException e)
281             {
282                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "Double", e, this as IXmlLineInfo);
283             }
284         }
285 
286         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
287         // and converts the content to a float. Stops at start tags and end tags.
ReadContentAsFloat()288         public virtual float ReadContentAsFloat()
289         {
290             if (!CanReadContentAs())
291             {
292                 throw CreateReadContentAsException(nameof(ReadContentAsFloat));
293             }
294             try
295             {
296                 return XmlConvert.ToSingle(InternalReadContentAsString());
297             }
298             catch (FormatException e)
299             {
300                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "Float", e, this as IXmlLineInfo);
301             }
302         }
303 
304         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
305         // and converts the content to a decimal. Stops at start tags and end tags.
ReadContentAsDecimal()306         public virtual decimal ReadContentAsDecimal()
307         {
308             if (!CanReadContentAs())
309             {
310                 throw CreateReadContentAsException(nameof(ReadContentAsDecimal));
311             }
312             try
313             {
314                 return XmlConvert.ToDecimal(InternalReadContentAsString());
315             }
316             catch (FormatException e)
317             {
318                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "Decimal", e, this as IXmlLineInfo);
319             }
320         }
321 
322         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
323         // and converts the content to an int. Stops at start tags and end tags.
ReadContentAsInt()324         public virtual int ReadContentAsInt()
325         {
326             if (!CanReadContentAs())
327             {
328                 throw CreateReadContentAsException(nameof(ReadContentAsInt));
329             }
330             try
331             {
332                 return XmlConvert.ToInt32(InternalReadContentAsString());
333             }
334             catch (FormatException e)
335             {
336                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "Int", e, this as IXmlLineInfo);
337             }
338         }
339 
340         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
341         // and converts the content to a long. Stops at start tags and end tags.
ReadContentAsLong()342         public virtual long ReadContentAsLong()
343         {
344             if (!CanReadContentAs())
345             {
346                 throw CreateReadContentAsException(nameof(ReadContentAsLong));
347             }
348             try
349             {
350                 return XmlConvert.ToInt64(InternalReadContentAsString());
351             }
352             catch (FormatException e)
353             {
354                 throw new XmlException(SR.Xml_ReadContentAsFormatException, "Long", e, this as IXmlLineInfo);
355             }
356         }
357 
358         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
359         // and returns the content as a string. Stops at start tags and end tags.
ReadContentAsString()360         public virtual string ReadContentAsString()
361         {
362             if (!CanReadContentAs())
363             {
364                 throw CreateReadContentAsException(nameof(ReadContentAsString));
365             }
366             return InternalReadContentAsString();
367         }
368 
369         // Concatenates values of textual nodes of the current content, ignoring comments and PIs, expanding entity references,
370         // and converts the content to the requested type. Stops at start tags and end tags.
ReadContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver)371         public virtual object ReadContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver)
372         {
373             if (!CanReadContentAs())
374             {
375                 throw CreateReadContentAsException(nameof(ReadContentAs));
376             }
377 
378             string strContentValue = InternalReadContentAsString();
379             if (returnType == typeof(string))
380             {
381                 return strContentValue;
382             }
383             else
384             {
385                 try
386                 {
387                     return XmlUntypedStringConverter.Instance.FromString(strContentValue, returnType, (namespaceResolver == null ? this as IXmlNamespaceResolver : namespaceResolver));
388                 }
389                 catch (FormatException e)
390                 {
391                     throw new XmlException(SR.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
392                 }
393                 catch (InvalidCastException e)
394                 {
395                     throw new XmlException(SR.Xml_ReadContentAsFormatException, returnType.ToString(), e, this as IXmlLineInfo);
396                 }
397             }
398         }
399 
400         // Returns the content of the current element as the most appropriate type. Moves to the node following the element's end tag.
ReadElementContentAsObject()401         public virtual object ReadElementContentAsObject()
402         {
403             if (SetupReadElementContentAsXxx("ReadElementContentAsObject"))
404             {
405                 object value = ReadContentAsObject();
406                 FinishReadElementContentAsXxx();
407                 return value;
408             }
409             return string.Empty;
410         }
411 
412         // Checks local name and namespace of the current element and returns its content as the most appropriate type. Moves to the node following the element's end tag.
ReadElementContentAsObject(string localName, string namespaceURI)413         public virtual object ReadElementContentAsObject(string localName, string namespaceURI)
414         {
415             CheckElement(localName, namespaceURI);
416             return ReadElementContentAsObject();
417         }
418 
419         // Returns the content of the current element as a boolean. Moves to the node following the element's end tag.
ReadElementContentAsBoolean()420         public virtual bool ReadElementContentAsBoolean()
421         {
422             if (SetupReadElementContentAsXxx("ReadElementContentAsBoolean"))
423             {
424                 bool value = ReadContentAsBoolean();
425                 FinishReadElementContentAsXxx();
426                 return value;
427             }
428             return XmlConvert.ToBoolean(string.Empty);
429         }
430 
431         // Checks local name and namespace of the current element and returns its content as a boolean. Moves to the node following the element's end tag.
ReadElementContentAsBoolean(string localName, string namespaceURI)432         public virtual bool ReadElementContentAsBoolean(string localName, string namespaceURI)
433         {
434             CheckElement(localName, namespaceURI);
435             return ReadElementContentAsBoolean();
436         }
437 
438         // Returns the content of the current element as a DateTime. Moves to the node following the element's end tag.
ReadElementContentAsDateTime()439         public virtual DateTime ReadElementContentAsDateTime()
440         {
441             if (SetupReadElementContentAsXxx("ReadElementContentAsDateTime"))
442             {
443                 DateTime value = ReadContentAsDateTime();
444                 FinishReadElementContentAsXxx();
445                 return value;
446             }
447             return XmlConvert.ToDateTime(string.Empty, XmlDateTimeSerializationMode.RoundtripKind);
448         }
449 
450         // Checks local name and namespace of the current element and returns its content as a DateTime.
451         // Moves to the node following the element's end tag.
ReadElementContentAsDateTime(string localName, string namespaceURI)452         public virtual DateTime ReadElementContentAsDateTime(string localName, string namespaceURI)
453         {
454             CheckElement(localName, namespaceURI);
455             return ReadElementContentAsDateTime();
456         }
457 
458         // Returns the content of the current element as a double. Moves to the node following the element's end tag.
ReadElementContentAsDouble()459         public virtual double ReadElementContentAsDouble()
460         {
461             if (SetupReadElementContentAsXxx("ReadElementContentAsDouble"))
462             {
463                 double value = ReadContentAsDouble();
464                 FinishReadElementContentAsXxx();
465                 return value;
466             }
467             return XmlConvert.ToDouble(string.Empty);
468         }
469 
470         // Checks local name and namespace of the current element and returns its content as a double.
471         // Moves to the node following the element's end tag.
ReadElementContentAsDouble(string localName, string namespaceURI)472         public virtual double ReadElementContentAsDouble(string localName, string namespaceURI)
473         {
474             CheckElement(localName, namespaceURI);
475             return ReadElementContentAsDouble();
476         }
477 
478         // Returns the content of the current element as a float. Moves to the node following the element's end tag.
ReadElementContentAsFloat()479         public virtual float ReadElementContentAsFloat()
480         {
481             if (SetupReadElementContentAsXxx("ReadElementContentAsFloat"))
482             {
483                 float value = ReadContentAsFloat();
484                 FinishReadElementContentAsXxx();
485                 return value;
486             }
487             return XmlConvert.ToSingle(string.Empty);
488         }
489 
490         // Checks local name and namespace of the current element and returns its content as a float.
491         // Moves to the node following the element's end tag.
ReadElementContentAsFloat(string localName, string namespaceURI)492         public virtual float ReadElementContentAsFloat(string localName, string namespaceURI)
493         {
494             CheckElement(localName, namespaceURI);
495             return ReadElementContentAsFloat();
496         }
497 
498         // Returns the content of the current element as a decimal. Moves to the node following the element's end tag.
ReadElementContentAsDecimal()499         public virtual decimal ReadElementContentAsDecimal()
500         {
501             if (SetupReadElementContentAsXxx("ReadElementContentAsDecimal"))
502             {
503                 decimal value = ReadContentAsDecimal();
504                 FinishReadElementContentAsXxx();
505                 return value;
506             }
507             return XmlConvert.ToDecimal(string.Empty);
508         }
509 
510         // Checks local name and namespace of the current element and returns its content as a decimal.
511         // Moves to the node following the element's end tag.
ReadElementContentAsDecimal(string localName, string namespaceURI)512         public virtual decimal ReadElementContentAsDecimal(string localName, string namespaceURI)
513         {
514             CheckElement(localName, namespaceURI);
515             return ReadElementContentAsDecimal();
516         }
517 
518         // Returns the content of the current element as an int. Moves to the node following the element's end tag.
ReadElementContentAsInt()519         public virtual int ReadElementContentAsInt()
520         {
521             if (SetupReadElementContentAsXxx("ReadElementContentAsInt"))
522             {
523                 int value = ReadContentAsInt();
524                 FinishReadElementContentAsXxx();
525                 return value;
526             }
527             return XmlConvert.ToInt32(string.Empty);
528         }
529 
530         // Checks local name and namespace of the current element and returns its content as an int.
531         // Moves to the node following the element's end tag.
ReadElementContentAsInt(string localName, string namespaceURI)532         public virtual int ReadElementContentAsInt(string localName, string namespaceURI)
533         {
534             CheckElement(localName, namespaceURI);
535             return ReadElementContentAsInt();
536         }
537 
538         // Returns the content of the current element as a long. Moves to the node following the element's end tag.
ReadElementContentAsLong()539         public virtual long ReadElementContentAsLong()
540         {
541             if (SetupReadElementContentAsXxx("ReadElementContentAsLong"))
542             {
543                 long value = ReadContentAsLong();
544                 FinishReadElementContentAsXxx();
545                 return value;
546             }
547             return XmlConvert.ToInt64(string.Empty);
548         }
549 
550         // Checks local name and namespace of the current element and returns its content as a long.
551         // Moves to the node following the element's end tag.
ReadElementContentAsLong(string localName, string namespaceURI)552         public virtual long ReadElementContentAsLong(string localName, string namespaceURI)
553         {
554             CheckElement(localName, namespaceURI);
555             return ReadElementContentAsLong();
556         }
557 
558         // Returns the content of the current element as a string. Moves to the node following the element's end tag.
ReadElementContentAsString()559         public virtual string ReadElementContentAsString()
560         {
561             if (SetupReadElementContentAsXxx("ReadElementContentAsString"))
562             {
563                 string value = ReadContentAsString();
564                 FinishReadElementContentAsXxx();
565                 return value;
566             }
567             return string.Empty;
568         }
569 
570         // Checks local name and namespace of the current element and returns its content as a string.
571         // Moves to the node following the element's end tag.
ReadElementContentAsString(string localName, string namespaceURI)572         public virtual string ReadElementContentAsString(string localName, string namespaceURI)
573         {
574             CheckElement(localName, namespaceURI);
575             return ReadElementContentAsString();
576         }
577 
578         // Returns the content of the current element as the requested type. Moves to the node following the element's end tag.
ReadElementContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver)579         public virtual object ReadElementContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver)
580         {
581             if (SetupReadElementContentAsXxx("ReadElementContentAs"))
582             {
583                 object value = ReadContentAs(returnType, namespaceResolver);
584                 FinishReadElementContentAsXxx();
585                 return value;
586             }
587             return (returnType == typeof(string)) ? string.Empty : XmlUntypedStringConverter.Instance.FromString(string.Empty, returnType, namespaceResolver);
588         }
589 
590         // Checks local name and namespace of the current element and returns its content as the requested type.
591         // Moves to the node following the element's end tag.
ReadElementContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)592         public virtual object ReadElementContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver, string localName, string namespaceURI)
593         {
594             CheckElement(localName, namespaceURI);
595             return ReadElementContentAs(returnType, namespaceResolver);
596         }
597 
598         // Attribute Accessors
599         // The number of attributes on the current node.
600         public abstract int AttributeCount { get; }
601 
602         // Gets the value of the attribute with the specified Name
GetAttribute(string name)603         public abstract string GetAttribute(string name);
604 
605         // Gets the value of the attribute with the LocalName and NamespaceURI
GetAttribute(string name, string namespaceURI)606         public abstract string GetAttribute(string name, string namespaceURI);
607 
608         // Gets the value of the attribute with the specified index.
GetAttribute(int i)609         public abstract string GetAttribute(int i);
610 
611         // Gets the value of the attribute with the specified index.
612         public virtual string this[int i]
613         {
614             get
615             {
616                 return GetAttribute(i);
617             }
618         }
619 
620         // Gets the value of the attribute with the specified Name.
621         public virtual string this[string name]
622         {
623             get
624             {
625                 return GetAttribute(name);
626             }
627         }
628 
629         // Gets the value of the attribute with the LocalName and NamespaceURI
630         public virtual string this[string name, string namespaceURI]
631         {
632             get
633             {
634                 return GetAttribute(name, namespaceURI);
635             }
636         }
637 
638         // Moves to the attribute with the specified Name.
MoveToAttribute(string name)639         public abstract bool MoveToAttribute(string name);
640 
641         // Moves to the attribute with the specified LocalName and NamespaceURI.
MoveToAttribute(string name, string ns)642         public abstract bool MoveToAttribute(string name, string ns);
643 
644         // Moves to the attribute with the specified index.
MoveToAttribute(int i)645         public virtual void MoveToAttribute(int i)
646         {
647             if (i < 0 || i >= AttributeCount)
648             {
649                 throw new ArgumentOutOfRangeException(nameof(i));
650             }
651             MoveToElement();
652             MoveToFirstAttribute();
653             int j = 0;
654             while (j < i)
655             {
656                 MoveToNextAttribute();
657                 j++;
658             }
659         }
660 
661         // Moves to the first attribute of the current node.
MoveToFirstAttribute()662         public abstract bool MoveToFirstAttribute();
663 
664         // Moves to the next attribute.
MoveToNextAttribute()665         public abstract bool MoveToNextAttribute();
666 
667         // Moves to the element that contains the current attribute node.
MoveToElement()668         public abstract bool MoveToElement();
669 
670         // Parses the attribute value into one or more Text and/or EntityReference node types.
671 
ReadAttributeValue()672         public abstract bool ReadAttributeValue();
673 
674         // Moving through the Stream
675         // Reads the next node from the stream.
676 
Read()677         public abstract bool Read();
678 
679         // Returns true when the XmlReader is positioned at the end of the stream.
680         public abstract bool EOF { get; }
681 
682         // Closes the stream/TextReader (if CloseInput==true), changes the ReadState to Closed, and sets all the properties back to zero/empty string.
Close()683         public virtual void Close() { }
684 
685         // Returns the read state of the XmlReader.
686         public abstract ReadState ReadState { get; }
687 
688         // Skips to the end tag of the current element.
Skip()689         public virtual void Skip()
690         {
691             if (ReadState != ReadState.Interactive)
692             {
693                 return;
694             }
695             SkipSubtree();
696         }
697 
698         // Gets the XmlNameTable associated with the XmlReader.
699         public abstract XmlNameTable NameTable { get; }
700 
701         // Resolves a namespace prefix in the current element's scope.
LookupNamespace(string prefix)702         public abstract string LookupNamespace(string prefix);
703 
704         // Returns true if the XmlReader can expand general entities.
705         public virtual bool CanResolveEntity
706         {
707             get
708             {
709                 return false;
710             }
711         }
712 
713         // Resolves the entity reference for nodes of NodeType EntityReference.
ResolveEntity()714         public abstract void ResolveEntity();
715 
716         // Binary content access methods
717         // Returns true if the reader supports call to ReadContentAsBase64, ReadElementContentAsBase64, ReadContentAsBinHex and ReadElementContentAsBinHex.
718         public virtual bool CanReadBinaryContent
719         {
720             get
721             {
722                 return false;
723             }
724         }
725 
726         // Returns decoded bytes of the current base64 text content. Call this methods until it returns 0 to get all the data.
ReadContentAsBase64(byte[] buffer, int index, int count)727         public virtual int ReadContentAsBase64(byte[] buffer, int index, int count)
728         {
729             throw new NotSupportedException(SR.Format(SR.Xml_ReadBinaryContentNotSupported, "ReadContentAsBase64"));
730         }
731 
732         // Returns decoded bytes of the current base64 element content. Call this methods until it returns 0 to get all the data.
ReadElementContentAsBase64(byte[] buffer, int index, int count)733         public virtual int ReadElementContentAsBase64(byte[] buffer, int index, int count)
734         {
735             throw new NotSupportedException(SR.Format(SR.Xml_ReadBinaryContentNotSupported, "ReadElementContentAsBase64"));
736         }
737 
738         // Returns decoded bytes of the current binhex text content. Call this methods until it returns 0 to get all the data.
ReadContentAsBinHex(byte[] buffer, int index, int count)739         public virtual int ReadContentAsBinHex(byte[] buffer, int index, int count)
740         {
741             throw new NotSupportedException(SR.Format(SR.Xml_ReadBinaryContentNotSupported, "ReadContentAsBinHex"));
742         }
743 
744         // Returns decoded bytes of the current binhex element content. Call this methods until it returns 0 to get all the data.
ReadElementContentAsBinHex(byte[] buffer, int index, int count)745         public virtual int ReadElementContentAsBinHex(byte[] buffer, int index, int count)
746         {
747             throw new NotSupportedException(SR.Format(SR.Xml_ReadBinaryContentNotSupported, "ReadElementContentAsBinHex"));
748         }
749 
750         // Text streaming methods
751 
752         // Returns true if the XmlReader supports calls to ReadValueChunk.
753         public virtual bool CanReadValueChunk
754         {
755             get
756             {
757                 return false;
758             }
759         }
760 
761         // Returns a chunk of the value of the current node. Call this method in a loop to get all the data.
762         // Use this method to get a streaming access to the value of the current node.
ReadValueChunk(char[] buffer, int index, int count)763         public virtual int ReadValueChunk(char[] buffer, int index, int count)
764         {
765             throw new NotSupportedException(SR.Xml_ReadValueChunkNotSupported);
766         }
767 
768         // Virtual helper methods
769         // Reads the contents of an element as a string. Stops of comments, PIs or entity references.
770         [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
ReadString()771         public virtual string ReadString()
772         {
773             if (this.ReadState != ReadState.Interactive)
774             {
775                 return string.Empty;
776             }
777             this.MoveToElement();
778             if (this.NodeType == XmlNodeType.Element)
779             {
780                 if (this.IsEmptyElement)
781                 {
782                     return string.Empty;
783                 }
784                 else if (!this.Read())
785                 {
786                     throw new InvalidOperationException(SR.Xml_InvalidOperation);
787                 }
788                 if (this.NodeType == XmlNodeType.EndElement)
789                 {
790                     return string.Empty;
791                 }
792             }
793             string result = string.Empty;
794             while (IsTextualNode(this.NodeType))
795             {
796                 result += this.Value;
797                 if (!this.Read())
798                 {
799                     break;
800                 }
801             }
802             return result;
803         }
804 
805         // Checks whether the current node is a content (non-whitespace text, CDATA, Element, EndElement, EntityReference
806         // or EndEntity) node. If the node is not a content node, then the method skips ahead to the next content node or
807         // end of file. Skips over nodes of type ProcessingInstruction, DocumentType, Comment, Whitespace and SignificantWhitespace.
MoveToContent()808         public virtual XmlNodeType MoveToContent()
809         {
810             do
811             {
812                 switch (this.NodeType)
813                 {
814                     case XmlNodeType.Attribute:
815                         MoveToElement();
816                         goto case XmlNodeType.Element;
817                     case XmlNodeType.Element:
818                     case XmlNodeType.EndElement:
819                     case XmlNodeType.CDATA:
820                     case XmlNodeType.Text:
821                     case XmlNodeType.EntityReference:
822                     case XmlNodeType.EndEntity:
823                         return this.NodeType;
824                 }
825             } while (Read());
826             return this.NodeType;
827         }
828 
829         // Checks that the current node is an element and advances the reader to the next node.
ReadStartElement()830         public virtual void ReadStartElement()
831         {
832             if (MoveToContent() != XmlNodeType.Element)
833             {
834                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
835             }
836             Read();
837         }
838 
839         // Checks that the current content node is an element with the given Name and advances the reader to the next node.
ReadStartElement(string name)840         public virtual void ReadStartElement(string name)
841         {
842             if (MoveToContent() != XmlNodeType.Element)
843             {
844                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
845             }
846             if (this.Name == name)
847             {
848                 Read();
849             }
850             else
851             {
852                 throw new XmlException(SR.Xml_ElementNotFound, name, this as IXmlLineInfo);
853             }
854         }
855 
856         // Checks that the current content node is an element with the given LocalName and NamespaceURI
857         // and advances the reader to the next node.
ReadStartElement(string localname, string ns)858         public virtual void ReadStartElement(string localname, string ns)
859         {
860             if (MoveToContent() != XmlNodeType.Element)
861             {
862                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
863             }
864             if (this.LocalName == localname && this.NamespaceURI == ns)
865             {
866                 Read();
867             }
868             else
869             {
870                 throw new XmlException(SR.Xml_ElementNotFoundNs, new string[2] { localname, ns }, this as IXmlLineInfo);
871             }
872         }
873 
874         // Reads a text-only element.
875         [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
ReadElementString()876         public virtual string ReadElementString()
877         {
878             string result = string.Empty;
879 
880             if (MoveToContent() != XmlNodeType.Element)
881             {
882                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
883             }
884             if (!this.IsEmptyElement)
885             {
886                 Read();
887                 result = ReadString();
888                 if (this.NodeType != XmlNodeType.EndElement)
889                 {
890                     throw new XmlException(SR.Xml_UnexpectedNodeInSimpleContent, new string[] { this.NodeType.ToString(), "ReadElementString" }, this as IXmlLineInfo);
891                 }
892                 Read();
893             }
894             else
895             {
896                 Read();
897             }
898             return result;
899         }
900 
901         // Checks that the Name property of the element found matches the given string before reading a text-only element.
902         [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
ReadElementString(string name)903         public virtual string ReadElementString(string name)
904         {
905             string result = string.Empty;
906 
907             if (MoveToContent() != XmlNodeType.Element)
908             {
909                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
910             }
911             if (this.Name != name)
912             {
913                 throw new XmlException(SR.Xml_ElementNotFound, name, this as IXmlLineInfo);
914             }
915 
916             if (!this.IsEmptyElement)
917             {
918                 //Read();
919                 result = ReadString();
920                 if (this.NodeType != XmlNodeType.EndElement)
921                 {
922                     throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
923                 }
924                 Read();
925             }
926             else
927             {
928                 Read();
929             }
930             return result;
931         }
932 
933         // Checks that the LocalName and NamespaceURI properties of the element found matches the given strings
934         // before reading a text-only element.
935         [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
ReadElementString(string localname, string ns)936         public virtual string ReadElementString(string localname, string ns)
937         {
938             string result = string.Empty;
939             if (MoveToContent() != XmlNodeType.Element)
940             {
941                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
942             }
943             if (this.LocalName != localname || this.NamespaceURI != ns)
944             {
945                 throw new XmlException(SR.Xml_ElementNotFoundNs, new string[2] { localname, ns }, this as IXmlLineInfo);
946             }
947 
948             if (!this.IsEmptyElement)
949             {
950                 //Read();
951                 result = ReadString();
952                 if (this.NodeType != XmlNodeType.EndElement)
953                 {
954                     throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
955                 }
956                 Read();
957             }
958             else
959             {
960                 Read();
961             }
962 
963             return result;
964         }
965 
966         // Checks that the current content node is an end tag and advances the reader to the next node.
ReadEndElement()967         public virtual void ReadEndElement()
968         {
969             if (MoveToContent() != XmlNodeType.EndElement)
970             {
971                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
972             }
973             Read();
974         }
975 
976         // Calls MoveToContent and tests if the current content node is a start tag or empty element tag (XmlNodeType.Element).
IsStartElement()977         public virtual bool IsStartElement()
978         {
979             return MoveToContent() == XmlNodeType.Element;
980         }
981 
982         // Calls MoveToContentand tests if the current content node is a start tag or empty element tag (XmlNodeType.Element) and if the
983         // Name property of the element found matches the given argument.
IsStartElement(string name)984         public virtual bool IsStartElement(string name)
985         {
986             return (MoveToContent() == XmlNodeType.Element) &&
987                    (this.Name == name);
988         }
989 
990         // Calls MoveToContent and tests if the current content node is a start tag or empty element tag (XmlNodeType.Element) and if
991         // the LocalName and NamespaceURI properties of the element found match the given strings.
IsStartElement(string localname, string ns)992         public virtual bool IsStartElement(string localname, string ns)
993         {
994             return (MoveToContent() == XmlNodeType.Element) &&
995                    (this.LocalName == localname && this.NamespaceURI == ns);
996         }
997 
998         // Reads to the following element with the given Name.
ReadToFollowing(string name)999         public virtual bool ReadToFollowing(string name)
1000         {
1001             if (name == null || name.Length == 0)
1002             {
1003                 throw XmlConvert.CreateInvalidNameArgumentException(name, nameof(name));
1004             }
1005             // atomize name
1006             name = NameTable.Add(name);
1007 
1008             // find following element with that name
1009             while (Read())
1010             {
1011                 if (NodeType == XmlNodeType.Element && Ref.Equal(name, Name))
1012                 {
1013                     return true;
1014                 }
1015             }
1016             return false;
1017         }
1018 
1019         // Reads to the following element with the given LocalName and NamespaceURI.
ReadToFollowing(string localName, string namespaceURI)1020         public virtual bool ReadToFollowing(string localName, string namespaceURI)
1021         {
1022             if (localName == null || localName.Length == 0)
1023             {
1024                 throw XmlConvert.CreateInvalidNameArgumentException(localName, nameof(localName));
1025             }
1026             if (namespaceURI == null)
1027             {
1028                 throw new ArgumentNullException(nameof(namespaceURI));
1029             }
1030 
1031             // atomize local name and namespace
1032             localName = NameTable.Add(localName);
1033             namespaceURI = NameTable.Add(namespaceURI);
1034 
1035             // find following element with that name
1036             while (Read())
1037             {
1038                 if (NodeType == XmlNodeType.Element && Ref.Equal(localName, LocalName) && Ref.Equal(namespaceURI, NamespaceURI))
1039                 {
1040                     return true;
1041                 }
1042             }
1043             return false;
1044         }
1045 
1046         // Reads to the first descendant of the current element with the given Name.
ReadToDescendant(string name)1047         public virtual bool ReadToDescendant(string name)
1048         {
1049             if (name == null || name.Length == 0)
1050             {
1051                 throw XmlConvert.CreateInvalidNameArgumentException(name, nameof(name));
1052             }
1053             // save the element or root depth
1054             int parentDepth = Depth;
1055             if (NodeType != XmlNodeType.Element)
1056             {
1057                 // adjust the depth if we are on root node
1058                 if (ReadState == ReadState.Initial)
1059                 {
1060                     Debug.Assert(parentDepth == 0);
1061                     parentDepth--;
1062                 }
1063                 else
1064                 {
1065                     return false;
1066                 }
1067             }
1068             else if (IsEmptyElement)
1069             {
1070                 return false;
1071             }
1072 
1073             // atomize name
1074             name = NameTable.Add(name);
1075 
1076             // find the descendant
1077             while (Read() && Depth > parentDepth)
1078             {
1079                 if (NodeType == XmlNodeType.Element && Ref.Equal(name, Name))
1080                 {
1081                     return true;
1082                 }
1083             }
1084             Debug.Assert(NodeType == XmlNodeType.EndElement || NodeType == XmlNodeType.None || ReadState == ReadState.Error);
1085             return false;
1086         }
1087 
1088         // Reads to the first descendant of the current element with the given LocalName and NamespaceURI.
ReadToDescendant(string localName, string namespaceURI)1089         public virtual bool ReadToDescendant(string localName, string namespaceURI)
1090         {
1091             if (localName == null || localName.Length == 0)
1092             {
1093                 throw XmlConvert.CreateInvalidNameArgumentException(localName, nameof(localName));
1094             }
1095             if (namespaceURI == null)
1096             {
1097                 throw new ArgumentNullException(nameof(namespaceURI));
1098             }
1099             // save the element or root depth
1100             int parentDepth = Depth;
1101             if (NodeType != XmlNodeType.Element)
1102             {
1103                 // adjust the depth if we are on root node
1104                 if (ReadState == ReadState.Initial)
1105                 {
1106                     Debug.Assert(parentDepth == 0);
1107                     parentDepth--;
1108                 }
1109                 else
1110                 {
1111                     return false;
1112                 }
1113             }
1114             else if (IsEmptyElement)
1115             {
1116                 return false;
1117             }
1118 
1119             // atomize local name and namespace
1120             localName = NameTable.Add(localName);
1121             namespaceURI = NameTable.Add(namespaceURI);
1122 
1123             // find the descendant
1124             while (Read() && Depth > parentDepth)
1125             {
1126                 if (NodeType == XmlNodeType.Element && Ref.Equal(localName, LocalName) && Ref.Equal(namespaceURI, NamespaceURI))
1127                 {
1128                     return true;
1129                 }
1130             }
1131             Debug.Assert(NodeType == XmlNodeType.EndElement);
1132             return false;
1133         }
1134 
1135         // Reads to the next sibling of the current element with the given Name.
ReadToNextSibling(string name)1136         public virtual bool ReadToNextSibling(string name)
1137         {
1138             if (name == null || name.Length == 0)
1139             {
1140                 throw XmlConvert.CreateInvalidNameArgumentException(name, nameof(name));
1141             }
1142 
1143             // atomize name
1144             name = NameTable.Add(name);
1145 
1146             // find the next sibling
1147             XmlNodeType nt;
1148             do
1149             {
1150                 if (!SkipSubtree())
1151                 {
1152                     break;
1153                 }
1154                 nt = NodeType;
1155                 if (nt == XmlNodeType.Element && Ref.Equal(name, Name))
1156                 {
1157                     return true;
1158                 }
1159             } while (nt != XmlNodeType.EndElement && !EOF);
1160             return false;
1161         }
1162 
1163         // Reads to the next sibling of the current element with the given LocalName and NamespaceURI.
ReadToNextSibling(string localName, string namespaceURI)1164         public virtual bool ReadToNextSibling(string localName, string namespaceURI)
1165         {
1166             if (localName == null || localName.Length == 0)
1167             {
1168                 throw XmlConvert.CreateInvalidNameArgumentException(localName, nameof(localName));
1169             }
1170             if (namespaceURI == null)
1171             {
1172                 throw new ArgumentNullException(nameof(namespaceURI));
1173             }
1174 
1175             // atomize local name and namespace
1176             localName = NameTable.Add(localName);
1177             namespaceURI = NameTable.Add(namespaceURI);
1178 
1179             // find the next sibling
1180             XmlNodeType nt;
1181             do
1182             {
1183                 if (!SkipSubtree())
1184                 {
1185                     break;
1186                 }
1187                 nt = NodeType;
1188                 if (nt == XmlNodeType.Element && Ref.Equal(localName, LocalName) && Ref.Equal(namespaceURI, NamespaceURI))
1189                 {
1190                     return true;
1191                 }
1192             } while (nt != XmlNodeType.EndElement && !EOF);
1193             return false;
1194         }
1195 
1196         // Returns true if the given argument is a valid Name.
IsName(string str)1197         public static bool IsName(string str)
1198         {
1199             if (str == null)
1200             {
1201                 throw new NullReferenceException();
1202             }
1203             return ValidateNames.IsNameNoNamespaces(str);
1204         }
1205 
1206         // Returns true if the given argument is a valid NmToken.
IsNameToken(string str)1207         public static bool IsNameToken(string str)
1208         {
1209             if (str == null)
1210             {
1211                 throw new NullReferenceException();
1212             }
1213             return ValidateNames.IsNmtokenNoNamespaces(str);
1214         }
1215 
1216         // Returns the inner content (including markup) of an element or attribute as a string.
ReadInnerXml()1217         public virtual string ReadInnerXml()
1218         {
1219             if (ReadState != ReadState.Interactive)
1220             {
1221                 return string.Empty;
1222             }
1223             if ((this.NodeType != XmlNodeType.Attribute) && (this.NodeType != XmlNodeType.Element))
1224             {
1225                 Read();
1226                 return string.Empty;
1227             }
1228 
1229             StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
1230             XmlWriter xtw = CreateWriterForInnerOuterXml(sw);
1231 
1232             try
1233             {
1234                 if (this.NodeType == XmlNodeType.Attribute)
1235                 {
1236                     ((XmlTextWriter)xtw).QuoteChar = this.QuoteChar;
1237                     WriteAttributeValue(xtw);
1238                 }
1239                 if (this.NodeType == XmlNodeType.Element)
1240                 {
1241                     this.WriteNode(xtw, false);
1242                 }
1243             }
1244             finally
1245             {
1246                 xtw.Close();
1247             }
1248             return sw.ToString();
1249         }
1250 
1251         // Writes the content (inner XML) of the current node into the provided XmlWriter.
WriteNode(XmlWriter xtw, bool defattr)1252         private void WriteNode(XmlWriter xtw, bool defattr)
1253         {
1254             Debug.Assert(xtw is XmlTextWriter);
1255             int d = this.NodeType == XmlNodeType.None ? -1 : this.Depth;
1256             while (this.Read() && (d < this.Depth))
1257             {
1258                 switch (this.NodeType)
1259                 {
1260                     case XmlNodeType.Element:
1261                         xtw.WriteStartElement(this.Prefix, this.LocalName, this.NamespaceURI);
1262                         ((XmlTextWriter)xtw).QuoteChar = this.QuoteChar;
1263                         xtw.WriteAttributes(this, defattr);
1264                         if (this.IsEmptyElement)
1265                         {
1266                             xtw.WriteEndElement();
1267                         }
1268                         break;
1269                     case XmlNodeType.Text:
1270                         xtw.WriteString(this.Value);
1271                         break;
1272                     case XmlNodeType.Whitespace:
1273                     case XmlNodeType.SignificantWhitespace:
1274                         xtw.WriteWhitespace(this.Value);
1275                         break;
1276                     case XmlNodeType.CDATA:
1277                         xtw.WriteCData(this.Value);
1278                         break;
1279                     case XmlNodeType.EntityReference:
1280                         xtw.WriteEntityRef(this.Name);
1281                         break;
1282                     case XmlNodeType.XmlDeclaration:
1283                     case XmlNodeType.ProcessingInstruction:
1284                         xtw.WriteProcessingInstruction(this.Name, this.Value);
1285                         break;
1286                     case XmlNodeType.DocumentType:
1287                         xtw.WriteDocType(this.Name, this.GetAttribute("PUBLIC"), this.GetAttribute("SYSTEM"), this.Value);
1288                         break;
1289                     case XmlNodeType.Comment:
1290                         xtw.WriteComment(this.Value);
1291                         break;
1292                     case XmlNodeType.EndElement:
1293                         xtw.WriteFullEndElement();
1294                         break;
1295                 }
1296             }
1297             if (d == this.Depth && this.NodeType == XmlNodeType.EndElement)
1298             {
1299                 Read();
1300             }
1301         }
1302 
1303         // Writes the attribute into the provided XmlWriter.
WriteAttributeValue(XmlWriter xtw)1304         private void WriteAttributeValue(XmlWriter xtw)
1305         {
1306             string attrName = this.Name;
1307             while (ReadAttributeValue())
1308             {
1309                 if (this.NodeType == XmlNodeType.EntityReference)
1310                 {
1311                     xtw.WriteEntityRef(this.Name);
1312                 }
1313                 else
1314                 {
1315                     xtw.WriteString(this.Value);
1316                 }
1317             }
1318             this.MoveToAttribute(attrName);
1319         }
1320 
1321         // Returns the current element and its descendants or an attribute as a string.
ReadOuterXml()1322         public virtual string ReadOuterXml()
1323         {
1324             if (ReadState != ReadState.Interactive)
1325             {
1326                 return string.Empty;
1327             }
1328             if ((this.NodeType != XmlNodeType.Attribute) && (this.NodeType != XmlNodeType.Element))
1329             {
1330                 Read();
1331                 return string.Empty;
1332             }
1333 
1334             StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
1335             XmlWriter xtw = CreateWriterForInnerOuterXml(sw);
1336 
1337             try
1338             {
1339                 if (this.NodeType == XmlNodeType.Attribute)
1340                 {
1341                     xtw.WriteStartAttribute(this.Prefix, this.LocalName, this.NamespaceURI);
1342                     WriteAttributeValue(xtw);
1343                     xtw.WriteEndAttribute();
1344                 }
1345                 else
1346                 {
1347                     xtw.WriteNode(this, false);
1348                 }
1349             }
1350             finally
1351             {
1352                 xtw.Close();
1353             }
1354             return sw.ToString();
1355         }
1356 
CreateWriterForInnerOuterXml(StringWriter sw)1357         private XmlWriter CreateWriterForInnerOuterXml(StringWriter sw)
1358         {
1359             XmlTextWriter w = new XmlTextWriter(sw);
1360             // This is a V1 hack; we can put a custom implementation of ReadOuterXml on XmlTextReader/XmlValidatingReader
1361             SetNamespacesFlag(w);
1362             return w;
1363         }
1364 
SetNamespacesFlag(XmlTextWriter xtw)1365         private void SetNamespacesFlag(XmlTextWriter xtw)
1366         {
1367             XmlTextReader tr = this as XmlTextReader;
1368             if (tr != null)
1369             {
1370                 xtw.Namespaces = tr.Namespaces;
1371             }
1372             else
1373             {
1374 #pragma warning disable 618
1375                 XmlValidatingReader vr = this as XmlValidatingReader;
1376                 if (vr != null)
1377                 {
1378                     xtw.Namespaces = vr.Namespaces;
1379                 }
1380             }
1381 #pragma warning restore 618
1382         }
1383 
1384         // Returns an XmlReader that will read only the current element and its descendants and then go to EOF state.
ReadSubtree()1385         public virtual XmlReader ReadSubtree()
1386         {
1387             if (NodeType != XmlNodeType.Element)
1388             {
1389                 throw new InvalidOperationException(SR.Xml_ReadSubtreeNotOnElement);
1390             }
1391             return new XmlSubtreeReader(this);
1392         }
1393 
1394         // Returns true when the current node has any attributes.
1395         public virtual bool HasAttributes
1396         {
1397             get
1398             {
1399                 return AttributeCount > 0;
1400             }
1401         }
1402 
1403         //
1404         // IDisposable interface
1405         //
Dispose()1406         public void Dispose()
1407         {
1408             Dispose(true);
1409         }
1410 
Dispose(bool disposing)1411         protected virtual void Dispose(bool disposing)
1412         {
1413             if (disposing && ReadState != ReadState.Closed)
1414             {
1415                 Close();
1416             }
1417         }
1418 
1419         //
1420         // Internal methods
1421         //
1422         // Validation support
1423         internal virtual XmlNamespaceManager NamespaceManager
1424         {
1425             get
1426             {
1427                 return null;
1428             }
1429         }
1430 
IsTextualNode(XmlNodeType nodeType)1431         internal static bool IsTextualNode(XmlNodeType nodeType)
1432         {
1433 #if DEBUG
1434             // This code verifies IsTextualNodeBitmap mapping of XmlNodeType to a bool specifying
1435             // whether the node is 'textual' = Text, CDATA, Whitespace or SignificantWhitespace.
1436             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.None)));
1437             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Element)));
1438             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Attribute)));
1439             Debug.Assert(0 != (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Text)));
1440             Debug.Assert(0 != (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.CDATA)));
1441             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.EntityReference)));
1442             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Entity)));
1443             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.ProcessingInstruction)));
1444             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Comment)));
1445             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Document)));
1446             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.DocumentType)));
1447             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.DocumentFragment)));
1448             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Notation)));
1449             Debug.Assert(0 != (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.Whitespace)));
1450             Debug.Assert(0 != (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.SignificantWhitespace)));
1451             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.EndElement)));
1452             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.EndEntity)));
1453             Debug.Assert(0 == (s_isTextualNodeBitmap & (1 << (int)XmlNodeType.XmlDeclaration)));
1454 #endif
1455             return 0 != (s_isTextualNodeBitmap & (1 << (int)nodeType));
1456         }
1457 
CanReadContentAs(XmlNodeType nodeType)1458         internal static bool CanReadContentAs(XmlNodeType nodeType)
1459         {
1460 #if DEBUG
1461             // This code verifies IsTextualNodeBitmap mapping of XmlNodeType to a bool specifying
1462             // whether ReadContentAsXxx calls are allowed on his node type
1463             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.None)));
1464             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Element)));
1465             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Attribute)));
1466             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Text)));
1467             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.CDATA)));
1468             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.EntityReference)));
1469             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Entity)));
1470             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.ProcessingInstruction)));
1471             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Comment)));
1472             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Document)));
1473             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.DocumentType)));
1474             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.DocumentFragment)));
1475             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Notation)));
1476             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.Whitespace)));
1477             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.SignificantWhitespace)));
1478             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.EndElement)));
1479             Debug.Assert(0 != (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.EndEntity)));
1480             Debug.Assert(0 == (s_canReadContentAsBitmap & (1 << (int)XmlNodeType.XmlDeclaration)));
1481 #endif
1482             return 0 != (s_canReadContentAsBitmap & (1 << (int)nodeType));
1483         }
1484 
HasValueInternal(XmlNodeType nodeType)1485         internal static bool HasValueInternal(XmlNodeType nodeType)
1486         {
1487 #if DEBUG
1488             // This code verifies HasValueBitmap mapping of XmlNodeType to a bool specifying
1489             // whether the node can have a non-empty Value
1490             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.None)));
1491             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.Element)));
1492             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.Attribute)));
1493             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.Text)));
1494             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.CDATA)));
1495             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.EntityReference)));
1496             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.Entity)));
1497             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.ProcessingInstruction)));
1498             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.Comment)));
1499             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.Document)));
1500             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.DocumentType)));
1501             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.DocumentFragment)));
1502             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.Notation)));
1503             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.Whitespace)));
1504             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.SignificantWhitespace)));
1505             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.EndElement)));
1506             Debug.Assert(0 == (s_hasValueBitmap & (1 << (int)XmlNodeType.EndEntity)));
1507             Debug.Assert(0 != (s_hasValueBitmap & (1 << (int)XmlNodeType.XmlDeclaration)));
1508 #endif
1509             return 0 != (s_hasValueBitmap & (1 << (int)nodeType));
1510         }
1511 
1512         //
1513         // Private methods
1514         //
1515         //SkipSubTree is called whenever validation of the skipped subtree is required on a reader with XsdValidation
SkipSubtree()1516         private bool SkipSubtree()
1517         {
1518             MoveToElement();
1519             if (NodeType == XmlNodeType.Element && !IsEmptyElement)
1520             {
1521                 int depth = Depth;
1522 
1523                 while (Read() && depth < Depth)
1524                 {
1525                     // Nothing, just read on
1526                 }
1527 
1528                 // consume end tag
1529                 if (NodeType == XmlNodeType.EndElement)
1530                     return Read();
1531             }
1532             else
1533             {
1534                 return Read();
1535             }
1536 
1537             return false;
1538         }
1539 
CheckElement(string localName, string namespaceURI)1540         internal void CheckElement(string localName, string namespaceURI)
1541         {
1542             if (localName == null || localName.Length == 0)
1543             {
1544                 throw XmlConvert.CreateInvalidNameArgumentException(localName, nameof(localName));
1545             }
1546             if (namespaceURI == null)
1547             {
1548                 throw new ArgumentNullException(nameof(namespaceURI));
1549             }
1550             if (NodeType != XmlNodeType.Element)
1551             {
1552                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString(), this as IXmlLineInfo);
1553             }
1554             if (LocalName != localName || NamespaceURI != namespaceURI)
1555             {
1556                 throw new XmlException(SR.Xml_ElementNotFoundNs, new string[2] { localName, namespaceURI }, this as IXmlLineInfo);
1557             }
1558         }
1559 
CreateReadContentAsException(string methodName)1560         internal Exception CreateReadContentAsException(string methodName)
1561         {
1562             return CreateReadContentAsException(methodName, NodeType, this as IXmlLineInfo);
1563         }
1564 
CreateReadElementContentAsException(string methodName)1565         internal Exception CreateReadElementContentAsException(string methodName)
1566         {
1567             return CreateReadElementContentAsException(methodName, NodeType, this as IXmlLineInfo);
1568         }
1569 
CanReadContentAs()1570         internal bool CanReadContentAs()
1571         {
1572             return CanReadContentAs(this.NodeType);
1573         }
1574 
CreateReadContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo lineInfo)1575         internal static Exception CreateReadContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo lineInfo)
1576         {
1577             return new InvalidOperationException(AddLineInfo(SR.Format(SR.Xml_InvalidReadContentAs, new string[] { methodName, nodeType.ToString() }), lineInfo));
1578         }
1579 
CreateReadElementContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo lineInfo)1580         internal static Exception CreateReadElementContentAsException(string methodName, XmlNodeType nodeType, IXmlLineInfo lineInfo)
1581         {
1582             return new InvalidOperationException(AddLineInfo(SR.Format(SR.Xml_InvalidReadElementContentAs, new string[] { methodName, nodeType.ToString() }), lineInfo));
1583         }
1584 
AddLineInfo(string message, IXmlLineInfo lineInfo)1585         private static string AddLineInfo(string message, IXmlLineInfo lineInfo)
1586         {
1587             if (lineInfo != null)
1588             {
1589                 string[] lineArgs = new string[2];
1590                 lineArgs[0] = lineInfo.LineNumber.ToString(CultureInfo.InvariantCulture);
1591                 lineArgs[1] = lineInfo.LinePosition.ToString(CultureInfo.InvariantCulture);
1592                 message += " " + SR.Format(SR.Xml_ErrorPosition, lineArgs);
1593             }
1594             return message;
1595         }
1596 
InternalReadContentAsString()1597         internal string InternalReadContentAsString()
1598         {
1599             string value = string.Empty;
1600             StringBuilder sb = null;
1601             do
1602             {
1603                 switch (this.NodeType)
1604                 {
1605                     case XmlNodeType.Attribute:
1606                         return this.Value;
1607                     case XmlNodeType.Text:
1608                     case XmlNodeType.Whitespace:
1609                     case XmlNodeType.SignificantWhitespace:
1610                     case XmlNodeType.CDATA:
1611                         // merge text content
1612                         if (value.Length == 0)
1613                         {
1614                             value = this.Value;
1615                         }
1616                         else
1617                         {
1618                             if (sb == null)
1619                             {
1620                                 sb = new StringBuilder();
1621                                 sb.Append(value);
1622                             }
1623                             sb.Append(this.Value);
1624                         }
1625                         break;
1626                     case XmlNodeType.ProcessingInstruction:
1627                     case XmlNodeType.Comment:
1628                     case XmlNodeType.EndEntity:
1629                         // skip comments, pis and end entity nodes
1630                         break;
1631                     case XmlNodeType.EntityReference:
1632                         if (this.CanResolveEntity)
1633                         {
1634                             this.ResolveEntity();
1635                             break;
1636                         }
1637                         goto default;
1638                     case XmlNodeType.EndElement:
1639                     default:
1640                         goto ReturnContent;
1641                 }
1642             } while ((this.AttributeCount != 0) ? this.ReadAttributeValue() : this.Read());
1643 
1644         ReturnContent:
1645             return (sb == null) ? value : sb.ToString();
1646         }
1647 
SetupReadElementContentAsXxx(string methodName)1648         private bool SetupReadElementContentAsXxx(string methodName)
1649         {
1650             if (this.NodeType != XmlNodeType.Element)
1651             {
1652                 throw CreateReadElementContentAsException(methodName);
1653             }
1654 
1655             bool isEmptyElement = this.IsEmptyElement;
1656 
1657             // move to content or beyond the empty element
1658             this.Read();
1659 
1660             if (isEmptyElement)
1661             {
1662                 return false;
1663             }
1664 
1665             XmlNodeType nodeType = this.NodeType;
1666             if (nodeType == XmlNodeType.EndElement)
1667             {
1668                 this.Read();
1669                 return false;
1670             }
1671             else if (nodeType == XmlNodeType.Element)
1672             {
1673                 throw new XmlException(SR.Xml_MixedReadElementContentAs, string.Empty, this as IXmlLineInfo);
1674             }
1675             return true;
1676         }
1677 
FinishReadElementContentAsXxx()1678         private void FinishReadElementContentAsXxx()
1679         {
1680             if (this.NodeType != XmlNodeType.EndElement)
1681             {
1682                 throw new XmlException(SR.Xml_InvalidNodeType, this.NodeType.ToString());
1683             }
1684             this.Read();
1685         }
1686 
1687         internal bool IsDefaultInternal
1688         {
1689             get
1690             {
1691                 if (this.IsDefault)
1692                 {
1693                     return true;
1694                 }
1695                 IXmlSchemaInfo schemaInfo = this.SchemaInfo;
1696                 if (schemaInfo != null && schemaInfo.IsDefault)
1697                 {
1698                     return true;
1699                 }
1700                 return false;
1701             }
1702         }
1703 
1704         internal virtual IDtdInfo DtdInfo
1705         {
1706             get
1707             {
1708                 return null;
1709             }
1710         }
1711 
GetV1ConformanceLevel(XmlReader reader)1712         internal static ConformanceLevel GetV1ConformanceLevel(XmlReader reader)
1713         {
1714             XmlTextReaderImpl tri = GetXmlTextReaderImpl(reader);
1715             return tri != null ? tri.V1ComformanceLevel : ConformanceLevel.Document;
1716         }
1717 
GetXmlTextReaderImpl(XmlReader reader)1718         private static XmlTextReaderImpl GetXmlTextReaderImpl(XmlReader reader)
1719         {
1720             XmlTextReaderImpl tri = reader as XmlTextReaderImpl;
1721             if (tri != null)
1722             {
1723                 return tri;
1724             }
1725 
1726             XmlTextReader tr = reader as XmlTextReader;
1727             if (tr != null)
1728             {
1729                 return tr.Impl;
1730             }
1731 
1732             XmlValidatingReaderImpl vri = reader as XmlValidatingReaderImpl;
1733             if (vri != null)
1734             {
1735                 return vri.ReaderImpl;
1736             }
1737 #pragma warning disable 618
1738             XmlValidatingReader vr = reader as XmlValidatingReader;
1739 #pragma warning restore 618
1740             if (vr != null)
1741             {
1742                 return vr.Impl.ReaderImpl;
1743             }
1744 
1745             return null;
1746         }
1747 
1748         //
1749         // Static methods for creating readers
1750         //
1751 
1752         // Creates an XmlReader for parsing XML from the given Uri.
Create(string inputUri)1753         public static XmlReader Create(string inputUri)
1754         {
1755             return XmlReader.Create(inputUri, (XmlReaderSettings)null, (XmlParserContext)null);
1756         }
1757 
1758         // Creates an XmlReader according to the settings for parsing XML from the given Uri.
Create(string inputUri, XmlReaderSettings settings)1759         public static XmlReader Create(string inputUri, XmlReaderSettings settings)
1760         {
1761             return XmlReader.Create(inputUri, settings, (XmlParserContext)null);
1762         }
1763 
1764         // Creates an XmlReader according to the settings and parser context for parsing XML from the given Uri.
Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)1765         public static XmlReader Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)
1766         {
1767             if (settings == null)
1768             {
1769                 settings = new XmlReaderSettings();
1770             }
1771             return settings.CreateReader(inputUri, inputContext);
1772         }
1773 
1774         // Creates an XmlReader according for parsing XML from the given stream.
Create(Stream input)1775         public static XmlReader Create(Stream input)
1776         {
1777             return Create(input, (XmlReaderSettings)null, (string)string.Empty);
1778         }
1779 
1780         // Creates an XmlReader according to the settings for parsing XML from the given stream.
Create(Stream input, XmlReaderSettings settings)1781         public static XmlReader Create(Stream input, XmlReaderSettings settings)
1782         {
1783             return Create(input, settings, string.Empty);
1784         }
1785 
1786         // Creates an XmlReader according to the settings and base Uri for parsing XML from the given stream.
Create(Stream input, XmlReaderSettings settings, String baseUri)1787         public static XmlReader Create(Stream input, XmlReaderSettings settings, String baseUri)
1788         {
1789             if (settings == null)
1790             {
1791                 settings = new XmlReaderSettings();
1792             }
1793             return settings.CreateReader(input, null, (string)baseUri, null);
1794         }
1795 
1796         // Creates an XmlReader according to the settings and parser context for parsing XML from the given stream.
Create(Stream input, XmlReaderSettings settings, XmlParserContext inputContext)1797         public static XmlReader Create(Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
1798         {
1799             if (settings == null)
1800             {
1801                 settings = new XmlReaderSettings();
1802             }
1803             return settings.CreateReader(input, null, (string)string.Empty, inputContext);
1804         }
1805 
1806         // Creates an XmlReader according for parsing XML from the given TextReader.
Create(TextReader input)1807         public static XmlReader Create(TextReader input)
1808         {
1809             return Create(input, (XmlReaderSettings)null, (string)string.Empty);
1810         }
1811 
1812         // Creates an XmlReader according to the settings for parsing XML from the given TextReader.
Create(TextReader input, XmlReaderSettings settings)1813         public static XmlReader Create(TextReader input, XmlReaderSettings settings)
1814         {
1815             return Create(input, settings, string.Empty);
1816         }
1817 
1818         // Creates an XmlReader according to the settings and baseUri for parsing XML from the given TextReader.
Create(TextReader input, XmlReaderSettings settings, String baseUri)1819         public static XmlReader Create(TextReader input, XmlReaderSettings settings, String baseUri)
1820         {
1821             if (settings == null)
1822             {
1823                 settings = new XmlReaderSettings();
1824             }
1825             return settings.CreateReader(input, baseUri, null);
1826         }
1827 
1828         // Creates an XmlReader according to the settings and parser context for parsing XML from the given TextReader.
Create(TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)1829         public static XmlReader Create(TextReader input, XmlReaderSettings settings, XmlParserContext inputContext)
1830         {
1831             if (settings == null)
1832             {
1833                 settings = new XmlReaderSettings();
1834             }
1835             return settings.CreateReader(input, string.Empty, inputContext);
1836         }
1837 
1838         // Creates an XmlReader according to the settings wrapped over the given reader.
Create(XmlReader reader, XmlReaderSettings settings)1839         public static XmlReader Create(XmlReader reader, XmlReaderSettings settings)
1840         {
1841             if (settings == null)
1842             {
1843                 settings = new XmlReaderSettings();
1844             }
1845             return settings.CreateReader(reader);
1846         }
1847 
1848         // !!!!!!
1849         // NOTE: This method is called via reflection from System.Data.dll and from Analysis Services in Yukon.
1850         // Do not change its signature without notifying the appropriate teams!
1851         // !!!!!!
1852 #if UAPAOT
CreateSqlReader(Stream input, XmlReaderSettings settings, XmlParserContext inputContext)1853         public static XmlReader CreateSqlReader(Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
1854 #else
1855         internal static XmlReader CreateSqlReader(Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
1856 #endif
1857         {
1858             if (input == null)
1859             {
1860                 throw new ArgumentNullException(nameof(input));
1861             }
1862             if (settings == null)
1863             {
1864                 settings = new XmlReaderSettings();
1865             }
1866 
1867             XmlReader reader;
1868 
1869             // allocate byte buffer
1870             byte[] bytes = new byte[CalcBufferSize(input)];
1871 
1872             int byteCount = 0;
1873             int read;
1874             do
1875             {
1876                 read = input.Read(bytes, byteCount, bytes.Length - byteCount);
1877                 byteCount += read;
1878             } while (read > 0 && byteCount< 2);
1879 
1880             // create text or binary XML reader depenting on the stream first 2 bytes
1881             if (byteCount >= 2 && (bytes[0] == 0xdf && bytes[1] == 0xff))
1882             {
1883                 if (inputContext != null)
1884                     throw new ArgumentException(SR.XmlBinary_NoParserContext, nameof(inputContext));
1885                 reader = new XmlSqlBinaryReader(input, bytes, byteCount, string.Empty, settings.CloseInput, settings);
1886             }
1887             else
1888             {
1889                 reader = new XmlTextReaderImpl(input, bytes, byteCount, settings, null, string.Empty, inputContext, settings.CloseInput);
1890             }
1891 
1892             // wrap with validating reader
1893             if (settings.ValidationType != ValidationType.None)
1894             {
1895                 reader = settings.AddValidation(reader);
1896             }
1897 
1898             if (settings.Async)
1899             {
1900                 reader = XmlAsyncCheckReader.CreateAsyncCheckWrapper(reader);
1901             }
1902 
1903             return reader;
1904         }
1905 
CalcBufferSize(Stream input)1906         internal static int CalcBufferSize(Stream input)
1907         {
1908             // determine the size of byte buffer
1909             int bufferSize = DefaultBufferSize;
1910             if (input.CanSeek)
1911             {
1912                 long len = input.Length;
1913                 if (len < bufferSize)
1914                 {
1915                     bufferSize = checked((int)len);
1916                 }
1917                 else if (len > MaxStreamLengthForDefaultBufferSize)
1918                 {
1919                     bufferSize = BiggerBufferSize;
1920                 }
1921             }
1922 
1923             // return the byte buffer size
1924             return bufferSize;
1925         }
1926 
1927         private object debuggerDisplayProxy { get { return new XmlReaderDebuggerDisplayProxy(this); } }
1928 
1929         [DebuggerDisplay("{ToString()}")]
1930         private struct XmlReaderDebuggerDisplayProxy
1931         {
1932             private XmlReader _reader;
1933 
XmlReaderDebuggerDisplayProxySystem.Xml.XmlReader.XmlReaderDebuggerDisplayProxy1934             internal XmlReaderDebuggerDisplayProxy(XmlReader reader)
1935             {
1936                 _reader = reader;
1937             }
1938 
ToStringSystem.Xml.XmlReader.XmlReaderDebuggerDisplayProxy1939             public override string ToString()
1940             {
1941                 XmlNodeType nt = _reader.NodeType;
1942                 string result = nt.ToString();
1943                 switch (nt)
1944                 {
1945                     case XmlNodeType.Element:
1946                     case XmlNodeType.EndElement:
1947                     case XmlNodeType.EntityReference:
1948                     case XmlNodeType.EndEntity:
1949                         result += ", Name=\"" + _reader.Name + '"';
1950                         break;
1951                     case XmlNodeType.Attribute:
1952                     case XmlNodeType.ProcessingInstruction:
1953                         result += ", Name=\"" + _reader.Name + "\", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_reader.Value) + '"';
1954                         break;
1955                     case XmlNodeType.Text:
1956                     case XmlNodeType.Whitespace:
1957                     case XmlNodeType.SignificantWhitespace:
1958                     case XmlNodeType.Comment:
1959                     case XmlNodeType.XmlDeclaration:
1960                     case XmlNodeType.CDATA:
1961                         result += ", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_reader.Value) + '"';
1962                         break;
1963                     case XmlNodeType.DocumentType:
1964                         result += ", Name=\"" + _reader.Name + "'";
1965                         result += ", SYSTEM=\"" + _reader.GetAttribute("SYSTEM") + '"';
1966                         result += ", PUBLIC=\"" + _reader.GetAttribute("PUBLIC") + '"';
1967                         result += ", Value=\"" + XmlConvert.EscapeValueForDebuggerDisplay(_reader.Value) + '"';
1968                         break;
1969                 }
1970                 return result;
1971             }
1972         }
1973     }
1974 }
1975 
1976