コード例 #1
0
        public void TestRtfCompressedToRtfByteByByte()
        {
            var          input = new byte[] { (byte)'-', 0x00, 0x00, 0x00, (byte)'+', 0x00, 0x00, 0x00, (byte)'L', (byte)'Z', (byte)'F', (byte)'u', 0xf1, 0xc5, 0xc7, 0xa7, 0x03, 0x00, (byte)'\n', 0x00, (byte)'r', (byte)'c', (byte)'p', (byte)'g', (byte)'1', (byte)'2', (byte)'5', (byte)'B', (byte)'2', (byte)'\n', 0xf3, (byte)' ', (byte)'h', (byte)'e', (byte)'l', (byte)'\t', 0x00, (byte)' ', (byte)'b', (byte)'w', 0x05, 0xb0, (byte)'l', (byte)'d', (byte)'}', (byte)'\n', 0x80, 0x0f, 0xa0 };
            const string expected = "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n";
            var          filter = new RtfCompressedToRtf();
            int          outputIndex, outputLength;

            byte[] output;

            using (var memory = new MemoryStream()) {
                for (int i = 0; i < input.Length; i++)
                {
                    output = filter.Filter(input, i, 1, out outputIndex, out outputLength);
                    memory.Write(output, outputIndex, outputLength);
                }

                output = filter.Flush(input, 0, 0, out outputIndex, out outputLength);
                memory.Write(output, outputIndex, outputLength);

                output = memory.ToArray();
            }

            Assert.AreEqual(43, output.Length, "outputLength");
            Assert.IsTrue(filter.IsValidCrc32, "IsValidCrc32");
            Assert.AreEqual(RtfCompressionMode.Compressed, filter.CompressionMode, "ComnpressionMode");

            var text = Encoding.ASCII.GetString(output);

            Assert.AreEqual(expected, text);
        }
コード例 #2
0
        public void TestRtfCompressedToRtfRawByteByByte()
        {
            var          input = new byte[] { (byte)'.', 0x00, 0x00, 0x00, (byte)'\"', 0x00, 0x00, 0x00, (byte)'M', (byte)'E', (byte)'L', (byte)'A', (byte)' ', 0xdf, 0x12, 0xce, (byte)'{', (byte)'\\', (byte)'r', (byte)'t', (byte)'f', (byte)'1', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'c', (byte)'p', (byte)'g', (byte)'1', (byte)'2', (byte)'5', (byte)'2', (byte)'\\', (byte)'p', (byte)'a', (byte)'r', (byte)'d', (byte)' ', (byte)'t', (byte)'e', (byte)'s', (byte)'t', (byte)'}' };
            const string expected = "{\\rtf1\\ansi\\ansicpg1252\\pard test}";
            var          filter = new RtfCompressedToRtf();
            int          outputIndex, outputLength;

            byte[] output;

            using (var memory = new MemoryStream()) {
                for (int i = 0; i < input.Length; i++)
                {
                    output = filter.Filter(input, i, 1, out outputIndex, out outputLength);
                    memory.Write(output, outputIndex, outputLength);
                }

                output = filter.Flush(input, 0, 0, out outputIndex, out outputLength);
                memory.Write(output, outputIndex, outputLength);

                output = memory.ToArray();
            }

            Assert.AreEqual(34, output.Length, "outputLength");
            Assert.IsTrue(filter.IsValidCrc32, "IsValidCrc32");
            Assert.AreEqual(RtfCompressionMode.Uncompressed, filter.CompressionMode, "ComnpressionMode");

            var text = Encoding.ASCII.GetString(output);

            Assert.AreEqual(expected, text);
        }
コード例 #3
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;
            }
        }
コード例 #4
0
        public void TestRtfCompressedToRtfInvalidCrc()
        {
            var input = new byte[] { 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, (byte)'L', (byte)'Z', (byte)'F', (byte)'u', 0xff, 0xff, 0xff, 0xff };
            var filter = new RtfCompressedToRtf();
            int outputIndex, outputLength;

            byte[] output;

            output = filter.Flush(input, 0, input.Length, out outputIndex, out outputLength);

            Assert.AreEqual(0, outputIndex, "outputIndex");
            Assert.AreEqual(0, outputLength, "outputLength");
            Assert.IsFalse(filter.IsValidCrc32, "IsValidCrc32");
            Assert.AreEqual(RtfCompressionMode.Compressed, filter.CompressionMode, "ComnpressionMode");
        }
コード例 #5
0
        public void TestRtfCompressedToRtfUnknownCompressionType()
        {
            var input = new byte[] { 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, (byte)'A', (byte)'B', (byte)'C', (byte)'D', 0xff, 0xff, 0xff, 0xff };
            var filter = new RtfCompressedToRtf();
            int outputIndex, outputLength;

            byte[] output;

            output = filter.Flush(input, 0, input.Length, out outputIndex, out outputLength);

            Assert.AreEqual(16, outputIndex, "outputIndex");
            Assert.AreEqual(0, outputLength, "outputLength");
            Assert.IsFalse(filter.IsValidCrc32, "IsValidCrc32");
            Assert.AreEqual((RtfCompressionMode)1145258561, filter.CompressionMode, "ComnpressionMode");
        }
コード例 #6
0
        public void TestRtfCompressedToRtfRaw()
        {
            var          input = new byte[] { (byte)'.', 0x00, 0x00, 0x00, (byte)'\"', 0x00, 0x00, 0x00, (byte)'M', (byte)'E', (byte)'L', (byte)'A', (byte)' ', 0xdf, 0x12, 0xce, (byte)'{', (byte)'\\', (byte)'r', (byte)'t', (byte)'f', (byte)'1', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'\\', (byte)'a', (byte)'n', (byte)'s', (byte)'i', (byte)'c', (byte)'p', (byte)'g', (byte)'1', (byte)'2', (byte)'5', (byte)'2', (byte)'\\', (byte)'p', (byte)'a', (byte)'r', (byte)'d', (byte)' ', (byte)'t', (byte)'e', (byte)'s', (byte)'t', (byte)'}' };
            const string expected = "{\\rtf1\\ansi\\ansicpg1252\\pard test}";
            var          filter = new RtfCompressedToRtf();
            int          outputIndex, outputLength;

            byte[] output;

            output = filter.Flush(input, 0, input.Length, out outputIndex, out outputLength);

            Assert.AreEqual(16, outputIndex, "outputIndex");
            Assert.AreEqual(34, outputLength, "outputLength");
            Assert.IsTrue(filter.IsValidCrc32, "IsValidCrc32");
            Assert.AreEqual(RtfCompressionMode.Uncompressed, filter.CompressionMode, "ComnpressionMode");

            var text = Encoding.ASCII.GetString(output, outputIndex, outputLength);

            Assert.AreEqual(expected, text);
        }
コード例 #7
0
        public void TestCrossingWritePositionExample()
        {
            // http://msdn.microsoft.com/en-us/library/ee158471(v=exchg.80).aspx
            var compressedRtfData = new byte[] {
                // header
                0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x4c, 0x5a, 0x46, 0x75, 0xe2, 0xd4, 0x4b, 0x51,

                // data
                0x41, 0x00, 0x04, 0x20, 0x57, 0x58, 0x59, 0x5a, 0x0d, 0x6e, 0x7d, 0x01, 0x0e, 0xb0
            };
            var expected = "{\\rtf1 WXYZWXYZWXYZWXYZWXYZ}";

            var converter = new RtfCompressedToRtf();
            int outputLength, outputIndex;

            var decompressed = converter.Flush(compressedRtfData, 0, compressedRtfData.Length, out outputIndex, out outputLength);
            var text         = Encoding.UTF8.GetString(decompressed, outputIndex, outputLength);

            Assert.AreEqual(expected, text, "Decompressed RTF data does not match.");
            Assert.IsTrue(converter.IsValidCrc32, "Invalid CRC32 checksum.");
        }
コード例 #8
0
        public void TestSimpleCompressedRtfExample()
        {
            // http://msdn.microsoft.com/en-us/library/ee217938(v=exchg.80).aspx
            var compressedRtfData = new byte[] {
                // header
                0x2d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x4c, 0x5a, 0x46, 0x75, 0xf1, 0xc5, 0xc7, 0xa7,

                // data
                0x03, 0x00, 0x0a, 0x00, 0x72, 0x63, 0x70, 0x67, 0x31, 0x32, 0x35, 0x42, 0x32, 0x0a, 0xf3, 0x20,
                0x68, 0x65, 0x6c, 0x09, 0x00, 0x20, 0x62, 0x77, 0x05, 0xb0, 0x6c, 0x64, 0x7d, 0x0a, 0x80, 0x0f,
                0xa0
            };
            var expected = "{\\rtf1\\ansi\\ansicpg1252\\pard hello world}\r\n";

            var converter = new RtfCompressedToRtf();
            int outputLength, outputIndex;

            var decompressed = converter.Flush(compressedRtfData, 0, compressedRtfData.Length, out outputIndex, out outputLength);
            var text         = Encoding.UTF8.GetString(decompressed, outputIndex, outputLength);

            Assert.AreEqual(expected, text, "Decompressed RTF data does not match.");
            Assert.IsTrue(converter.IsValidCrc32, "Invalid CRC32 checksum.");
        }
コード例 #9
0
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var prop  = reader.TnefPropertyReader;
            var chars = new char[1024];
            var buf   = new byte[1024];

            while (prop.ReadNextProperty())
            {
                var    type = prop.ValueType;
                object value;

                switch (prop.PropertyTag.Id)
                {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.MessageId = prop.ReadValueAsString();
                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var rtf = new TextPart("rtf");
                        rtf.ContentType.Name = "body.rtf";

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryStream();

                        using (var filtered = new FilteredStream(content)) {
                            filtered.Add(converter);

                            using (var compressed = prop.GetRawValueReadStream()) {
                                compressed.CopyTo(filtered, 4096);
                                filtered.Flush();
                            }
                        }

                        rtf.Content      = new MimeContent(content);
                        content.Position = 0;

                        builder.Attachments.Add(rtf);

                        //Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var html = new TextPart("html");
                        html.ContentType.Name = "body.html";
                        html.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(html);

                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var plain = new TextPart("plain");
                        plain.ContentType.Name = "body.txt";
                        plain.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(plain);

                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.AlternateRecipientAllowed:
                    Assert.AreEqual(typeof(bool), type);
                    value = prop.ReadValueAsBoolean();
                    break;

                case TnefPropertyId.MessageClass:
                    Assert.AreEqual(typeof(string), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.Importance:
                    Assert.AreEqual(typeof(int), type);
                    value = prop.ReadValueAsInt16();
                    break;

                case TnefPropertyId.Priority:
                    Assert.AreEqual(typeof(int), type);
                    value = prop.ReadValueAsInt16();
                    break;

                case TnefPropertyId.Sensitivity:
                    Assert.AreEqual(typeof(int), type);
                    value = prop.ReadValueAsInt16();
                    break;

                case TnefPropertyId.ClientSubmitTime:
                    Assert.AreEqual(typeof(DateTime), type);
                    value = prop.ReadValueAsDateTime();
                    break;

                case TnefPropertyId.SubjectPrefix:
                    Assert.AreEqual(typeof(string), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.MessageSubmissionId:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.ConversationTopic:
                    Assert.AreEqual(typeof(string), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.ConversationIndex:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsBytes();
                    break;

                case TnefPropertyId.SenderName:
                    Assert.AreEqual(typeof(string), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.NormalizedSubject:
                    Assert.AreEqual(typeof(string), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.CreationTime:
                    Assert.AreEqual(typeof(DateTime), type);
                    value = prop.ReadValueAsDateTime();
                    break;

                case TnefPropertyId.LastModificationTime:
                    Assert.AreEqual(typeof(DateTime), type);
                    value = prop.ReadValueAsDateTime();
                    break;

                case TnefPropertyId.InternetCPID:
                    Assert.AreEqual(typeof(int), type);
                    value = prop.ReadValueAsInt32();
                    break;

                case TnefPropertyId.MessageCodepage:
                    Assert.AreEqual(typeof(int), type);
                    value = prop.ReadValueAsInt32();
                    break;

                case TnefPropertyId.INetMailOverrideFormat:
                    Assert.AreEqual(typeof(int), type);
                    value = prop.ReadValueAsInt32();
                    break;

                case TnefPropertyId.ReadReceiptRequested:
                    Assert.AreEqual(typeof(bool), type);
                    value = prop.ReadValueAsBoolean();
                    break;

                case TnefPropertyId.OriginatorDeliveryReportRequested:
                    Assert.AreEqual(typeof(bool), type);
                    value = prop.ReadValueAsBoolean();
                    break;

                case TnefPropertyId.TnefCorrelationKey:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.SenderSearchKey:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.DeleteAfterSubmit:
                    Assert.AreEqual(typeof(bool), type);
                    value = prop.ReadValueAsBoolean();
                    break;

                case TnefPropertyId.MessageDeliveryTime:
                    Assert.AreEqual(typeof(DateTime), type);
                    value = prop.ReadValueAsDateTime();
                    break;

                case TnefPropertyId.SentmailEntryId:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsString();
                    break;

                case TnefPropertyId.RtfInSync:
                    Assert.AreEqual(typeof(bool), type);
                    value = prop.ReadValueAsBoolean();
                    break;

                case TnefPropertyId.MappingSignature:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsBytes();
                    break;

                case TnefPropertyId.StoreRecordKey:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsBytes();
                    break;

                case TnefPropertyId.StoreEntryId:
                    Assert.AreEqual(typeof(byte[]), type);
                    value = prop.ReadValueAsBytes();
                    break;

                default:
                    Assert.Throws <ArgumentNullException> (() => prop.ReadTextValue(null, 0, chars.Length));
                    Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, -1, chars.Length));
                    Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadTextValue(chars, 0, -1));

                    Assert.Throws <ArgumentNullException> (() => prop.ReadRawValue(null, 0, buf.Length));
                    Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, -1, buf.Length));
                    Assert.Throws <ArgumentOutOfRangeException> (() => prop.ReadRawValue(buf, 0, -1));

                    if (type == typeof(int) || type == typeof(long) || type == typeof(bool) || type == typeof(double) || type == typeof(float))
                    {
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsString());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid());
                    }
                    else if (type == typeof(string))
                    {
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsBoolean());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsDouble());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsFloat());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt16());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt32());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsInt64());
                        Assert.Throws <InvalidOperationException> (() => prop.ReadValueAsGuid());
                    }

                    try {
                        value = prop.ReadValue();
                    } catch (Exception ex) {
                        Console.WriteLine("Error in prop.ReadValue(): {0}", ex);
                        value = null;
                    }

                    //Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value);
                    Assert.AreEqual(type, value.GetType(), "Unexpected value type for {0}: {1}", prop.PropertyTag, value.GetType().Name);
                    break;
                }
            }
        }
コード例 #10
0
ファイル: TnefTests.cs プロジェクト: surekqomi/MimeKit
        static void ExtractMapiProperties(TnefReader reader, MimeMessage message, BodyBuilder builder)
        {
            var prop = reader.TnefPropertyReader;

            while (prop.ReadNextProperty())
            {
                switch (prop.PropertyTag.Id)
                {
                case TnefPropertyId.InternetMessageId:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.MessageId = prop.ReadValueAsString();
                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.MessageId);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for Message-Id: {0}", prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.Subject:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode)
                    {
                        message.Subject = prop.ReadValueAsString();
                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, message.Subject);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for Subject: {0}", prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.RtfCompressed:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var rtf = new TextPart("rtf");
                        rtf.ContentType.Name = "body.rtf";

                        var converter = new RtfCompressedToRtf();
                        var content   = new MemoryStream();

                        using (var filtered = new FilteredStream(content)) {
                            filtered.Add(converter);

                            using (var compressed = prop.GetRawValueReadStream()) {
                                compressed.CopyTo(filtered, 4096);
                                filtered.Flush();
                            }
                        }

                        rtf.ContentObject = new ContentObject(content);
                        content.Position  = 0;

                        builder.Attachments.Add(rtf);

                        //Console.WriteLine ("Message Property: {0} = <compressed rtf data>", prop.PropertyTag.Id);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.BodyHtml:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var html = new TextPart("html");
                        html.ContentType.Name = "body.html";
                        html.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(html);

                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, html.Text);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;

                case TnefPropertyId.Body:
                    if (prop.PropertyTag.ValueTnefType == TnefPropertyType.String8 ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Unicode ||
                        prop.PropertyTag.ValueTnefType == TnefPropertyType.Binary)
                    {
                        var plain = new TextPart("plain");
                        plain.ContentType.Name = "body.txt";
                        plain.Text             = prop.ReadValueAsString();

                        builder.Attachments.Add(plain);

                        //Console.WriteLine ("Message Property: {0} = {1}", prop.PropertyTag.Id, plain.Text);
                    }
                    else
                    {
                        Assert.Fail("Unknown property type for {0}: {1}", prop.PropertyTag.Id, prop.PropertyTag.ValueTnefType);
                    }
                    break;

                default:
                    object value;

                    try {
                        value = prop.ReadValue();
                    } catch (Exception ex) {
                        Console.WriteLine("Error in prop.ReadValue(): {0}", ex);
                        value = null;
                    }

                    //Console.WriteLine ("Message Property (unhandled): {0} = {1}", prop.PropertyTag.Id, value);
                    break;
                }
            }
        }