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); } } }