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