summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Text/EncodingProvider.cs
blob: b1dea2cd3cf92f0595773f78a21972f4a2b6f65e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace System.Text
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    [System.Runtime.InteropServices.ComVisible(true)]
    public abstract class EncodingProvider
    {
        public EncodingProvider() { }
        public abstract Encoding GetEncoding(string name);
        public abstract Encoding GetEncoding(int codepage);

        // GetEncoding should return either valid encoding or null. shouldn't throw any exception except on null name
        public virtual Encoding GetEncoding(string name, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
        {
            Encoding enc = GetEncoding(name);
            if (enc != null)
            {
                enc = (Encoding)GetEncoding(name).Clone();
                enc.EncoderFallback = encoderFallback;
                enc.DecoderFallback = decoderFallback;
            }

            return enc;
        }

        public virtual Encoding GetEncoding(int codepage, EncoderFallback encoderFallback, DecoderFallback decoderFallback)
        {
            Encoding enc = GetEncoding(codepage);
            if (enc != null)
            {
                enc = (Encoding)GetEncoding(codepage).Clone();
                enc.EncoderFallback = encoderFallback;
                enc.DecoderFallback = decoderFallback;
            }

            return enc;
        }

        internal static void AddProvider(EncodingProvider provider)
        {
            if (provider == null)
                throw new ArgumentNullException("provider");

            lock (s_InternalSyncObject)
            {
                if (s_providers == null)
                {
                    s_providers = new EncodingProvider[1] { provider };
                    return;
                }

                if (Array.IndexOf(s_providers, provider) >= 0)
                {
                    return;
                }

                var providers = new EncodingProvider[s_providers.Length + 1];
                Array.Copy(s_providers, providers, s_providers.Length);
                providers[providers.Length - 1] = provider;
                s_providers = providers;
            }
        }

        internal static Encoding GetEncodingFromProvider(int codepage)
        {
            if (s_providers == null)
                return null;

            var providers = s_providers;
            foreach (EncodingProvider provider in providers)
            {
                Encoding enc = provider.GetEncoding(codepage);
                if (enc != null)
                    return enc;
            }

            return null;
        }

        internal static Encoding GetEncodingFromProvider(string encodingName)
        {
            if (s_providers == null)
                return null;

            var providers = s_providers;
            foreach (EncodingProvider provider in providers)
            {
                Encoding enc = provider.GetEncoding(encodingName);
                if (enc != null)
                    return enc;
            }

            return null;
        }

        internal static Encoding GetEncodingFromProvider(int codepage, EncoderFallback enc, DecoderFallback dec)
        {
            if (s_providers == null)
                return null;

            var providers = s_providers;
            foreach (EncodingProvider provider in providers)
            {
                Encoding encing = provider.GetEncoding(codepage, enc, dec);
                if (encing != null)
                    return encing;
            }

            return null;
        }

        internal static Encoding GetEncodingFromProvider(string encodingName, EncoderFallback enc, DecoderFallback dec)
        {
            if (s_providers == null)
                return null;

            var providers = s_providers;
            foreach (EncodingProvider provider in providers)
            {
                Encoding encoding = provider.GetEncoding(encodingName, enc, dec);
                if (encoding != null)
                    return encoding;
            }

            return null;
        }

        private static Object s_InternalSyncObject = new Object();
        private static volatile EncodingProvider[] s_providers;
    }
}