/// <summary> /// Is the position in the string the start of an encoded-word /// </summary> /// <param name="InString">String to examine</param> /// <param name="InBx">Position in string</param> /// <returns></returns> public static bool IsStartOfEncodedWord(string InString, int InBx) { bool isEncodedWord = true; if (AcCommon.PullString(InString, InBx, 2, null) != "=?") { isEncodedWord = false; } else { isEncodedWord = CrackEncodedWord(InString, InBx).a; } return(isEncodedWord); }
// ------------------- CalcMessageShowCodes --------------------------- // return the message string in a form that shows the cr, lf, and tab codes private string CalcMessageShowCodes( ) { string msg = Message; StringBuilder sb = new StringBuilder(msg.Length); for (int Ix = 0; Ix < msg.Length; ++Ix) { char ch1 = msg[Ix]; if (ch1 == '\t') { sb.Append("<TAB>"); } // a crlf followed by a space in a message header is a FOLD. mail agents // interpret folds as whitespace. else if ((ch1 == '\r') && (AcCommon.PullString(msg, Ix, 3, null) == "\r\n ")) { sb.Append("<FOLD>"); Ix += 2; } else if ((ch1 == '\r') && (AcCommon.PullString(msg, Ix, 2, null) == NetworkConstants.CrLf)) { sb.Append("<CRLF>"); ++Ix; } else if (ch1 == '\r') { sb.Append("<CR>"); } else if (ch1 == '\n') { sb.Append("<LF>"); } else { sb.Append(ch1); } } return(sb.ToString( )); }
/// <summary> /// Decode the quoted-printable encoded string. /// Note: use DecodeLines to decode lines of text that include the QP line /// continuation character ( "=" ). /// </summary> /// <param name="InString"></param> /// <returns></returns> public static string DecodeString(string InString) { StringBuilder sb = new StringBuilder(InString.Length); for (int Ix = 0; Ix < InString.Length; ++Ix) { char ch1 = InString[Ix]; if (ch1 != '=') { sb.Append(ch1); } else { string hex = AcCommon.PullString(InString, Ix + 1, 2, " "); // note: not an error if a lone "=" in a QP encoded string. if (AcCommon.IsHexExternalForm(hex) == false) { sb.Append(ch1); } else { // sb.Append( (char) Convert.ToInt32( hex, 16 )) ; // Ix += 2 ; byte singleByte = System.Convert.ToByte(hex, 16); byte[] bytes = AcCommon.ToByteArray(singleByte); string hexChar = System.Text.Encoding.ASCII.GetString(bytes); sb.Append(hexChar); Ix += 2; } } } return(sb.ToString( )); }
/// <summary> /// Crack the component parts of the encoded-word string starting at InBx /// in the string. Return an object pair. pair.a is a bool set to false if the /// encoded-word string is not correctly formed. pair.b is a MimeEncodedWord object /// containing the component parts of the cracked word. /// </summary> /// <param name="InString"></param> /// <param name="InBx"></param> /// <returns></returns> public static BoolObjectPair CrackEncodedWord(string InString, int InBx) { int Fx, Ix, Lx, RemLx; string ws = null; MimeEncodedWord ew = new MimeEncodedWord( ); bool isEncodedWord = true; try { // isolate the next 80 chars from the string as a workspace ( encoded words are // limited to 75 chars or less ) ew.Bx = InBx; ws = AcCommon.PullString(InString, InBx, 80, null).ToLower( ); Ix = 0; // isolate the charset name Ix = 2; if (isEncodedWord == true) { RemLx = ws.Length - Ix; if (RemLx <= 3) { isEncodedWord = false; } else { Fx = ws.IndexOf("?q?", Ix); if (Fx == -1) { isEncodedWord = false; } else { Lx = Fx - Ix; ew.CharSet = InString.Substring(InBx + Ix, Lx); Ix = Fx + 3; } } } // quoted-printable encoded text runs until "?=" if (isEncodedWord == true) { RemLx = ws.Length - Ix; if (RemLx <= 2) { isEncodedWord = false; } else { Fx = ws.IndexOf("?=", Ix); if (Fx == -1) { isEncodedWord = false; } else { Lx = Fx - Ix; string qpEncoded = InString.Substring(InBx + Ix, Lx); ew.DecodedValue = QuotedPrintable.DecodeString(qpEncoded); ew.Lx = Fx + 2; } } } } catch (Exception) { isEncodedWord = false; } return(new BoolObjectPair(isEncodedWord, ew)); }