EncodingProvider.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. namespace System.Text
  5. {
  6. public abstract class EncodingProvider
  7. {
  8. public EncodingProvider() { }
  9. public abstract Encoding? GetEncoding(string name);
  10. public abstract Encoding? GetEncoding(int codepage);
  11. // GetEncoding should return either valid encoding or null. shouldn't throw any exception except on null name
  12. public virtual Encoding? GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
  13. {
  14. Encoding? enc = GetEncoding(name);
  15. if (enc != null)
  16. {
  17. enc = (Encoding)enc.Clone();
  18. enc.EncoderFallback = encoderFallback;
  19. enc.DecoderFallback = decoderFallback;
  20. }
  21. return enc;
  22. }
  23. public virtual Encoding? GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
  24. {
  25. Encoding? enc = GetEncoding(codepage);
  26. if (enc != null)
  27. {
  28. enc = (Encoding)enc.Clone();
  29. enc.EncoderFallback = encoderFallback;
  30. enc.DecoderFallback = decoderFallback;
  31. }
  32. return enc;
  33. }
  34. internal static void AddProvider(EncodingProvider provider)
  35. {
  36. if (provider == null)
  37. throw new ArgumentNullException(nameof(provider));
  38. lock (s_InternalSyncObject)
  39. {
  40. if (s_providers == null)
  41. {
  42. s_providers = new EncodingProvider[1] { provider };
  43. return;
  44. }
  45. if (Array.IndexOf(s_providers, provider) >= 0)
  46. {
  47. return;
  48. }
  49. EncodingProvider[] providers = new EncodingProvider[s_providers.Length + 1];
  50. Array.Copy(s_providers, providers, s_providers.Length);
  51. providers[^1] = provider;
  52. s_providers = providers;
  53. }
  54. }
  55. internal static Encoding? GetEncodingFromProvider(int codepage)
  56. {
  57. if (s_providers == null)
  58. return null;
  59. EncodingProvider[] providers = s_providers;
  60. foreach (EncodingProvider provider in providers)
  61. {
  62. Encoding? enc = provider.GetEncoding(codepage);
  63. if (enc != null)
  64. return enc;
  65. }
  66. return null;
  67. }
  68. internal static Encoding? GetEncodingFromProvider(string encodingName)
  69. {
  70. if (s_providers == null)
  71. return null;
  72. EncodingProvider[] providers = s_providers;
  73. foreach (EncodingProvider provider in providers)
  74. {
  75. Encoding? enc = provider.GetEncoding(encodingName);
  76. if (enc != null)
  77. return enc;
  78. }
  79. return null;
  80. }
  81. internal static Encoding? GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
  82. {
  83. if (s_providers == null)
  84. return null;
  85. EncodingProvider[] providers = s_providers;
  86. foreach (EncodingProvider provider in providers)
  87. {
  88. Encoding? encoding = provider.GetEncoding(codepage, enc, dec);
  89. if (encoding != null)
  90. return encoding;
  91. }
  92. return null;
  93. }
  94. internal static Encoding? GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
  95. {
  96. if (s_providers == null)
  97. return null;
  98. EncodingProvider[] providers = s_providers;
  99. foreach (EncodingProvider provider in providers)
  100. {
  101. Encoding? encoding = provider.GetEncoding(encodingName, enc, dec);
  102. if (encoding != null)
  103. return encoding;
  104. }
  105. return null;
  106. }
  107. private static readonly object s_InternalSyncObject = new object();
  108. private static volatile EncodingProvider[]? s_providers;
  109. }
  110. }