protected override Stream OpenValueReadStream(out int skipTrailingNulls)
        {
            TnefPropertyType tnefType         = this.PropertyReader.PropertyTag.TnefType;
            TnefPropertyType tnefPropertyType = tnefType;

            switch (tnefPropertyType)
            {
            case TnefPropertyType.String8:
            {
                skipTrailingNulls = 1;
                TextToText textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly);
                textToText.InputEncoding  = this.GetString8Encoding();
                textToText.OutputEncoding = ConvertUtils.UnicodeEncoding;
                return(new ConverterStream(this.PropertyReader.GetRawValueReadStream(), textToText, ConverterStreamAccess.Read));
            }

            case TnefPropertyType.Unicode:
                skipTrailingNulls = 2;
                return(this.PropertyReader.GetRawValueReadStream());

            default:
                if (tnefPropertyType == TnefPropertyType.Binary)
                {
                    skipTrailingNulls = 0;
                    return(this.PropertyReader.GetRawValueReadStream());
                }
                StorageGlobals.ContextTraceError(ExTraceGlobals.CcInboundTnefTracer, "InboundTnefConverter::StreamLargeProperty: only supports binary and string properties.");
                throw new ConversionFailedException(ConversionFailureReason.CorruptContent);
            }
        }
Beispiel #2
0
        private void CreateDetectionStream(BodyStreamFormat format, Charset contentCharset, string extraData, bool trustHtmlMetaTag)
        {
            this.detectorCache = new PooledMemoryStream(8192);
            if (extraData != null)
            {
                byte[] bytes = ConvertUtils.UnicodeEncoding.GetBytes(extraData);
                this.detectorCache.Write(bytes, 0, bytes.Length);
            }
            switch (format)
            {
            case BodyStreamFormat.Text:
            {
                if (contentCharset.CodePage == 1200)
                {
                    this.detectorConversionStream = new StreamWrapper(this.detectorCache, false);
                    return;
                }
                TextToText textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly);
                textToText.InputEncoding          = contentCharset.GetEncoding();
                textToText.OutputEncoding         = ConvertUtils.UnicodeEncoding;
                textToText.OutputStreamBufferSize = 1024;
                textToText.InputStreamBufferSize  = 1024;
                this.detectorConversionStream     = new ConverterStream(new StreamWrapper(this.detectorCache, false), textToText, ConverterStreamAccess.Write);
                return;
            }

            case BodyStreamFormat.Html:
            {
                HtmlToText htmlToText = new HtmlToText(TextExtractionMode.ExtractText);
                htmlToText.InputEncoding             = contentCharset.GetEncoding();
                htmlToText.OutputEncoding            = ConvertUtils.UnicodeEncoding;
                htmlToText.DetectEncodingFromMetaTag = trustHtmlMetaTag;
                htmlToText.OutputStreamBufferSize    = 1024;
                htmlToText.InputStreamBufferSize     = 1024;
                this.detectorConversionStream        = new ConverterStream(new StreamWrapper(this.detectorCache, false), htmlToText, ConverterStreamAccess.Write);
                return;
            }

            case BodyStreamFormat.RtfCompressed:
            case BodyStreamFormat.RtfUncompressed:
            {
                RtfToText rtfToText = new RtfToText(TextExtractionMode.ExtractText);
                rtfToText.OutputEncoding         = ConvertUtils.UnicodeEncoding;
                rtfToText.OutputStreamBufferSize = 1024;
                rtfToText.InputStreamBufferSize  = 1024;
                this.detectorConversionStream    = new ConverterStream(new StreamWrapper(this.detectorCache, false), rtfToText, ConverterStreamAccess.Write);
                if (format == BodyStreamFormat.RtfCompressed)
                {
                    RtfCompressedToRtf rtfCompressedToRtf = new RtfCompressedToRtf();
                    rtfCompressedToRtf.OutputStreamBufferSize = 1024;
                    rtfCompressedToRtf.InputStreamBufferSize  = 1024;
                    this.detectorConversionStream             = new ConverterStream(this.detectorConversionStream, rtfCompressedToRtf, ConverterStreamAccess.Write);
                }
                return;
            }

            default:
                return;
            }
        }
Beispiel #3
0
        public void TestHeaderAndFooter()
        {
            string expected  = "Header,Footer";
            string text      = ",";
            var    converter = new TextToText {
                Header = "Header", Footer = "Footer"
            };
            var result = converter.Convert(text);

            Assert.AreEqual(expected, result);
        }
Beispiel #4
0
        public void TestSimpleTextToText()
        {
            string expected = "This is some sample text. This is line #1." + Environment.NewLine +
                              "This is line #2." + Environment.NewLine +
                              "And this is line #3." + Environment.NewLine;
            string text = "This is some sample text. This is line #1." + Environment.NewLine +
                          "This is line #2." + Environment.NewLine +
                          "And this is line #3." + Environment.NewLine;
            var converter = new TextToText();
            var result    = converter.Convert(text);

            Assert.AreEqual(expected, result);
        }
Beispiel #5
0
        public void TestDefaultPropertyValues()
        {
            var converter = new TextToText();

            Assert.IsFalse(converter.DetectEncodingFromByteOrderMark, "DetectEncodingFromByteOrderMark");
            Assert.IsNull(converter.Footer, "Footer");
            Assert.IsNull(converter.Header, "Header");
            Assert.AreEqual(Encoding.UTF8, converter.InputEncoding, "InputEncoding");
            Assert.AreEqual(TextFormat.Text, converter.InputFormat, "InputFormat");
            Assert.AreEqual(Encoding.UTF8, converter.OutputEncoding, "OutputEncoding");
            Assert.AreEqual(TextFormat.Text, converter.OutputFormat, "OutputFormat");
            Assert.AreEqual(4096, converter.InputStreamBufferSize, "InputStreamBufferSize");
            Assert.AreEqual(4096, converter.OutputStreamBufferSize, "OutputStreamBufferSize");
        }
Beispiel #6
0
        internal Stream ConvertWriteStreamFormat(Stream stream, Charset writeStreamCharset)
        {
            if (this.internalFormat == (InternalBodyFormat)this.format && (writeStreamCharset == null || this.charset == writeStreamCharset))
            {
                return(stream);
            }
            Charset       charset = writeStreamCharset ?? this.charset;
            TextConverter converter;

            if (this.internalFormat == InternalBodyFormat.RtfCompressed)
            {
                stream = new ConverterStream(stream, new RtfToRtfCompressed(), ConverterStreamAccess.Write);
                if (BodyFormat.Rtf == this.format)
                {
                    return(stream);
                }
                converter = new TextToRtf
                {
                    InputEncoding = charset.GetEncoding()
                };
            }
            else if (this.internalFormat == InternalBodyFormat.Enriched)
            {
                converter = new HtmlToEnriched
                {
                    InputEncoding  = charset.GetEncoding(),
                    OutputEncoding = this.Encoding
                };
            }
            else if (this.internalFormat == InternalBodyFormat.Html)
            {
                converter = new HtmlToHtml
                {
                    InputEncoding  = charset.GetEncoding(),
                    OutputEncoding = this.Encoding
                };
            }
            else
            {
                converter = new TextToText
                {
                    InputEncoding  = charset.GetEncoding(),
                    OutputEncoding = this.Encoding
                };
            }
            return(new ConverterStream(stream, converter, ConverterStreamAccess.Write));
        }
Beispiel #7
0
        public void TestConvertFromStreamToStream()
        {
            const string input     = "This is some text...";
            var          converter = new TextToText {
                DetectEncodingFromByteOrderMark = false,
                InputEncoding  = Encoding.ASCII,
                OutputEncoding = Encoding.ASCII
            };

            using (var output = new MemoryStream()) {
                using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(input)))
                    converter.Convert(stream, output);

                var result = Encoding.ASCII.GetString(output.GetBuffer(), 0, (int)output.Length);

                Assert.AreEqual(input, result);
            }
        }
Beispiel #8
0
        public void TestConvertFromStreamToWriter()
        {
            const string input     = "This is some text...";
            var          converter = new TextToText {
                DetectEncodingFromByteOrderMark = false,
                InputEncoding  = Encoding.ASCII,
                OutputEncoding = Encoding.ASCII
            };

            using (var writer = new StringWriter()) {
                using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(input)))
                    converter.Convert(stream, writer);

                var result = writer.ToString();

                Assert.AreEqual(input, result);
            }
        }
        private static object FromTextToText(ICoreItem coreItem, BodyWriteConfiguration configuration, Stream bodyStream, bool createWriter)
        {
            Stream stream = null;
            object obj    = null;

            try
            {
                stream = new BodyCharsetDetectionStream(bodyStream, null, coreItem, BodyStreamFormat.Text, ConvertUtils.UnicodeCharset, configuration.TargetCharset, configuration.TargetCharsetFlags, null, false);
                if (!createWriter && !configuration.IsContentTransformationNeeded(coreItem))
                {
                    obj = stream;
                }
                else
                {
                    TextToText textToText;
                    if (string.IsNullOrEmpty(configuration.InjectPrefix) && string.IsNullOrEmpty(configuration.InjectSuffix))
                    {
                        textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly);
                    }
                    else
                    {
                        textToText = new TextToText();
                    }
                    textToText.InputEncoding  = configuration.SourceEncoding;
                    textToText.OutputEncoding = ConvertUtils.UnicodeEncoding;
                    if (!string.IsNullOrEmpty(configuration.InjectPrefix) || !string.IsNullOrEmpty(configuration.InjectSuffix))
                    {
                        textToText.Header             = configuration.InjectPrefix;
                        textToText.Footer             = configuration.InjectSuffix;
                        textToText.HeaderFooterFormat = configuration.InjectionHeaderFooterFormat;
                    }
                    obj = BodyWriteDelegates.GetConverterStreamOrWriter(stream, textToText, createWriter);
                }
            }
            finally
            {
                if (obj == null && stream != null)
                {
                    BodyWriteDelegates.SafeDisposeStream(stream);
                }
            }
            return(obj);
        }
Beispiel #10
0
        public void TestArgumentExceptions()
        {
            var converter = new TextToText();

            Assert.Throws <ArgumentNullException> (() => converter.InputEncoding  = null);
            Assert.Throws <ArgumentNullException> (() => converter.OutputEncoding = null);

            Assert.Throws <ArgumentOutOfRangeException> (() => converter.InputStreamBufferSize  = -1);
            Assert.Throws <ArgumentOutOfRangeException> (() => converter.OutputStreamBufferSize = -1);

            Assert.Throws <ArgumentNullException> (() => converter.Convert(null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert((Stream)null, Stream.Null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert(Stream.Null, (Stream)null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert((TextReader)null, Stream.Null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert(Stream.Null, (TextWriter)null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert(new StreamReader(Stream.Null), (Stream)null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert((Stream)null, new StreamWriter(Stream.Null)));
            Assert.Throws <ArgumentNullException> (() => converter.Convert(new StreamReader(Stream.Null), (TextWriter)null));
            Assert.Throws <ArgumentNullException> (() => converter.Convert((TextReader)null, new StreamWriter(Stream.Null)));
        }
Beispiel #11
0
        public void TestPropertySetters()
        {
            var latin1    = Encoding.GetEncoding("iso-8859-1");
            var utf16     = Encoding.Unicode;
            var converter = new TextToText();

            converter.InputEncoding = latin1;
            Assert.AreEqual(latin1, converter.InputEncoding, "InputEncoding");

            converter.InputStreamBufferSize = 5000;
            Assert.AreEqual(5000, converter.InputStreamBufferSize, "InputStreamBufferSize");

            converter.OutputEncoding = utf16;
            Assert.AreEqual(utf16, converter.OutputEncoding, "OutputEncoding");

            converter.OutputStreamBufferSize = 6000;
            Assert.AreEqual(6000, converter.OutputStreamBufferSize, "OutputStreamBufferSize");

            converter.DetectEncodingFromByteOrderMark = true;
            Assert.IsTrue(converter.DetectEncodingFromByteOrderMark, "DetectEncodingFromByteOrderMark");
        }
        private static object FromTextToText(ICoreItem coreItem, BodyReadConfiguration configuration, Stream bodyStream, bool createReader)
        {
            TextToText textToText;

            if (string.IsNullOrEmpty(configuration.InjectPrefix) && string.IsNullOrEmpty(configuration.InjectSuffix))
            {
                textToText = new TextToText(TextToTextConversionMode.ConvertCodePageOnly);
            }
            else
            {
                textToText = new TextToText();
            }
            textToText.InputEncoding  = ConvertUtils.UnicodeEncoding;
            textToText.OutputEncoding = configuration.Encoding;
            if (!string.IsNullOrEmpty(configuration.InjectPrefix) || !string.IsNullOrEmpty(configuration.InjectSuffix))
            {
                textToText.Header             = configuration.InjectPrefix;
                textToText.Footer             = configuration.InjectSuffix;
                textToText.HeaderFooterFormat = configuration.InjectionHeaderFooterFormat;
            }
            return(BodyReadDelegates.GetTextStreamOrReader(bodyStream, textToText, createReader));
        }
Beispiel #13
0
        static public void AddFooterToBody(String messageid, Microsoft.Exchange.Data.Transport.Email.Body body, String text)
        {
            Stream   originalbodycontent = null;
            Stream   newbodycontent      = null;
            Encoding encoding;
            String   charsetname;
            Log      log = Log.Instance;

            try
            {
                BodyFormat bodyformat = body.BodyFormat;
                if (!body.TryGetContentReadStream(out originalbodycontent))
                {
                    //body can't be decoded
                    log.Do(messageid + ": email body format could not be decoded - warning footer not appended", 0);
                }
                if (BodyFormat.Text == bodyformat)
                {
                    charsetname = body.CharsetName;
                    if (null == charsetname || !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetname, out encoding))
                    {
                        // either no charset, or charset is not supported by the system
                        log.Do(messageid + ": email body character set is either not defined or not supported by the system - warning footer not appended", 0);
                    }
                    else
                    {
                        TextToText texttotextconversion = new TextToText();
                        texttotextconversion.InputEncoding      = encoding;
                        texttotextconversion.HeaderFooterFormat = HeaderFooterFormat.Text;
                        texttotextconversion.Footer             = text;
                        newbodycontent = body.GetContentWriteStream();
                        try
                        {
                            texttotextconversion.Convert(originalbodycontent, newbodycontent);
                        }
                        catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                        {
                            log.Do(messageid + ": error while performing body text conversion - warning footer not appended", 0);
                        }
                    }
                }
                else if (BodyFormat.Html == bodyformat)
                {
                    charsetname = body.CharsetName;
                    if (null == charsetname ||
                        !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetname, out encoding))
                    {
                        log.Do(messageid + ": email body character set is either not defined or unsupported - warning footer not appended", 0);
                    }
                    else
                    {
                        HtmlToHtml htmltohtmlconversion = new HtmlToHtml();
                        htmltohtmlconversion.InputEncoding      = encoding;
                        htmltohtmlconversion.HeaderFooterFormat = HeaderFooterFormat.Html;
                        htmltohtmlconversion.Footer             = "<p><font size=\"-1\">" + text + "</font></p>";
                        newbodycontent = body.GetContentWriteStream();

                        try
                        {
                            htmltohtmlconversion.Convert(originalbodycontent, newbodycontent);
                        }
                        catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                        {
                            // the conversion has failed..
                            log.Do(messageid + ": error while performing body html conversion - warning footer not appended", 0);
                        }
                    }
                }
                else if (BodyFormat.Rtf == bodyformat)
                {
                    RtfToRtf rtftortfconversion = new RtfToRtf();
                    rtftortfconversion.HeaderFooterFormat = HeaderFooterFormat.Html;
                    rtftortfconversion.Footer             = "<font face=\"Arial\" size=\"+1\">" + text + "</font>";
                    Stream uncompressedbodycontent = body.GetContentWriteStream();

                    try
                    {
                        rtftortfconversion.Convert(originalbodycontent, uncompressedbodycontent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        //Conversion failed
                        log.Do(messageid + ": error while decompressing body rtf - warning footer not appended", 0);
                    }

                    RtfToRtfCompressed rtfcompressionconversion = new RtfToRtfCompressed();
                    rtfcompressionconversion.CompressionMode = RtfCompressionMode.Compressed;
                    newbodycontent = body.GetContentWriteStream();

                    try
                    {
                        rtfcompressionconversion.Convert(uncompressedbodycontent, newbodycontent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // the conversion has failed..
                        log.Do(messageid + ": error compressing body rtf - warning footer not appended", 0);
                    }
                }

                else
                {
                    // Handle cases where the body format is not one of the above.
                    log.Do(messageid + ": unsupported body email format - warning footer not appended", 0);
                }
            }

            finally
            {
                if (originalbodycontent != null)
                {
                    originalbodycontent.Close();
                }

                if (newbodycontent != null)
                {
                    newbodycontent.Close();
                }
            }
        }
        /// <summary>
        /// Invoked by Exchange when the entire message has been received.
        /// </summary>
        /// <param name="source">The source of this event.</param>
        /// <param name="eodArgs">The arguments for this event.</param>
        public void OnEndOfDataHandler(ReceiveMessageEventSource source, EndOfDataEventArgs eodArgs)
        {
            Debug.WriteLine("[BodyConversion] OnEndOfDataHandler is called");

            // The purpose of this sample is to show how TextConverters can be used
            // to update the body. This sample shows how to ensure that no active
            // content, such as scripts, can pass through in a message body.

            EmailMessage message             = eodArgs.MailItem.Message;
            Stream       originalBodyContent = null;
            Stream       newBodyContent      = null;
            Encoding     encoding;
            string       charsetName;

            try
            {
                Body       body       = message.Body;
                BodyFormat bodyFormat = body.BodyFormat;

                if (!body.TryGetContentReadStream(out originalBodyContent))
                {
                    // You cannot decode the body.
                    return;
                }

                if (BodyFormat.Text == bodyFormat)
                {
                    // Plain text body. Add a disclaimer to this body.

                    charsetName = body.CharsetName;
                    if (null == charsetName ||
                        !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetName, out encoding))
                    {
                        // Either no charset, or charset is not supported by the system.
                        return;
                    }

                    // Create and set up the TextToText conversion object.
                    TextToText textToTextConversion = new TextToText();

                    // Don't change the body code page.
                    textToTextConversion.InputEncoding = encoding;
                    // By default, the output code page is the same as the input code page.

                    // Add a disclaimer to indicate that the body is not being filtered.
                    textToTextConversion.HeaderFooterFormat = HeaderFooterFormat.Text;
                    textToTextConversion.Footer             = "the plain text body is NOT being filtered";

                    // Open the stream to write updated content into.
                    newBodyContent = body.GetContentWriteStream();

                    // Do the conversion. This will replace the original text.
                    // with an updated version.
                    try
                    {
                        // The easiest way to do the conversion in one step is by using the Convert
                        // method. It creates the appropriate converter stream
                        // and copies from one stream to another.
                        textToTextConversion.Convert(originalBodyContent, newBodyContent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // The conversion has failed.
                    }
                }
                else if (BodyFormat.Html == bodyFormat)
                {
                    // The HTML body.

                    // Filter the original HTML to remove any scripts and other
                    // potentially unsafe content.

                    charsetName = body.CharsetName;
                    if (null == charsetName ||
                        !Microsoft.Exchange.Data.Globalization.Charset.TryGetEncoding(charsetName, out encoding))
                    {
                        // Either no charset, or charset is not supported by the system.
                        return;
                    }

                    // Create and set up the HtmlToHtml conversion object.
                    HtmlToHtml htmlToHtmlConversion = new HtmlToHtml();

                    // Don't change the body code page.
                    htmlToHtmlConversion.InputEncoding = encoding;
                    // By default, the output code page is the same as the input code page.

                    // Set up output HTML filtering. HTML filtering will ensure that
                    // no scripts or active content can pass through.
                    htmlToHtmlConversion.FilterHtml = true;

                    // Add a disclaimer to indicate that the body is being filtered.
                    htmlToHtmlConversion.HeaderFooterFormat = HeaderFooterFormat.Html;
                    htmlToHtmlConversion.Footer             = "<p><font face=\"Arial\" size=\"+1\">the HTML body is being filtered</font></p>";

                    // Open the stream to write updated content into.
                    newBodyContent = body.GetContentWriteStream();

                    // Do the conversion. This will replace the original HTML
                    // with a filtered version.
                    try
                    {
                        // The easiest way to do the conversion in one step is by using the Convert
                        // method. It creates an appropriate converter stream
                        // and copies from one stream to another.
                        htmlToHtmlConversion.Convert(originalBodyContent, newBodyContent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // The conversion has failed.
                    }
                }
                else if (BodyFormat.Rtf == bodyFormat)
                {
                    // This is compressed RTF body in a TNEF message.

                    // Compressed RTF body can contain the encapsulated original HTML to be
                    // filtered.

                    // Do not modify the message format here, just filter out
                    // potentially unsafe content. Convert RTF to HTML, filter out any
                    // unsafe HTML content, and convert the result back to RTF.

                    // Note that conversion from RTF to HTML and back to RTF can result in loss of data. Some
                    // embedded images in RTF can be lost and formatting can slightly change.

                    // First wrap the original body content, which is in a "compressed RTF" format, into
                    // a stream that will do RTF decompression. Reading from this stream
                    // will return original RTF (the same format that the Word and RichEdit controls are using).
                    ConverterStream uncompressedRtf = new ConverterStream(originalBodyContent, new RtfCompressedToRtf(), ConverterStreamAccess.Read);

                    // Create and configure the RtfToHtml conversion object.
                    RtfToHtml rtfToHtmlConversion = new RtfToHtml();

                    // Set up output HTML filtering. HTML filtering will ensure that
                    // no scripts or active content can pass through.
                    rtfToHtmlConversion.FilterHtml = true;

                    // Add a disclaimer to indicate that the body is being filtered.
                    rtfToHtmlConversion.HeaderFooterFormat = HeaderFooterFormat.Html;
                    rtfToHtmlConversion.Footer             = "<p><font face=\"Arial\" size=1>the RTF body is being filtered</font></p>";

                    // Now create a wrapping TextReader object, which returns the filtered
                    // HTML converted (or extracted) from the original RTF.
                    ConverterReader html = new ConverterReader(uncompressedRtf, rtfToHtmlConversion);

                    // After you filter the HTML, convert it back to RTF. For the purposes of this sample, do not
                    // change the message format.

                    // Create and configure the HtmlToRtf conversion object.
                    HtmlToRtf htmlToRtfConversion = new HtmlToRtf();

                    // Create a wrapping stream that returns RTF converted back from filtered HTML.
                    ConverterStream filteredRtf = new ConverterStream(html, htmlToRtfConversion);

                    // Create and configure the RtfToRtfCompressed conversion object, which
                    // will compress the resulting RTF.
                    RtfToRtfCompressed rtfCompressionConversion = new RtfToRtfCompressed();

                    // Always write it back in a compressed form.
                    rtfCompressionConversion.CompressionMode = RtfCompressionMode.Compressed;

                    // Open the stream to write updated body content into.
                    newBodyContent = body.GetContentWriteStream();

                    // Finally, perform the complete chain of conversions you set up. This
                    // will read the original compressed RTF chunk by chunk, convert it to HTML
                    // and filter scripts, then convert HTML back to RTF, compress it and write
                    // back into the current message body.
                    try
                    {
                        // Use the Convert method because it is convenient. This Convert
                        // method compresses the resulting RTF it reads from the conversion
                        // chain stream you set up and writes the result into the output stream.
                        // It saves a few lines of code that would be required to create another wrapper stream and
                        // copy from one stream to another.
                        rtfCompressionConversion.Convert(filteredRtf, newBodyContent);
                    }
                    catch (Microsoft.Exchange.Data.TextConverters.TextConvertersException)
                    {
                        // The conversion has failed.
                    }
                }

                else
                {
                    // Handle cases where the body format is not one of the above.
                }
            }

            finally
            {
                if (originalBodyContent != null)
                {
                    originalBodyContent.Close();
                }

                if (newBodyContent != null)
                {
                    newBodyContent.Close();
                }
            }
        }
        public override Stream OpenReadStream(long start, long end)
        {
            base.ThrowIfDisposed();
            BodyFormatConversionStorage.BodyFormatConversion conversion = BodyFormatConversionStorage.GetConversion(this.originalFormat, this.targetFormat);
            TextConverter converter     = null;
            Encoding      inputEncoding = null;

            if (this.originalCharset != null)
            {
                inputEncoding = this.originalCharset.GetEncoding();
            }
            Encoding outputEncoding = null;

            if (this.targetCharset != null)
            {
                outputEncoding = this.targetCharset.GetEncoding();
            }
            Stream stream = this.originalStorage.OpenReadStream(this.originalStart, this.originalEnd);

            switch (conversion)
            {
            case BodyFormatConversionStorage.BodyFormatConversion.HtmlToText:
                converter = new HtmlToText
                {
                    InputEncoding  = inputEncoding,
                    OutputEncoding = outputEncoding
                };
                break;

            case BodyFormatConversionStorage.BodyFormatConversion.HtmlToEnriched:
                converter = new HtmlToEnriched
                {
                    InputEncoding  = inputEncoding,
                    OutputEncoding = outputEncoding
                };
                break;

            case BodyFormatConversionStorage.BodyFormatConversion.RtfCompressedToText:
                stream    = new ConverterStream(stream, new RtfCompressedToRtf(), ConverterStreamAccess.Read);
                converter = new RtfToText
                {
                    OutputEncoding = outputEncoding
                };
                break;

            case BodyFormatConversionStorage.BodyFormatConversion.TextToText:
                converter = new TextToText
                {
                    InputEncoding  = inputEncoding,
                    OutputEncoding = outputEncoding
                };
                break;

            case BodyFormatConversionStorage.BodyFormatConversion.HtmlToHtml:
                converter = new HtmlToHtml
                {
                    InputEncoding  = inputEncoding,
                    OutputEncoding = outputEncoding
                };
                break;

            case BodyFormatConversionStorage.BodyFormatConversion.EnrichedToText:
                converter = new EnrichedToText
                {
                    InputEncoding  = inputEncoding,
                    OutputEncoding = outputEncoding
                };
                break;
            }
            return(new ConverterStream(stream, converter, ConverterStreamAccess.Read));
        }