DecoderExceptionFallback.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. using System.Diagnostics.CodeAnalysis;
  5. using System.Globalization;
  6. using System.Runtime.Serialization;
  7. namespace System.Text
  8. {
  9. public sealed class DecoderExceptionFallback : DecoderFallback
  10. {
  11. public override DecoderFallbackBuffer CreateFallbackBuffer() =>
  12. new DecoderExceptionFallbackBuffer();
  13. // Maximum number of characters that this instance of this fallback could return
  14. public override int MaxCharCount => 0;
  15. public override bool Equals(object? value) =>
  16. value is DecoderExceptionFallback;
  17. public override int GetHashCode() => 879;
  18. }
  19. public sealed class DecoderExceptionFallbackBuffer : DecoderFallbackBuffer
  20. {
  21. public override bool Fallback(byte[] bytesUnknown, int index)
  22. {
  23. Throw(bytesUnknown, index);
  24. return true;
  25. }
  26. public override char GetNextChar() => (char)0;
  27. // Exception fallback doesn't have anywhere to back up to.
  28. public override bool MovePrevious() => false;
  29. // Exceptions are always empty
  30. public override int Remaining => 0;
  31. [DoesNotReturn]
  32. private void Throw(byte[] bytesUnknown, int index)
  33. {
  34. bytesUnknown ??= Array.Empty<byte>();
  35. // Create a string representation of our bytes.
  36. StringBuilder strBytes = new StringBuilder(bytesUnknown.Length * 4);
  37. const int MaxLength = 20;
  38. for (int i = 0; i < bytesUnknown.Length && i < MaxLength; i++)
  39. {
  40. strBytes.Append('[');
  41. strBytes.Append(bytesUnknown[i].ToString("X2", CultureInfo.InvariantCulture));
  42. strBytes.Append(']');
  43. }
  44. // In case the string's really long
  45. if (bytesUnknown.Length > MaxLength)
  46. {
  47. strBytes.Append(" ...");
  48. }
  49. // Known index
  50. throw new DecoderFallbackException(
  51. SR.Format(SR.Argument_InvalidCodePageBytesIndex,
  52. strBytes, index), bytesUnknown, index);
  53. }
  54. }
  55. // Exception for decoding unknown byte sequences.
  56. [Serializable]
  57. [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
  58. public sealed class DecoderFallbackException : ArgumentException
  59. {
  60. private readonly byte[]? _bytesUnknown = null;
  61. private readonly int _index = 0;
  62. public DecoderFallbackException()
  63. : base(SR.Arg_ArgumentException)
  64. {
  65. HResult = HResults.COR_E_ARGUMENT;
  66. }
  67. public DecoderFallbackException(string? message)
  68. : base(message)
  69. {
  70. HResult = HResults.COR_E_ARGUMENT;
  71. }
  72. public DecoderFallbackException(string? message, Exception? innerException)
  73. : base(message, innerException)
  74. {
  75. HResult = HResults.COR_E_ARGUMENT;
  76. }
  77. public DecoderFallbackException(string? message, byte[]? bytesUnknown, int index)
  78. : base(message)
  79. {
  80. _bytesUnknown = bytesUnknown;
  81. _index = index;
  82. }
  83. private DecoderFallbackException(SerializationInfo serializationInfo, StreamingContext streamingContext)
  84. : base(serializationInfo, streamingContext)
  85. {
  86. }
  87. public byte[]? BytesUnknown => _bytesUnknown;
  88. public int Index => _index;
  89. }
  90. }