Windows Phone character-encoding
See the question and my original answer on StackOverflowHere is a piece of code that is Windows Phone 7.1 (and Silverlight I think) compatible that redefines an ISO-8859-9 (or Latin9) encoding. The code also redefines the ISO-8859-1 (or Latin1) and Windows-1252 for convenience. It could also be used to define the other ISO Latin encoding family:
public class Latin9Encoding : LatinEncoding
{
public Latin9Encoding()
: base(CharMap)
{
}
static Latin9Encoding()
{
CharMap = new Dictionary<byte, char>();
CharMap.Add(0xD0, '\u011E');
CharMap.Add(0xDD, '\u0130');
CharMap.Add(0xDE, '\u015E');
CharMap.Add(0xF0, '\u011F');
CharMap.Add(0xFD, '\u0131');
CharMap.Add(0xFE, '\u015F');
}
public static Dictionary<byte, char> CharMap;
public override string WebName
{
get
{
return "iso-8859-9";
}
}
}
public class Windows1252Encoding : LatinEncoding
{
public Windows1252Encoding()
: base(CharMap)
{
}
static Windows1252Encoding()
{
CharMap = new Dictionary<byte, char>();
CharMap.Add(0x80, '\u20AC');
CharMap.Add(0x82, '\u201A');
CharMap.Add(0x83, '\u0192');
CharMap.Add(0x84, '\u201E');
CharMap.Add(0x85, '\u2026');
CharMap.Add(0x86, '\u2020');
CharMap.Add(0x87, '\u2021');
CharMap.Add(0x88, '\u02C6');
CharMap.Add(0x89, '\u2030');
CharMap.Add(0x8A, '\u0160');
CharMap.Add(0x8B, '\u2039');
CharMap.Add(0x8C, '\u0152');
CharMap.Add(0x8E, '\u017D');
CharMap.Add(0x91, '\u2018');
CharMap.Add(0x92, '\u2019');
CharMap.Add(0x93, '\u201C');
CharMap.Add(0x94, '\u201D');
CharMap.Add(0x95, '\u2022');
CharMap.Add(0x96, '\u2013');
CharMap.Add(0x97, '\u2014');
CharMap.Add(0x98, '\u02DC');
CharMap.Add(0x99, '\u2122');
CharMap.Add(0x9A, '\u0161');
CharMap.Add(0x9B, '\u203A');
CharMap.Add(0x9C, '\u0153');
CharMap.Add(0x9E, '\u017E');
CharMap.Add(0x9F, '\u0178');
}
public static Dictionary<byte, char> CharMap;
public override string WebName
{
get
{
return "Windows-1252";
}
}
}
public class Latin1Encoding : LatinEncoding
{
public Latin1Encoding()
: base(null)
{
}
public override string WebName
{
get
{
return "iso-8859-1";
}
}
}
public abstract class LatinEncoding : Encoding
{
protected LatinEncoding(Dictionary<byte, char> map)
{
FallbackByte = (byte)'?';
if (map != null)
{
Map = map;
ReverseMap = new Dictionary<char, byte>(map.Count);
foreach (var entry in map)
{
ReverseMap[entry.Value] = entry.Key;
}
}
}
public byte FallbackByte { get; set; }
public Dictionary<byte, char> Map { get; private set; }
public Dictionary<char, byte> ReverseMap { get; private set; }
public override int GetByteCount(char[] chars, int index, int count)
{
return count;
}
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
if (chars == null)
throw new ArgumentNullException("bytes");
if (charIndex < 0)
throw new ArgumentOutOfRangeException("charIndex");
if (charCount < 0)
throw new ArgumentOutOfRangeException("charCount");
if (bytes == null)
throw new ArgumentNullException("bytes");
if (byteIndex < 0)
throw new ArgumentOutOfRangeException("byteIndex");
if ((charIndex + charCount) > chars.Length)
throw new ArgumentOutOfRangeException("charCount");
if ((byteIndex + charCount) > bytes.Length)
throw new ArgumentOutOfRangeException("charCount");
for (int i = 0; i < charCount; i++)
{
char c = chars[charIndex + i];
if (ReverseMap != null)
{
byte b;
if (ReverseMap.TryGetValue(c, out b))
{
bytes[byteIndex + i] = b;
continue;
}
}
bytes[byteIndex + i] = c > 255 ? FallbackByte : (byte)c;
}
return charCount;
}
public override int GetCharCount(byte[] bytes, int index, int count)
{
return count;
}
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
if (bytes == null)
throw new ArgumentNullException("bytes");
if (chars == null)
throw new ArgumentNullException("chars");
if (byteIndex < 0)
throw new ArgumentOutOfRangeException("byteIndex");
if (byteCount < 0)
throw new ArgumentOutOfRangeException("byteCount");
if (charIndex < 0)
throw new ArgumentOutOfRangeException("charIndex");
if ((byteIndex + byteCount) > bytes.Length)
throw new ArgumentOutOfRangeException("byteCount");
if ((charIndex + byteCount) > chars.Length)
throw new ArgumentOutOfRangeException("byteCount");
for (int i = 0; i < byteCount; i++)
{
if (Map != null)
{
char c;
if (Map.TryGetValue(bytes[byteIndex + i], out c))
{
chars[charIndex + i] = c;
continue;
}
}
chars[charIndex + i] = (char)bytes[byteIndex + i];
}
return byteCount;
}
public override int GetMaxByteCount(int charCount)
{
return charCount;
}
public override int GetMaxCharCount(int byteCount)
{
return byteCount;
}
}