예제 #1
0
        private static Charset DetectOutboundCharset(Item item, OutboundConversionOptions options, object internetCpidObj, bool trustInternetCpid)
        {
            if (options != null && options.DetectionOptions.PreferredCharset != null && (options.DetectionOptions.RequiredCoverage == 0 || (!(internetCpidObj is PropertyError) && trustInternetCpid && options.DetectionOptions.PreferredCharset.CodePage == (int)internetCpidObj)))
            {
                Charset preferredCharset = options.DetectionOptions.PreferredCharset;
                if (ConvertUtils.TryTransformCharset(ref preferredCharset))
                {
                    return(preferredCharset);
                }
            }
            StringBuilder stringBuilder = new StringBuilder();

            item.CoreItem.GetCharsetDetectionData(stringBuilder, CharsetDetectionDataFlags.Complete | CharsetDetectionDataFlags.NoMessageDecoding);
            if (item.Body.IsBodyDefined)
            {
                using (TextReader textReader = item.Body.OpenTextReader(BodyFormat.TextPlain))
                {
                    char[] array     = new char[32768];
                    int    charCount = textReader.ReadBlock(array, 0, array.Length);
                    stringBuilder.Append(array, 0, charCount);
                }
            }
            OutboundCodePageDetector outboundCodePageDetector = new OutboundCodePageDetector();

            outboundCodePageDetector.AddText(stringBuilder.ToString());
            if (options != null && options.DetectionOptions.PreferredCharset != null && outboundCodePageDetector.GetCodePageCoverage(options.DetectionOptions.PreferredCharset.CodePage) >= options.DetectionOptions.RequiredCoverage)
            {
                Charset preferredCharset = options.DetectionOptions.PreferredCharset;
                if (ConvertUtils.TryTransformCharset(ref preferredCharset))
                {
                    return(preferredCharset);
                }
            }
            if (!(internetCpidObj is PropertyError) && !trustInternetCpid)
            {
                int     num = (options != null) ? options.DetectionOptions.RequiredCoverage : 100;
                Charset preferredCharset;
                if (Charset.TryGetCharset((int)internetCpidObj, out preferredCharset) && preferredCharset.IsDetectable && outboundCodePageDetector.GetCodePageCoverage((int)internetCpidObj) >= num && ConvertUtils.TryTransformCharset(ref preferredCharset))
                {
                    return(preferredCharset);
                }
            }
            if (!trustInternetCpid || (internetCpidObj is PropertyError && !item.Body.IsBodyDefined))
            {
                int     codePage = outboundCodePageDetector.GetCodePage();
                Charset preferredCharset;
                if (Charset.TryGetCharset(codePage, out preferredCharset) && ConvertUtils.TryTransformCharset(ref preferredCharset))
                {
                    return(preferredCharset);
                }
            }
            return(null);
        }
예제 #2
0
        public void ValidateItemCharset()
        {
            if (this.IsCharsetDetectionDisabled(this.CharsetFlags))
            {
                return;
            }
            int valueOrDefault = this.coreItem.PropertyBag.GetValueOrDefault <int>(InternalSchema.InternetCpid);

            if (ItemCharsetDetector.IsMultipleLanguageCodePage(valueOrDefault))
            {
                if (this.coreItem.Body.RawFormat == BodyFormat.TextHtml && this.coreItem.Body.ForceRedetectHtmlBodyCharset)
                {
                    Charset charset;
                    Charset targetCharset;
                    if (this.TryGetHtmlCharsetFromMetaTag(4096U, out charset) && charset.CodePage != valueOrDefault && Charset.TryGetCharset(valueOrDefault, out targetCharset))
                    {
                        this.RestampItemCharset(targetCharset, null, charset);
                    }
                    this.coreItem.Body.ForceRedetectHtmlBodyCharset = false;
                }
                return;
            }
            Charset charset2;

            if (ConvertUtils.TryGetValidCharset(valueOrDefault, out charset2) && charset2.IsDetectable)
            {
                StringBuilder stringBuilder = new StringBuilder();
                this.coreItem.GetCharsetDetectionData(stringBuilder, CharsetDetectionDataFlags.None);
                if (stringBuilder.Length == 0)
                {
                    return;
                }
                OutboundCodePageDetector outboundCodePageDetector = new OutboundCodePageDetector();
                outboundCodePageDetector.AddText(stringBuilder.ToString());
                if (outboundCodePageDetector.GetCodePageCoverage(valueOrDefault) >= this.DetectionOptions.RequiredCoverage)
                {
                    return;
                }
            }
            MemoryStream cachedHtml;
            int          num = this.DetectCpidWithOptions(null, out cachedHtml);
            Charset      charset3;

            if (Charset.TryGetCharset(num, out charset3) && charset3.IsAvailable)
            {
                this.RestampItemCharset(charset3, cachedHtml, null);
                return;
            }
            ExTraceGlobals.StorageTracer.TraceError <int>((long)this.GetHashCode(), "ValidateItemCharset: detected codepage {0} is not valid", num);
        }
예제 #3
0
        private int DetectCpid(Charset userCharset, out MemoryStream cachedHtmlBody)
        {
            OutboundCodePageDetector outboundCodePageDetector = this.BuildCodePageDetector(out cachedHtmlBody);
            int codePage;

            if (userCharset != null && userCharset.IsDetectable && outboundCodePageDetector.GetCodePageCoverage(userCharset.CodePage) >= this.DetectionOptions.RequiredCoverage)
            {
                codePage = userCharset.CodePage;
            }
            else
            {
                codePage = outboundCodePageDetector.GetCodePage(userCharset, false);
            }
            return(codePage);
        }
예제 #4
0
        private static void GenerateOldFashionedReportBody(MessageItem message, Stream outputStream, out CultureInfo cultureInfo, out Charset charset)
        {
            Encoding unicode = Encoding.Unicode;
            string   text    = ReportMessage.GenerateOldFashionedReportBody(message, out cultureInfo).ToString(cultureInfo);
            OutboundCodePageDetector outboundCodePageDetector = new OutboundCodePageDetector();

            outboundCodePageDetector.AddText(text);
            charset = Charset.GetCharset(outboundCodePageDetector.GetCodePage(Culture.GetCulture(cultureInfo.Name), false));
            using (MemoryStream memoryStream = new MemoryStream(unicode.GetBytes(text)))
            {
                new TextToHtml
                {
                    InputEncoding  = unicode,
                    OutputEncoding = charset.GetEncoding()
                }.Convert(memoryStream, outputStream);
            }
        }
예제 #5
0
        private OutboundCodePageDetector BuildCodePageDetector(out MemoryStream cachedHtmlBody)
        {
            cachedHtmlBody = null;
            OutboundCodePageDetector  outboundCodePageDetector  = new OutboundCodePageDetector();
            StringBuilder             stringBuilder             = new StringBuilder();
            CharsetDetectionDataFlags charsetDetectionDataFlags = CharsetDetectionDataFlags.Complete;

            if (this.coreItem.CharsetDetector.NoMessageDecoding && ItemBuilder.ReadStoreObjectTypeFromPropertyBag(this.coreItem.PropertyBag) == StoreObjectType.RightsManagedMessage)
            {
                charsetDetectionDataFlags |= CharsetDetectionDataFlags.NoMessageDecoding;
            }
            this.coreItem.GetCharsetDetectionData(stringBuilder, charsetDetectionDataFlags);
            outboundCodePageDetector.AddText(stringBuilder.ToString());
            if (this.cachedBodyData == null)
            {
                this.cachedBodyData = this.LoadCachedBodyData(out cachedHtmlBody);
            }
            if (this.cachedBodyData != null)
            {
                outboundCodePageDetector.AddText(this.cachedBodyData);
            }
            return(outboundCodePageDetector);
        }
예제 #6
0
        // Token: 0x06000252 RID: 594 RVA: 0x0000AF40 File Offset: 0x00009140
        internal static MimeStringList EncodeValue(string value, EncodingOptions encodingOptions, ValueEncodingStyle style)
        {
            if (string.IsNullOrEmpty(value))
            {
                return(MimeStringList.Empty);
            }
            if (!MimeCommon.IsEncodingRequired(value, encodingOptions.AllowUTF8))
            {
                return(new MimeStringList(new MimeString(value)));
            }
            MimeStringList result = default(MimeStringList);
            Charset        encodingCharset;

            if (encodingOptions.CharsetName != null)
            {
                encodingCharset = encodingOptions.GetEncodingCharset();
            }
            else
            {
                OutboundCodePageDetector outboundCodePageDetector = new OutboundCodePageDetector();
                outboundCodePageDetector.AddText(value);
                int codePage = outboundCodePageDetector.GetCodePage();
                if (!Charset.TryGetCharset(codePage, out encodingCharset))
                {
                    encodingCharset = MimeCommon.DefaultEncodingOptions.GetEncodingCharset();
                }
            }
            ByteEncoder.Tables.CharClasses charClasses = ByteEncoder.Tables.CharClasses.QEncode;
            if (style == ValueEncodingStyle.Phrase)
            {
                charClasses |= ByteEncoder.Tables.CharClasses.QPhraseUnsafe;
            }
            else if (style == ValueEncodingStyle.Comment)
            {
                charClasses |= ByteEncoder.Tables.CharClasses.QCommentUnsafe;
            }
            bool allowQEncoding = false;

            MimeCommon.CalculateMethodAndChunkSize calculateMethodAndChunkSize;
            if (encodingCharset.Kind == CodePageKind.Sbcs)
            {
                calculateMethodAndChunkSize = MimeCommon.calculateMethodAndChunkSizeSbcs;
                if (encodingCharset.AsciiSupport >= CodePageAsciiSupport.Fine)
                {
                    allowQEncoding = true;
                }
            }
            else if (encodingCharset.Kind == CodePageKind.Dbcs)
            {
                calculateMethodAndChunkSize = MimeCommon.calculateMethodAndChunkSizeDbcs;
                if (encodingCharset.AsciiSupport >= CodePageAsciiSupport.Fine)
                {
                    allowQEncoding = true;
                }
            }
            else if (encodingCharset.CodePage == 65001)
            {
                calculateMethodAndChunkSize = MimeCommon.calculateMethodAndChunkSizeUtf8;
                allowQEncoding = true;
            }
            else if (encodingCharset.CodePage == 1200 || encodingCharset.CodePage == 1201)
            {
                calculateMethodAndChunkSize = MimeCommon.calculateMethodAndChunkSizeUnicode16;
            }
            else if (encodingCharset.CodePage == 12000 || encodingCharset.CodePage == 12001)
            {
                calculateMethodAndChunkSize = MimeCommon.calculateMethodAndChunkSizeUnicode32;
            }
            else
            {
                calculateMethodAndChunkSize = MimeCommon.calculateMethodAndChunkSizeMbcs;
            }
            int num  = 75;
            int num2 = 7 + encodingCharset.Name.Length;
            int num3 = num - num2;

            if (num3 < 32)
            {
                num  = num2 + 32;
                num3 = 32;
            }
            byte[]   byteBuffer = ScratchPad.GetByteBuffer(num3);
            Encoding encoding   = encodingCharset.GetEncoding();

            byte[] array = new byte[5 + encodingCharset.Name.Length];
            int    num4  = 0;

            array[num4++] = 61;
            array[num4++] = 63;
            num4         += ByteString.StringToBytes(encodingCharset.Name, array, num4, false);
            array[num4++] = 63;
            array[num4++] = 88;
            array[num4++] = 63;
            MimeString mimeString = new MimeString(array);
            int        num5       = 0;

            byte[] array2 = null;
            int    num6   = 0;
            int    num7   = num3 / 4;

            while (num5 != value.Length)
            {
                byte b;
                int  num8;
                calculateMethodAndChunkSize(allowQEncoding, charClasses, encoding, value, num5, num3, out b, out num8);
                int bytes;
                int num10;
                for (;;)
                {
                    for (;;)
                    {
                        try
                        {
                            bytes = encoding.GetBytes(value, num5, num8, byteBuffer, 0);
                        }
                        catch (ArgumentException)
                        {
                            if (num8 < 2)
                            {
                                throw;
                            }
                            num8 -= ((num8 > 10) ? 3 : 1);
                            if (MimeCommon.IsLowSurrogate(value[num5 + num8]) && MimeCommon.IsHighSurrogate(value[num5 + num8 - 1]))
                            {
                                num8--;
                            }
                            break;
                        }
                        if (bytes == 0)
                        {
                            goto IL_424;
                        }
                        if (array2 == null || array2.Length - num6 < num + 1)
                        {
                            if (array2 != null)
                            {
                                result.Append(new MimeString(array2, 0, num6));
                                num6 = 0;
                            }
                            int val  = ((value.Length - num5) / num8 + 1) * (num + 1);
                            int num9 = Math.Min(val, 4096 / (num + 1) * (num + 1));
                            array2 = new byte[num9];
                        }
                        num10 = num6;
                        if (result.Count > 0 || num10 > 0)
                        {
                            array2[num10++] = 32;
                        }
                        num10            += mimeString.CopyTo(array2, num10);
                        array2[num10 - 2] = b;
                        if (b != 81)
                        {
                            goto IL_3F5;
                        }
                        int num11 = num10;
                        int num12 = 0;
                        while (num12 < bytes && num10 - num11 + 1 <= num3)
                        {
                            byte b2 = byteBuffer[num12];
                            if (MimeCommon.QEncodingRequired((char)b2, charClasses))
                            {
                                if (num10 - num11 + 3 > num3)
                                {
                                    break;
                                }
                                array2[num10++] = 61;
                                array2[num10++] = ByteEncoder.NibbleToHex[b2 >> 4];
                                array2[num10++] = ByteEncoder.NibbleToHex[(int)(b2 & 15)];
                            }
                            else
                            {
                                if (b2 == 32)
                                {
                                    b2 = 95;
                                }
                                array2[num10++] = b2;
                            }
                            num12++;
                        }
                        if (num12 == bytes)
                        {
                            goto IL_408;
                        }
                        if (num8 < 2)
                        {
                            goto Block_26;
                        }
                        num8 -= ((num8 > 10) ? 3 : 1);
                        if (MimeCommon.IsLowSurrogate(value[num5 + num8]) && MimeCommon.IsHighSurrogate(value[num5 + num8 - 1]))
                        {
                            num8--;
                        }
                    }
                }
IL_424:
                num5 += num8;
                continue;
Block_26:
                throw new InvalidOperationException("unexpected thing just happened");
IL_408:
                array2[num10++] = 63;
                array2[num10++] = 61;
                num6            = num10;
                goto IL_424;
IL_3F5:
                num10 += MimeCommon.Base64EncodeChunk(byteBuffer, 0, bytes, array2, num10);
                goto IL_408;
            }
            if (array2 != null)
            {
                result.Append(new MimeString(array2, 0, num6));
            }
            return(result);
        }