using System;
using System.Text;
using System.Globalization;
namespace XamlTorrent.Common
{
///
/// Represents hexadecimal (base-16) character encoding.
///
public class HexEncoding : Encoding
{
public HexEncoding()
: base()
{
}
public override int GetByteCount(char[] chars, int index, int count)
{
return (count / 2); // Hexadecimal uses 2 chars per byte
}
public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
for (int i = 0; i < charCount / 2; i++)
{
int lowCharIndex = (charIndex + (i * 2) + 1);
int highCharIndex = (charIndex + (i * 2));
byte low = AsciiToHex(chars[lowCharIndex]);
byte high = AsciiToHex(chars[highCharIndex]);
bytes[byteIndex + i] = (byte)(high * 0x10 + low);
}
return (charCount / 2);
}
private static byte AsciiToHex(char ch)
{
UInt16 c = ch;
if (c >= 0x30 && c <= 0x39) // digit
c -= 0x30;
else if (c >= 0x41 && c <= 0x46) // upper-case A...F
c -= 0x37;
else if (c >= 0x61 && c <= 0x66) // lower-case a...f
c -= 0x57;
else
throw new ArgumentOutOfRangeException("ch", "Non-hexadecimal character.");
return (byte)c;
}
private static char HexToAscii(byte bt)
{
if (bt < 0xA) // digit
return (char)(bt + 0x30);
else
return (char)(bt + 0x57);
}
public override int GetCharCount(byte[] bytes, int index, int count)
{
return (count * 2); // Hexadecimal uses 2 chars per byte
}
public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
{
for (int i = 0; i < byteCount; i++)
{
byte b = bytes[i];
byte low = (byte)(b % 0x10);
byte high = (byte)(b / 0x10);
int lowCharIndex = (charIndex + (i * 2) + 1);
int highCharIndex = (charIndex + (i * 2));
chars[lowCharIndex] = HexToAscii(low);
chars[highCharIndex] = HexToAscii(high);
}
return (byteCount * 2);
}
public override int GetMaxByteCount(int charCount)
{
return (charCount / 2); // Hexadecimal uses 2 chars per byte
}
public override int GetMaxCharCount(int byteCount)
{
return (byteCount * 2); // Hexadecimal uses 2 chars per byte
}
}
}