Created
November 25, 2015 17:04
-
-
Save stdray/6f06da01235b7223ca27 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public static class EncodingHelper | |
| { | |
| static readonly ConcurrentDictionary<Encoding, Encoding> CheckEncodingCache = | |
| new ConcurrentDictionary<Encoding, Encoding>(); | |
| static readonly ConcurrentDictionary<Encoding, Encoding> ReplaceEncodingCache = | |
| new ConcurrentDictionary<Encoding, Encoding>(); | |
| static readonly Encoding EncodingCP1251 = Encoding.GetEncoding(1251); | |
| public static string ToCP1251(this string str, string replaceStr = "") | |
| { | |
| return Encode(EncodingCP1251, str, replaceStr); | |
| } | |
| public static string Encode(Encoding encoding, string str, string replaceStr = "") | |
| { | |
| if (CanEncode(encoding, str)) | |
| return str; | |
| var replaceEncoding = GetReplaceEncoding(encoding, replaceStr); | |
| var src = Encoding.Unicode.GetBytes(str); | |
| var res = Encoding.Convert(Encoding.Unicode, replaceEncoding, src); | |
| return encoding.GetString(res); | |
| } | |
| public static bool CanEncode(Encoding encoding, string str) | |
| { | |
| if (string.IsNullOrEmpty(str)) | |
| return true; | |
| var enc = GetCheckEncoding(encoding); | |
| var arr = new char[1]; | |
| for (var i = 0; i < str.Length; i++) | |
| { | |
| arr[0] = str[i]; | |
| if (enc.GetByteCount(arr, 0, 1) < 1) | |
| return false; | |
| } | |
| return true; | |
| } | |
| static Encoding GetCheckEncoding(Encoding encoding) | |
| { | |
| return CheckEncodingCache.GetOrAdd(encoding, e => | |
| { | |
| var enc = (Encoding)e.Clone(); | |
| enc.EncoderFallback = new EncoderFallbackCheckExists(); | |
| return enc; | |
| }); | |
| } | |
| static Encoding GetReplaceEncoding(Encoding encoding, string replaceStr) | |
| { | |
| return ReplaceEncodingCache.GetOrAdd(encoding, e => | |
| { | |
| var enc = (Encoding)e.Clone(); | |
| enc.EncoderFallback = new EncoderReplacementFallback(replaceStr); | |
| enc.DecoderFallback = new DecoderReplacementFallback(replaceStr); | |
| return enc; | |
| }); | |
| } | |
| #region Classes | |
| class EncoderFallbackCheckExists : EncoderFallback | |
| { | |
| public override int MaxCharCount { get { return 1; } } | |
| public override EncoderFallbackBuffer CreateFallbackBuffer() | |
| { | |
| return new FallbackBufferCheckExists(); | |
| } | |
| } | |
| class FallbackBufferCheckExists : EncoderFallbackBuffer | |
| { | |
| public override int Remaining | |
| { | |
| get { return 0; } | |
| } | |
| public override bool Fallback(char charUnknown, int index) | |
| { | |
| return false; | |
| } | |
| public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index) | |
| { | |
| return false; | |
| } | |
| public override char GetNextChar() | |
| { | |
| return '\0'; | |
| } | |
| public override bool MovePrevious() | |
| { | |
| return false; | |
| } | |
| } | |
| #endregion | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [TestFixture] | |
| public class EncodingHelperTests | |
| { | |
| [TestCase(true, 1251, null)] | |
| [TestCase(true, 1251, "")] | |
| [TestCase(true, 1251, "asdad")] | |
| [TestCase(true, 1251, "абвгода")] | |
| [TestCase(true, 1250, "\x015f")] | |
| [TestCase(false, 1252, "\x015f")] | |
| [TestCase(false, 1250, "\x00fe")] | |
| [TestCase(true, 1252, "\x00fe")] | |
| [TestCase(false, 1251, "2183273-1-2")] | |
| public void CanEncode_ShouldBeExpexted(bool expected, int codePage, string str) | |
| { | |
| var enc = Encoding.GetEncoding(codePage); | |
| var res = EncodingHelper.CanEncode(enc, str); | |
| Assert.AreEqual(expected, res); | |
| } | |
| [TestCase(null, 1251, null)] | |
| [TestCase("", 1251, "")] | |
| [TestCase("asdad", 1251, "asdad")] | |
| [TestCase("абвгода", 1251, "абвгода")] | |
| [TestCase("\x015f", 1250, "\x015f")] | |
| [TestCase("", 1252, "\x015f")] | |
| [TestCase("", 1250, "\x00fe")] | |
| [TestCase("\x00fe", 1252, "\x00fe")] | |
| [TestCase("2183273-1-2", 1251, "2183273-1-2")] | |
| public void Encode_ShouldBeExpexted(string expected, int codePage, string str) | |
| { | |
| var enc = Encoding.GetEncoding(codePage); | |
| var res = EncodingHelper.Encode(enc, str); | |
| Assert.AreEqual(expected, res); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment