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