using System;
using System.Text;
namespace SWModules
{
public delegate void EncodingNotifier(StringBuilder sb);
///
/// The SafeEncoding Class is a child of the UTF8 Encoding class,
/// which implements input checking on the GetChars Methods, that
/// avoids exceptions when the input characters exceed decimal
/// value 127. Any values larger than 127 are converted to
/// carriage returns.
///
public class SafeEncoding : UTF8Encoding
{
private const byte Nonprintreplacement = 13;
private static SafeEncoding _utf8;
public static event EncodingNotifier Notify;
private static StringBuilder sbTemp = new StringBuilder(128);
///
/// Returns a static instance of the SafeEncoding class
///
public new static SafeEncoding UTF8
{
get { return _utf8 ?? (_utf8 = new SafeEncoding()); }
}
///
/// Checks for values above 127 and replaces with selected character
///
/// The byte array containing the sequence of bytes to decode.
/// A character array containing the results of decoding the specified sequence of bytes.
public new static char[] GetChars(byte[] bytes)
{
bool message_corrected = false;
for (var i = 0; i < bytes.Length; i++)
{
if (bytes[i] <= 127)
continue;
bytes[i] = Nonprintreplacement;
message_corrected = true;
}
try
{
if (message_corrected && Notify != null) GetStackNotify();
return UTF8Encoding.UTF8.GetChars(bytes);
}
catch {
return null;
}
}
///
/// Checks for values above 127 and replaces with selected character
///
/// The byte array containing the sequence of bytes to decode.
/// The index of the first byte to decode.
/// The number of bytes to decode.
/// A character array containing the results of decoding the specified sequence of bytes.
public new static char[] GetChars(byte[] bytes, int byteIndex, int byteCount)
{
bool message_corrected = false;
for (var i = byteIndex; i < byteIndex + byteCount; i++)
{
if (bytes[i] <= 127)
continue;
bytes[i] = Nonprintreplacement;
message_corrected = true;
}
try
{
if (message_corrected && Notify != null) GetStackNotify();
return UTF8Encoding.UTF8.GetChars(bytes, byteIndex, byteCount);
}
catch {
return null;
}
}
///
/// Collects a stack trace and notifies subscribers it had an issue decoding a message
///
private static void GetStackNotify()
{
try
{
throw new Exception("Bad Character in byte stream");
}
catch (Exception e)
{
sbTemp.Clear();
sbTemp.Append("[ERROR] SafeEncoding: ");
sbTemp.Append(e.Message);
sbTemp.Append(";");
sbTemp.Append(e.InnerException);
sbTemp.Append(";");
sbTemp.Append(e.StackTrace);
}
if (Notify != null) Notify(sbTemp);
}
}
}