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.Xml;
6 using System.Globalization;
7 using System.Collections.Generic;
8 using System.Xml.Serialization;
9 
10 
11 namespace System.Runtime.Serialization
12 {
13 #if USE_REFEMIT || uapaot
14     public class XmlReaderDelegator
15 #else
16     internal class XmlReaderDelegator
17 #endif
18     {
19         protected XmlReader reader;
20         protected XmlDictionaryReader dictionaryReader;
21         protected bool isEndOfEmptyElement = false;
22 
XmlReaderDelegator(XmlReader reader)23         public XmlReaderDelegator(XmlReader reader)
24         {
25             XmlObjectSerializer.CheckNull(reader, nameof(reader));
26             this.reader = reader;
27             this.dictionaryReader = reader as XmlDictionaryReader;
28         }
29 
30         internal XmlReader UnderlyingReader
31         {
32             get { return reader; }
33         }
34 
35         internal ExtensionDataReader UnderlyingExtensionDataReader
36         {
37             get { return reader as ExtensionDataReader; }
38         }
39 
40         internal int AttributeCount
41         {
42             get { return isEndOfEmptyElement ? 0 : reader.AttributeCount; }
43         }
44 
GetAttribute(string name)45         internal string GetAttribute(string name)
46         {
47             return isEndOfEmptyElement ? null : reader.GetAttribute(name);
48         }
49 
GetAttribute(string name, string namespaceUri)50         internal string GetAttribute(string name, string namespaceUri)
51         {
52             return isEndOfEmptyElement ? null : reader.GetAttribute(name, namespaceUri);
53         }
54 
GetAttribute(int i)55         internal string GetAttribute(int i)
56         {
57             if (isEndOfEmptyElement)
58                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(i), SR.Format(SR.XmlElementAttributes)));
59             return reader.GetAttribute(i);
60         }
61 
62         internal bool IsEmptyElement
63         {
64             get { return false; }
65         }
66 
IsNamespaceURI(string ns)67         internal bool IsNamespaceURI(string ns)
68         {
69             if (dictionaryReader == null)
70                 return ns == reader.NamespaceURI;
71             else
72                 return dictionaryReader.IsNamespaceUri(ns);
73         }
74 
IsLocalName(string localName)75         internal bool IsLocalName(string localName)
76         {
77             if (dictionaryReader == null)
78                 return localName == reader.LocalName;
79             else
80                 return dictionaryReader.IsLocalName(localName);
81         }
82 
IsNamespaceUri(XmlDictionaryString ns)83         internal bool IsNamespaceUri(XmlDictionaryString ns)
84         {
85             if (dictionaryReader == null)
86                 return ns.Value == reader.NamespaceURI;
87             else
88                 return dictionaryReader.IsNamespaceUri(ns);
89         }
90 
IsLocalName(XmlDictionaryString localName)91         internal bool IsLocalName(XmlDictionaryString localName)
92         {
93             if (dictionaryReader == null)
94                 return localName.Value == reader.LocalName;
95             else
96                 return dictionaryReader.IsLocalName(localName);
97         }
98 
IndexOfLocalName(XmlDictionaryString[] localNames, XmlDictionaryString ns)99         internal int IndexOfLocalName(XmlDictionaryString[] localNames, XmlDictionaryString ns)
100         {
101             if (dictionaryReader != null)
102                 return dictionaryReader.IndexOfLocalName(localNames, ns);
103 
104             if (reader.NamespaceURI == ns.Value)
105             {
106                 string localName = this.LocalName;
107                 for (int i = 0; i < localNames.Length; i++)
108                 {
109                     if (localName == localNames[i].Value)
110                     {
111                         return i;
112                     }
113                 }
114             }
115 
116             return -1;
117         }
118 
119 #if USE_REFEMIT
IsStartElement()120         public bool IsStartElement()
121 #else
122         internal bool IsStartElement()
123 #endif
124         {
125             return !isEndOfEmptyElement && reader.IsStartElement();
126         }
127 
IsStartElement(string localname, string ns)128         internal bool IsStartElement(string localname, string ns)
129         {
130             return !isEndOfEmptyElement && reader.IsStartElement(localname, ns);
131         }
132 
133 #if USE_REFEMIT
IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)134         public bool IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)
135 #else
136         internal bool IsStartElement(XmlDictionaryString localname, XmlDictionaryString ns)
137 #endif
138         {
139             if (dictionaryReader == null)
140                 return !isEndOfEmptyElement && reader.IsStartElement(localname.Value, ns.Value);
141             else
142                 return !isEndOfEmptyElement && dictionaryReader.IsStartElement(localname, ns);
143         }
144 
MoveToAttribute(string name)145         internal bool MoveToAttribute(string name)
146         {
147             return isEndOfEmptyElement ? false : reader.MoveToAttribute(name);
148         }
149 
MoveToAttribute(string name, string ns)150         internal bool MoveToAttribute(string name, string ns)
151         {
152             return isEndOfEmptyElement ? false : reader.MoveToAttribute(name, ns);
153         }
154 
MoveToAttribute(int i)155         internal void MoveToAttribute(int i)
156         {
157             if (isEndOfEmptyElement)
158                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(i), SR.Format(SR.XmlElementAttributes)));
159             reader.MoveToAttribute(i);
160         }
161 
MoveToElement()162         internal bool MoveToElement()
163         {
164             return isEndOfEmptyElement ? false : reader.MoveToElement();
165         }
166 
MoveToFirstAttribute()167         internal bool MoveToFirstAttribute()
168         {
169             return isEndOfEmptyElement ? false : reader.MoveToFirstAttribute();
170         }
171 
MoveToNextAttribute()172         internal bool MoveToNextAttribute()
173         {
174             return isEndOfEmptyElement ? false : reader.MoveToNextAttribute();
175         }
176 
177 #if USE_REFEMIT
178         public XmlNodeType NodeType
179 #else
180         internal XmlNodeType NodeType
181 #endif
182         {
183             get { return isEndOfEmptyElement ? XmlNodeType.EndElement : reader.NodeType; }
184         }
185 
Read()186         internal bool Read()
187         {
188             //reader.MoveToFirstAttribute();
189             //if (NodeType == XmlNodeType.Attribute)
190             reader.MoveToElement();
191             if (!reader.IsEmptyElement)
192                 return reader.Read();
193             if (isEndOfEmptyElement)
194             {
195                 isEndOfEmptyElement = false;
196                 return reader.Read();
197             }
198             isEndOfEmptyElement = true;
199             return true;
200         }
201 
MoveToContent()202         internal XmlNodeType MoveToContent()
203         {
204             if (isEndOfEmptyElement)
205                 return XmlNodeType.EndElement;
206 
207             return reader.MoveToContent();
208         }
209 
ReadAttributeValue()210         internal bool ReadAttributeValue()
211         {
212             return isEndOfEmptyElement ? false : reader.ReadAttributeValue();
213         }
214 
215 #if USE_REFEMIT
ReadEndElement()216         public void ReadEndElement()
217 #else
218         internal void ReadEndElement()
219 #endif
220         {
221             if (isEndOfEmptyElement)
222                 Read();
223             else
224                 reader.ReadEndElement();
225         }
226 
CreateInvalidPrimitiveTypeException(Type type)227         private Exception CreateInvalidPrimitiveTypeException(Type type)
228         {
229             return new InvalidDataContractException(SR.Format(
230                 type.IsInterface ? SR.InterfaceTypeCannotBeCreated : SR.InvalidPrimitiveType,
231                 DataContract.GetClrTypeFullName(type)));
232         }
233 
ReadElementContentAsAnyType(Type valueType)234         public object ReadElementContentAsAnyType(Type valueType)
235         {
236             Read();
237             object o = ReadContentAsAnyType(valueType);
238             ReadEndElement();
239             return o;
240         }
241 
ReadContentAsAnyType(Type valueType)242         internal object ReadContentAsAnyType(Type valueType)
243         {
244             switch (Type.GetTypeCode(valueType))
245             {
246                 case TypeCode.Boolean:
247                     return ReadContentAsBoolean();
248                 case TypeCode.Char:
249                     return ReadContentAsChar();
250                 case TypeCode.Byte:
251                     return ReadContentAsUnsignedByte();
252                 case TypeCode.Int16:
253                     return ReadContentAsShort();
254                 case TypeCode.Int32:
255                     return ReadContentAsInt();
256                 case TypeCode.Int64:
257                     return ReadContentAsLong();
258                 case TypeCode.Single:
259                     return ReadContentAsSingle();
260                 case TypeCode.Double:
261                     return ReadContentAsDouble();
262                 case TypeCode.Decimal:
263                     return ReadContentAsDecimal();
264                 case TypeCode.DateTime:
265                     return ReadContentAsDateTime();
266                 case TypeCode.String:
267                     return ReadContentAsString();
268 
269                 case TypeCode.SByte:
270                     return ReadContentAsSignedByte();
271                 case TypeCode.UInt16:
272                     return ReadContentAsUnsignedShort();
273                 case TypeCode.UInt32:
274                     return ReadContentAsUnsignedInt();
275                 case TypeCode.UInt64:
276                     return ReadContentAsUnsignedLong();
277                 case TypeCode.Empty:
278                 case TypeCode.DBNull:
279                 case TypeCode.Object:
280                 default:
281                     if (valueType == Globals.TypeOfByteArray)
282                         return ReadContentAsBase64();
283                     else if (valueType == Globals.TypeOfObject)
284                         return new object();
285                     else if (valueType == Globals.TypeOfTimeSpan)
286                         return ReadContentAsTimeSpan();
287                     else if (valueType == Globals.TypeOfGuid)
288                         return ReadContentAsGuid();
289                     else if (valueType == Globals.TypeOfUri)
290                         return ReadContentAsUri();
291                     else if (valueType == Globals.TypeOfXmlQualifiedName)
292                         return ReadContentAsQName();
293                     break;
294             }
295             throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidPrimitiveTypeException(valueType));
296         }
297 
ReadExtensionData(Type valueType)298         internal IDataNode ReadExtensionData(Type valueType)
299         {
300             switch (Type.GetTypeCode(valueType))
301             {
302                 case TypeCode.Boolean:
303                     return new DataNode<bool>(ReadContentAsBoolean());
304                 case TypeCode.Char:
305                     return new DataNode<char>(ReadContentAsChar());
306                 case TypeCode.Byte:
307                     return new DataNode<byte>(ReadContentAsUnsignedByte());
308                 case TypeCode.Int16:
309                     return new DataNode<short>(ReadContentAsShort());
310                 case TypeCode.Int32:
311                     return new DataNode<int>(ReadContentAsInt());
312                 case TypeCode.Int64:
313                     return new DataNode<long>(ReadContentAsLong());
314                 case TypeCode.Single:
315                     return new DataNode<float>(ReadContentAsSingle());
316                 case TypeCode.Double:
317                     return new DataNode<double>(ReadContentAsDouble());
318                 case TypeCode.Decimal:
319                     return new DataNode<decimal>(ReadContentAsDecimal());
320                 case TypeCode.DateTime:
321                     return new DataNode<DateTime>(ReadContentAsDateTime());
322                 case TypeCode.String:
323                     return new DataNode<string>(ReadContentAsString());
324                 case TypeCode.SByte:
325                     return new DataNode<sbyte>(ReadContentAsSignedByte());
326                 case TypeCode.UInt16:
327                     return new DataNode<ushort>(ReadContentAsUnsignedShort());
328                 case TypeCode.UInt32:
329                     return new DataNode<uint>(ReadContentAsUnsignedInt());
330                 case TypeCode.UInt64:
331                     return new DataNode<ulong>(ReadContentAsUnsignedLong());
332                 case TypeCode.Empty:
333                 case TypeCode.DBNull:
334                 case TypeCode.Object:
335                 default:
336                     if (valueType == Globals.TypeOfByteArray)
337                         return new DataNode<byte[]>(ReadContentAsBase64());
338                     else if (valueType == Globals.TypeOfObject)
339                         return new DataNode<object>(new object());
340                     else if (valueType == Globals.TypeOfTimeSpan)
341                         return new DataNode<TimeSpan>(ReadContentAsTimeSpan());
342                     else if (valueType == Globals.TypeOfGuid)
343                         return new DataNode<Guid>(ReadContentAsGuid());
344                     else if (valueType == Globals.TypeOfUri)
345                         return new DataNode<Uri>(ReadContentAsUri());
346                     else if (valueType == Globals.TypeOfXmlQualifiedName)
347                         return new DataNode<XmlQualifiedName>(ReadContentAsQName());
348                     break;
349             }
350             throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidPrimitiveTypeException(valueType));
351         }
352 
ThrowConversionException(string value, string type)353         private void ThrowConversionException(string value, string type)
354         {
355             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(XmlObjectSerializer.TryAddLineInfo(this, SR.Format(SR.XmlInvalidConversion, value, type))));
356         }
357 
ThrowNotAtElement()358         private void ThrowNotAtElement()
359         {
360             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.Format(SR.XmlStartElementExpected, "EndElement")));
361         }
362 
363 #if USE_REFEMIT
ReadElementContentAsChar()364         public virtual char ReadElementContentAsChar()
365 #else
366         internal virtual char ReadElementContentAsChar()
367 #endif
368         {
369             return ToChar(ReadElementContentAsInt());
370         }
371 
ReadContentAsChar()372         internal virtual char ReadContentAsChar()
373         {
374             return ToChar(ReadContentAsInt());
375         }
376 
ToChar(int value)377         private char ToChar(int value)
378         {
379             if (value < char.MinValue || value > char.MaxValue)
380             {
381                 ThrowConversionException(value.ToString(NumberFormatInfo.CurrentInfo), "Char");
382             }
383             return (char)value;
384         }
385 
386 #if USE_REFEMIT
ReadElementContentAsString()387         public string ReadElementContentAsString()
388 #else
389         internal string ReadElementContentAsString()
390 #endif
391         {
392             if (isEndOfEmptyElement)
393                 ThrowNotAtElement();
394 
395             return reader.ReadElementContentAsString();
396         }
397 
ReadContentAsString()398         internal string ReadContentAsString()
399         {
400             return isEndOfEmptyElement ? String.Empty : reader.ReadContentAsString();
401         }
402 
403 #if USE_REFEMIT
ReadElementContentAsBoolean()404         public bool ReadElementContentAsBoolean()
405 #else
406         internal bool ReadElementContentAsBoolean()
407 #endif
408         {
409             if (isEndOfEmptyElement)
410                 ThrowNotAtElement();
411 
412             return reader.ReadElementContentAsBoolean();
413         }
414 
ReadContentAsBoolean()415         internal bool ReadContentAsBoolean()
416         {
417             if (isEndOfEmptyElement)
418                 ThrowConversionException(string.Empty, "Boolean");
419 
420             return reader.ReadContentAsBoolean();
421         }
422 
423 #if USE_REFEMIT
ReadElementContentAsFloat()424         public float ReadElementContentAsFloat()
425 #else
426         internal float ReadElementContentAsFloat()
427 #endif
428         {
429             if (isEndOfEmptyElement)
430                 ThrowNotAtElement();
431 
432             return reader.ReadElementContentAsFloat();
433         }
434 
ReadContentAsSingle()435         internal float ReadContentAsSingle()
436         {
437             if (isEndOfEmptyElement)
438                 ThrowConversionException(string.Empty, "Float");
439 
440             return reader.ReadContentAsFloat();
441         }
442 
443 #if USE_REFEMIT
ReadElementContentAsDouble()444         public double ReadElementContentAsDouble()
445 #else
446         internal double ReadElementContentAsDouble()
447 #endif
448         {
449             if (isEndOfEmptyElement)
450                 ThrowNotAtElement();
451 
452             return reader.ReadElementContentAsDouble();
453         }
454 
ReadContentAsDouble()455         internal double ReadContentAsDouble()
456         {
457             if (isEndOfEmptyElement)
458                 ThrowConversionException(string.Empty, "Double");
459 
460             return reader.ReadContentAsDouble();
461         }
462 
463 #if USE_REFEMIT
ReadElementContentAsDecimal()464         public decimal ReadElementContentAsDecimal()
465 #else
466         internal decimal ReadElementContentAsDecimal()
467 #endif
468         {
469             if (isEndOfEmptyElement)
470                 ThrowNotAtElement();
471 
472             return reader.ReadElementContentAsDecimal();
473         }
474 
ReadContentAsDecimal()475         internal decimal ReadContentAsDecimal()
476         {
477             if (isEndOfEmptyElement)
478                 ThrowConversionException(string.Empty, "Decimal");
479 
480             return reader.ReadContentAsDecimal();
481         }
482 
483 #if USE_REFEMIT
ReadElementContentAsBase64()484         public virtual byte[] ReadElementContentAsBase64()
485 #else
486         internal virtual byte[] ReadElementContentAsBase64()
487 #endif
488         {
489             if (isEndOfEmptyElement)
490                 ThrowNotAtElement();
491 
492             if (dictionaryReader == null)
493             {
494                 return ReadContentAsBase64(reader.ReadElementContentAsString());
495             }
496             else
497             {
498                 return dictionaryReader.ReadElementContentAsBase64();
499             }
500         }
501 
ReadContentAsBase64()502         public virtual byte[] ReadContentAsBase64()
503         {
504             if (isEndOfEmptyElement)
505                 return new byte[0];
506 
507             if (dictionaryReader == null)
508             {
509                 return ReadContentAsBase64(reader.ReadContentAsString());
510             }
511             else
512             {
513                 return dictionaryReader.ReadContentAsBase64();
514             }
515         }
516 
ReadContentAsBase64(string str)517         internal byte[] ReadContentAsBase64(string str)
518         {
519             if (str == null)
520                 return null;
521             str = str.Trim();
522             if (str.Length == 0)
523                 return Array.Empty<byte>();
524 
525             try
526             {
527                 return Convert.FromBase64String(str);
528             }
529             catch (ArgumentException exception)
530             {
531                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "byte[]", exception));
532             }
533             catch (FormatException exception)
534             {
535                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "byte[]", exception));
536             }
537         }
538 
539 #if USE_REFEMIT
ReadElementContentAsDateTime()540         public virtual DateTime ReadElementContentAsDateTime()
541 #else
542         internal virtual DateTime ReadElementContentAsDateTime()
543 #endif
544         {
545             if (isEndOfEmptyElement)
546                 ThrowNotAtElement();
547 
548             return XmlConvert.ToDateTime(reader.ReadElementContentAsString(), XmlDateTimeSerializationMode.RoundtripKind);
549         }
550 
ReadContentAsDateTime()551         internal virtual DateTime ReadContentAsDateTime()
552         {
553             if (isEndOfEmptyElement)
554                 ThrowConversionException(string.Empty, "DateTime");
555 
556             return reader.ReadContentAsDateTime();
557         }
558 
559 #if USE_REFEMIT
ReadElementContentAsInt()560         public int ReadElementContentAsInt()
561 #else
562         internal int ReadElementContentAsInt()
563 #endif
564         {
565             if (isEndOfEmptyElement)
566                 ThrowNotAtElement();
567 
568             return reader.ReadElementContentAsInt();
569         }
570 
ReadContentAsInt()571         internal int ReadContentAsInt()
572         {
573             if (isEndOfEmptyElement)
574                 ThrowConversionException(string.Empty, "Int32");
575 
576             return reader.ReadContentAsInt();
577         }
578 
579 #if USE_REFEMIT
ReadElementContentAsLong()580         public long ReadElementContentAsLong()
581 #else
582         internal long ReadElementContentAsLong()
583 #endif
584         {
585             if (isEndOfEmptyElement)
586                 ThrowNotAtElement();
587 
588             return reader.ReadElementContentAsLong();
589         }
590 
ReadContentAsLong()591         internal long ReadContentAsLong()
592         {
593             if (isEndOfEmptyElement)
594                 ThrowConversionException(string.Empty, "Int64");
595 
596             return reader.ReadContentAsLong();
597         }
598 
599 #if USE_REFEMIT
ReadElementContentAsShort()600         public short ReadElementContentAsShort()
601 #else
602         internal short ReadElementContentAsShort()
603 #endif
604         {
605             return ToShort(ReadElementContentAsInt());
606         }
607 
ReadContentAsShort()608         internal short ReadContentAsShort()
609         {
610             return ToShort(ReadContentAsInt());
611         }
612 
ToShort(int value)613         private short ToShort(int value)
614         {
615             if (value < short.MinValue || value > short.MaxValue)
616             {
617                 ThrowConversionException(value.ToString(NumberFormatInfo.CurrentInfo), "Int16");
618             }
619             return (short)value;
620         }
621 
622 #if USE_REFEMIT
ReadElementContentAsUnsignedByte()623         public byte ReadElementContentAsUnsignedByte()
624 #else
625         internal byte ReadElementContentAsUnsignedByte()
626 #endif
627         {
628             return ToByte(ReadElementContentAsInt());
629         }
630 
ReadContentAsUnsignedByte()631         internal byte ReadContentAsUnsignedByte()
632         {
633             return ToByte(ReadContentAsInt());
634         }
635 
ToByte(int value)636         private byte ToByte(int value)
637         {
638             if (value < byte.MinValue || value > byte.MaxValue)
639             {
640                 ThrowConversionException(value.ToString(NumberFormatInfo.CurrentInfo), "Byte");
641             }
642             return (byte)value;
643         }
644 
645 #if USE_REFEMIT
646         [CLSCompliant(false)]
ReadElementContentAsSignedByte()647         public SByte ReadElementContentAsSignedByte()
648 #else
649         internal SByte ReadElementContentAsSignedByte()
650 #endif
651         {
652             return ToSByte(ReadElementContentAsInt());
653         }
654 
ReadContentAsSignedByte()655         internal SByte ReadContentAsSignedByte()
656         {
657             return ToSByte(ReadContentAsInt());
658         }
659 
ToSByte(int value)660         private SByte ToSByte(int value)
661         {
662             if (value < SByte.MinValue || value > SByte.MaxValue)
663             {
664                 ThrowConversionException(value.ToString(NumberFormatInfo.CurrentInfo), "SByte");
665             }
666             return (SByte)value;
667         }
668 
669 #if USE_REFEMIT
670         [CLSCompliant(false)]
ReadElementContentAsUnsignedInt()671         public UInt32 ReadElementContentAsUnsignedInt()
672 #else
673         internal UInt32 ReadElementContentAsUnsignedInt()
674 #endif
675         {
676             return ToUInt32(ReadElementContentAsLong());
677         }
678 
ReadContentAsUnsignedInt()679         internal UInt32 ReadContentAsUnsignedInt()
680         {
681             return ToUInt32(ReadContentAsLong());
682         }
683 
ToUInt32(long value)684         private UInt32 ToUInt32(long value)
685         {
686             if (value < UInt32.MinValue || value > UInt32.MaxValue)
687             {
688                 ThrowConversionException(value.ToString(NumberFormatInfo.CurrentInfo), "UInt32");
689             }
690             return (UInt32)value;
691         }
692 
693 #if USE_REFEMIT
694         [CLSCompliant(false)]
ReadElementContentAsUnsignedLong()695         public virtual UInt64 ReadElementContentAsUnsignedLong()
696 #else
697         internal virtual UInt64 ReadElementContentAsUnsignedLong()
698 #endif
699         {
700             if (isEndOfEmptyElement)
701                 ThrowNotAtElement();
702 
703             string str = reader.ReadElementContentAsString();
704 
705             if (str == null || str.Length == 0)
706                 ThrowConversionException(string.Empty, "UInt64");
707 
708             return XmlConverter.ToUInt64(str);
709         }
710 
ReadContentAsUnsignedLong()711         internal virtual UInt64 ReadContentAsUnsignedLong()
712         {
713             string str = reader.ReadContentAsString();
714 
715             if (str == null || str.Length == 0)
716                 ThrowConversionException(string.Empty, "UInt64");
717 
718             return XmlConverter.ToUInt64(str);
719         }
720 
721 #if USE_REFEMIT
722         [CLSCompliant(false)]
ReadElementContentAsUnsignedShort()723         public UInt16 ReadElementContentAsUnsignedShort()
724 #else
725         internal UInt16 ReadElementContentAsUnsignedShort()
726 #endif
727         {
728             return ToUInt16(ReadElementContentAsInt());
729         }
730 
ReadContentAsUnsignedShort()731         internal UInt16 ReadContentAsUnsignedShort()
732         {
733             return ToUInt16(ReadContentAsInt());
734         }
735 
ToUInt16(int value)736         private UInt16 ToUInt16(int value)
737         {
738             if (value < UInt16.MinValue || value > UInt16.MaxValue)
739             {
740                 ThrowConversionException(value.ToString(NumberFormatInfo.CurrentInfo), "UInt16");
741             }
742             return (UInt16)value;
743         }
744 
745 #if USE_REFEMIT
ReadElementContentAsTimeSpan()746         public TimeSpan ReadElementContentAsTimeSpan()
747 #else
748         internal TimeSpan ReadElementContentAsTimeSpan()
749 #endif
750         {
751             if (isEndOfEmptyElement)
752                 ThrowNotAtElement();
753 
754             string str = reader.ReadElementContentAsString();
755             return XmlConverter.ToTimeSpan(str);
756         }
757 
ReadContentAsTimeSpan()758         internal TimeSpan ReadContentAsTimeSpan()
759         {
760             string str = reader.ReadContentAsString();
761             return XmlConverter.ToTimeSpan(str);
762         }
763 
764 #if USE_REFEMIT
ReadElementContentAsGuid()765         public Guid ReadElementContentAsGuid()
766 #else
767         internal Guid ReadElementContentAsGuid()
768 #endif
769         {
770             if (isEndOfEmptyElement)
771                 ThrowNotAtElement();
772 
773             string str = reader.ReadElementContentAsString();
774             try
775             {
776                 return new Guid(str);
777             }
778             catch (ArgumentException exception)
779             {
780                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Guid", exception));
781             }
782             catch (FormatException exception)
783             {
784                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Guid", exception));
785             }
786             catch (OverflowException exception)
787             {
788                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Guid", exception));
789             }
790         }
791 
ReadContentAsGuid()792         internal Guid ReadContentAsGuid()
793         {
794             string str = reader.ReadContentAsString();
795             try
796             {
797                 return Guid.Parse(str);
798             }
799             catch (ArgumentException exception)
800             {
801                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Guid", exception));
802             }
803             catch (FormatException exception)
804             {
805                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Guid", exception));
806             }
807             catch (OverflowException exception)
808             {
809                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Guid", exception));
810             }
811         }
812 
813 #if USE_REFEMIT
ReadElementContentAsUri()814         public Uri ReadElementContentAsUri()
815 #else
816         internal Uri ReadElementContentAsUri()
817 #endif
818         {
819             if (isEndOfEmptyElement)
820                 ThrowNotAtElement();
821 
822             string str = ReadElementContentAsString();
823             try
824             {
825                 return new Uri(str, UriKind.RelativeOrAbsolute);
826             }
827             catch (ArgumentException exception)
828             {
829                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Uri", exception));
830             }
831             catch (FormatException exception)
832             {
833                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Uri", exception));
834             }
835         }
836 
ReadContentAsUri()837         internal Uri ReadContentAsUri()
838         {
839             string str = ReadContentAsString();
840             try
841             {
842                 return new Uri(str, UriKind.RelativeOrAbsolute);
843             }
844             catch (ArgumentException exception)
845             {
846                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Uri", exception));
847             }
848             catch (FormatException exception)
849             {
850                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(str, "Uri", exception));
851             }
852         }
853 
854 #if USE_REFEMIT
ReadElementContentAsQName()855         public XmlQualifiedName ReadElementContentAsQName()
856 #else
857         internal XmlQualifiedName ReadElementContentAsQName()
858 #endif
859         {
860             Read();
861             XmlQualifiedName obj = ReadContentAsQName();
862             ReadEndElement();
863             return obj;
864         }
865 
ReadContentAsQName()866         internal virtual XmlQualifiedName ReadContentAsQName()
867         {
868             return ParseQualifiedName(ReadContentAsString());
869         }
870 
ParseQualifiedName(string str)871         private XmlQualifiedName ParseQualifiedName(string str)
872         {
873             string name, ns, prefix;
874             if (str == null || str.Length == 0)
875                 name = ns = String.Empty;
876             else
877                 XmlObjectSerializerReadContext.ParseQualifiedName(str, this, out name, out ns, out prefix);
878             return new XmlQualifiedName(name, ns);
879         }
880 
CheckExpectedArrayLength(XmlObjectSerializerReadContext context, int arrayLength)881         private void CheckExpectedArrayLength(XmlObjectSerializerReadContext context, int arrayLength)
882         {
883             context.IncrementItemCount(arrayLength);
884         }
885 
GetArrayLengthQuota(XmlObjectSerializerReadContext context)886         protected int GetArrayLengthQuota(XmlObjectSerializerReadContext context)
887         {
888             return Math.Min(context.RemainingItemCount, int.MaxValue);
889         }
890 
CheckActualArrayLength(int expectedLength, int actualLength, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)891         private void CheckActualArrayLength(int expectedLength, int actualLength, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
892         {
893             if (expectedLength != actualLength)
894                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ArrayExceededSizeAttribute, expectedLength, itemName.Value, itemNamespace.Value)));
895         }
896 
897 #if USE_REFEMIT
TryReadBooleanArray(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out bool[] array)898         public bool TryReadBooleanArray(XmlObjectSerializerReadContext context,
899 #else
900         internal bool TryReadBooleanArray(XmlObjectSerializerReadContext context,
901 #endif
902             XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
903             int arrayLength, out bool[] array)
904         {
905             if (dictionaryReader == null)
906             {
907                 array = null;
908                 return false;
909             }
910 
911             if (arrayLength != -1)
912             {
913                 CheckExpectedArrayLength(context, arrayLength);
914                 array = new bool[arrayLength];
915                 int read = 0, offset = 0;
916                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
917                 {
918                     offset += read;
919                 }
920                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
921             }
922             else
923             {
924                 array = BooleanArrayHelperWithDictionaryString.Instance.ReadArray(
925                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
926                 context.IncrementItemCount(array.Length);
927             }
928             return true;
929         }
930 
931 #if USE_REFEMIT
TryReadDateTimeArray(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out DateTime[] array)932         public virtual bool TryReadDateTimeArray(XmlObjectSerializerReadContext context,
933 #else
934         internal virtual bool TryReadDateTimeArray(XmlObjectSerializerReadContext context,
935 #endif
936             XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
937             int arrayLength, out DateTime[] array)
938         {
939             if (dictionaryReader == null)
940             {
941                 array = null;
942                 return false;
943             }
944 
945             if (arrayLength != -1)
946             {
947                 CheckExpectedArrayLength(context, arrayLength);
948                 array = new DateTime[arrayLength];
949                 int read = 0, offset = 0;
950                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
951                 {
952                     offset += read;
953                 }
954                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
955             }
956             else
957             {
958                 array = DateTimeArrayHelperWithDictionaryString.Instance.ReadArray(
959                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
960                 context.IncrementItemCount(array.Length);
961             }
962             return true;
963         }
964 
965 #if USE_REFEMIT
TryReadDecimalArray(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out decimal[] array)966         public bool TryReadDecimalArray(XmlObjectSerializerReadContext context,
967 #else
968         internal bool TryReadDecimalArray(XmlObjectSerializerReadContext context,
969 #endif
970             XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
971             int arrayLength, out decimal[] array)
972         {
973             if (dictionaryReader == null)
974             {
975                 array = null;
976                 return false;
977             }
978 
979             if (arrayLength != -1)
980             {
981                 CheckExpectedArrayLength(context, arrayLength);
982                 array = new decimal[arrayLength];
983                 int read = 0, offset = 0;
984                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
985                 {
986                     offset += read;
987                 }
988                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
989             }
990             else
991             {
992                 array = DecimalArrayHelperWithDictionaryString.Instance.ReadArray(
993                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
994                 context.IncrementItemCount(array.Length);
995             }
996             return true;
997         }
998 
999 #if USE_REFEMIT
TryReadInt32Array(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out int[] array)1000         public bool TryReadInt32Array(XmlObjectSerializerReadContext context,
1001 #else
1002         internal bool TryReadInt32Array(XmlObjectSerializerReadContext context,
1003 #endif
1004             XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
1005             int arrayLength, out int[] array)
1006         {
1007             if (dictionaryReader == null)
1008             {
1009                 array = null;
1010                 return false;
1011             }
1012 
1013             if (arrayLength != -1)
1014             {
1015                 CheckExpectedArrayLength(context, arrayLength);
1016                 array = new int[arrayLength];
1017                 int read = 0, offset = 0;
1018                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
1019                 {
1020                     offset += read;
1021                 }
1022                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
1023             }
1024             else
1025             {
1026                 array = Int32ArrayHelperWithDictionaryString.Instance.ReadArray(
1027                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
1028                 context.IncrementItemCount(array.Length);
1029             }
1030             return true;
1031         }
1032 
1033 #if USE_REFEMIT
TryReadInt64Array(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out long[] array)1034         public bool TryReadInt64Array(XmlObjectSerializerReadContext context,
1035 #else
1036         internal bool TryReadInt64Array(XmlObjectSerializerReadContext context,
1037 #endif
1038             XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
1039             int arrayLength, out long[] array)
1040         {
1041             if (dictionaryReader == null)
1042             {
1043                 array = null;
1044                 return false;
1045             }
1046 
1047             if (arrayLength != -1)
1048             {
1049                 CheckExpectedArrayLength(context, arrayLength);
1050                 array = new long[arrayLength];
1051                 int read = 0, offset = 0;
1052                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
1053                 {
1054                     offset += read;
1055                 }
1056                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
1057             }
1058             else
1059             {
1060                 array = Int64ArrayHelperWithDictionaryString.Instance.ReadArray(
1061                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
1062                 context.IncrementItemCount(array.Length);
1063             }
1064             return true;
1065         }
1066 
1067 #if USE_REFEMIT
TryReadSingleArray(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out float[] array)1068         public bool TryReadSingleArray(XmlObjectSerializerReadContext context,
1069 #else
1070         internal bool TryReadSingleArray(XmlObjectSerializerReadContext context,
1071 #endif
1072         XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
1073             int arrayLength, out float[] array)
1074         {
1075             if (dictionaryReader == null)
1076             {
1077                 array = null;
1078                 return false;
1079             }
1080 
1081             if (arrayLength != -1)
1082             {
1083                 CheckExpectedArrayLength(context, arrayLength);
1084                 array = new float[arrayLength];
1085                 int read = 0, offset = 0;
1086                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
1087                 {
1088                     offset += read;
1089                 }
1090                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
1091             }
1092             else
1093             {
1094                 array = SingleArrayHelperWithDictionaryString.Instance.ReadArray(
1095                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
1096                 context.IncrementItemCount(array.Length);
1097             }
1098             return true;
1099         }
1100 
1101 #if USE_REFEMIT
TryReadDoubleArray(XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, int arrayLength, out double[] array)1102         public bool TryReadDoubleArray(XmlObjectSerializerReadContext context,
1103 #else
1104         internal bool TryReadDoubleArray(XmlObjectSerializerReadContext context,
1105 #endif
1106             XmlDictionaryString itemName, XmlDictionaryString itemNamespace,
1107             int arrayLength, out double[] array)
1108         {
1109             if (dictionaryReader == null)
1110             {
1111                 array = null;
1112                 return false;
1113             }
1114 
1115             if (arrayLength != -1)
1116             {
1117                 CheckExpectedArrayLength(context, arrayLength);
1118                 array = new double[arrayLength];
1119                 int read = 0, offset = 0;
1120                 while ((read = dictionaryReader.ReadArray(itemName, itemNamespace, array, offset, arrayLength - offset)) > 0)
1121                 {
1122                     offset += read;
1123                 }
1124                 CheckActualArrayLength(arrayLength, offset, itemName, itemNamespace);
1125             }
1126             else
1127             {
1128                 array = DoubleArrayHelperWithDictionaryString.Instance.ReadArray(
1129                     dictionaryReader, itemName, itemNamespace, GetArrayLengthQuota(context));
1130                 context.IncrementItemCount(array.Length);
1131             }
1132             return true;
1133         }
1134 
GetNamespacesInScope(XmlNamespaceScope scope)1135         internal IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope)
1136         {
1137             return (reader is IXmlNamespaceResolver) ? ((IXmlNamespaceResolver)reader).GetNamespacesInScope(scope) : null;
1138         }
1139 
1140         // IXmlLineInfo members
HasLineInfo()1141         internal bool HasLineInfo()
1142         {
1143             IXmlLineInfo iXmlLineInfo = reader as IXmlLineInfo;
1144             return (iXmlLineInfo == null) ? false : iXmlLineInfo.HasLineInfo();
1145         }
1146 
1147         internal int LineNumber
1148         {
1149             get
1150             {
1151                 IXmlLineInfo iXmlLineInfo = reader as IXmlLineInfo;
1152                 return (iXmlLineInfo == null) ? 0 : iXmlLineInfo.LineNumber;
1153             }
1154         }
1155 
1156         internal int LinePosition
1157         {
1158             get
1159             {
1160                 IXmlLineInfo iXmlLineInfo = reader as IXmlLineInfo;
1161                 return (iXmlLineInfo == null) ? 0 : iXmlLineInfo.LinePosition;
1162             }
1163         }
1164 
1165         // IXmlTextParser members
1166         internal bool Normalized
1167         {
1168             get
1169             {
1170                 XmlTextReader xmlTextReader = reader as XmlTextReader;
1171                 if (xmlTextReader == null)
1172                 {
1173                     IXmlTextParser xmlTextParser = reader as IXmlTextParser;
1174                     return (xmlTextParser == null) ? false : xmlTextParser.Normalized;
1175                 }
1176                 else
1177                     return xmlTextReader.Normalization;
1178             }
1179             set
1180             {
1181                 XmlTextReader xmlTextReader = reader as XmlTextReader;
1182                 if (xmlTextReader == null)
1183                 {
1184                     IXmlTextParser xmlTextParser = reader as IXmlTextParser;
1185                     if (xmlTextParser != null)
1186                         xmlTextParser.Normalized = value;
1187                 }
1188                 else
1189                     xmlTextReader.Normalization = value;
1190             }
1191         }
1192 
1193         internal WhitespaceHandling WhitespaceHandling
1194         {
1195             get
1196             {
1197                 XmlTextReader xmlTextReader = reader as XmlTextReader;
1198                 if (xmlTextReader == null)
1199                 {
1200                     IXmlTextParser xmlTextParser = reader as IXmlTextParser;
1201                     return (xmlTextParser == null) ? WhitespaceHandling.None : xmlTextParser.WhitespaceHandling;
1202                 }
1203                 else
1204                     return xmlTextReader.WhitespaceHandling;
1205             }
1206             set
1207             {
1208                 XmlTextReader xmlTextReader = reader as XmlTextReader;
1209                 if (xmlTextReader == null)
1210                 {
1211                     IXmlTextParser xmlTextParser = reader as IXmlTextParser;
1212                     if (xmlTextParser != null)
1213                         xmlTextParser.WhitespaceHandling = value;
1214                 }
1215                 else
1216                     xmlTextReader.WhitespaceHandling = value;
1217             }
1218         }
1219 
1220         // delegating properties and methods
1221         internal string Name { get { return reader.Name; } }
1222         internal string LocalName { get { return reader.LocalName; } }
1223         internal string NamespaceURI { get { return reader.NamespaceURI; } }
1224         internal string Value { get { return reader.Value; } }
1225         internal Type ValueType { get { return reader.ValueType; } }
1226         internal int Depth { get { return reader.Depth; } }
LookupNamespace(string prefix)1227         internal string LookupNamespace(string prefix) { return reader.LookupNamespace(prefix); }
1228         internal bool EOF { get { return reader.EOF; } }
1229 
Skip()1230         internal void Skip()
1231         {
1232             reader.Skip();
1233             isEndOfEmptyElement = false;
1234         }
1235     }
1236 }
1237 
1238