internal void ValidateCharset(bool charsetWasDefaulted, Stream contentStream) { bool strongDefault = !charsetWasDefaulted && this.charset.CodePage != 20127; FeInboundCharsetDetector feInboundCharsetDetector = new FeInboundCharsetDetector(this.charset.CodePage, strongDefault, true, true, true); byte[] byteBuffer = ScratchPad.GetByteBuffer(1024); int num = 0; int num2 = 0; while (num2 < 4096 && (num = contentStream.Read(byteBuffer, 0, byteBuffer.Length)) != 0) { feInboundCharsetDetector.AddBytes(byteBuffer, 0, num, false); num2 += num; } if (num == 0) { feInboundCharsetDetector.AddBytes(byteBuffer, 0, 0, true); } int codePageChoice = feInboundCharsetDetector.GetCodePageChoice(); if (codePageChoice != this.charset.CodePage) { this.charset = Charset.GetCharset(codePageChoice); } }
private void DecodeEncodedWord(byte bOrQ, Decoder decoder, ValuePosition encodedWordContentStart, ValuePosition encodedWordContentEnd, bool allowControlCharacters, ref byte[] byteBuffer, ref char[] charBuffer, StringBuilder sb) { ValueIterator valueIterator = new ValueIterator(this.iterator.Lines, this.iterator.LinesMask, encodedWordContentStart, encodedWordContentEnd); if (charBuffer == null) { charBuffer = ScratchPad.GetCharBuffer(Math.Min(1024, this.iterator.TotalLength)); } if (byteBuffer == null) { byteBuffer = ScratchPad.GetByteBuffer(Math.Max(this.maxCharsetNameLength + 1, Math.Min(1024, this.iterator.TotalLength))); } int num = 0; if (bOrQ == 66) { int num2 = 0; int num3 = 0; while (!valueIterator.Eof) { byte b = (byte)(valueIterator.Get() - 32); if ((int)b < ByteEncoder.Tables.Base64ToByte.Length) { b = ByteEncoder.Tables.Base64ToByte[(int)b]; if (b < 64) { num3 = (num3 << 6 | (int)b); num2++; if (num2 == 4) { byteBuffer[num++] = (byte)(num3 >> 16); byteBuffer[num++] = (byte)(num3 >> 8); byteBuffer[num++] = (byte)num3; num2 = 0; if (num + 3 >= byteBuffer.Length) { this.FlushDecodedBytes(byteBuffer, num, decoder, allowControlCharacters, charBuffer, sb); num = 0; } } } } } if (num2 != 0) { if (num2 == 2) { num3 <<= 12; byteBuffer[num++] = (byte)(num3 >> 16); } else if (num2 == 3) { num3 <<= 6; byteBuffer[num++] = (byte)(num3 >> 16); byteBuffer[num++] = (byte)(num3 >> 8); } } } else { while (!valueIterator.Eof) { byte b2 = (byte)valueIterator.Get(); if (b2 == 61) { int num4 = valueIterator.Get(); int num5 = valueIterator.Get(); num4 = (int)((num4 < 0) ? byte.MaxValue : ByteEncoder.Tables.NumFromHex[num4]); num5 = (int)((num5 < 0) ? byte.MaxValue : ByteEncoder.Tables.NumFromHex[num5]); if (num4 == 255 || num5 == 255) { b2 = 61; } else { b2 = (byte)(num4 << 4 | num5); } } else if (b2 == 95) { b2 = 32; } byteBuffer[num++] = b2; if (num >= byteBuffer.Length) { this.FlushDecodedBytes(byteBuffer, num, decoder, allowControlCharacters, charBuffer, sb); num = 0; } } } if (num != 0) { this.FlushDecodedBytes(byteBuffer, num, decoder, allowControlCharacters, charBuffer, sb); } }
private bool ParseEncodedWord(string lastEncodedWordCharsetName, string lastEncodedWordLanguage, ref byte[] byteBuffer, out string encodedWordCharsetName, out string encodedWordLanguage, out byte bOrQ, out ValuePosition encodedWordContentStart, out ValuePosition encodedWordContentEnd) { encodedWordCharsetName = null; encodedWordLanguage = null; bOrQ = 0; ValuePosition valuePosition = default(ValuePosition); encodedWordContentEnd = valuePosition; encodedWordContentStart = (encodedWordContentEnd = valuePosition); int num = this.iterator.Get(); if (this.iterator.Get() != 63) { return(false); } if (byteBuffer == null) { byteBuffer = ScratchPad.GetByteBuffer(Math.Max(this.maxCharsetNameLength + 1, Math.Min(1024, this.iterator.TotalLength))); } int num2 = -1; int i; for (i = 0; i < this.maxCharsetNameLength + 1; i++) { num = this.iterator.Get(); if (!ValueDecoder.Is2047Token((byte)num)) { break; } byteBuffer[i] = (byte)num; if (num2 == -1 && num == 42) { num2 = i; } } if (i == this.maxCharsetNameLength + 1 || num != 63 || i == 0 || num2 == 0) { return(false); } num = this.iterator.Get(); bOrQ = ((num == 66 || num == 98) ? 66 : ((num == 81 || num == 113) ? 81 : 0)); if (bOrQ == 0 || this.iterator.Get() != 63) { return(false); } if (num2 != -1) { int num3 = num2 + 1; int num4 = i - (num2 + 1); i = num2; if (num4 != 0) { if (lastEncodedWordLanguage != null && num4 == lastEncodedWordLanguage.Length) { int num5 = 0; while (num5 < num4 && lastEncodedWordLanguage[num5] == (char)byteBuffer[num3 + num5]) { num5++; } if (num5 != num4) { encodedWordLanguage = ByteString.BytesToString(byteBuffer, num3, num4, false); } else { encodedWordLanguage = lastEncodedWordLanguage; } } else { encodedWordLanguage = ByteString.BytesToString(byteBuffer, num3, num4, false); } } } if (lastEncodedWordCharsetName != null && i == lastEncodedWordCharsetName.Length) { int num6 = 0; while (num6 < i && lastEncodedWordCharsetName[num6] == (char)byteBuffer[num6]) { num6++; } if (num6 != i) { encodedWordCharsetName = ByteString.BytesToString(byteBuffer, 0, i, false); } else { encodedWordCharsetName = lastEncodedWordCharsetName; } } else { encodedWordCharsetName = ByteString.BytesToString(byteBuffer, 0, i, false); } encodedWordContentStart = this.iterator.CurrentPosition; bool flag = false; for (;;) { encodedWordContentEnd = this.iterator.CurrentPosition; num = this.iterator.Get(); if (num == -1) { break; } if (MimeScan.IsLWSP((byte)num)) { flag = true; } else { if (num == 63) { num = this.iterator.Get(); if (num == -1) { return(false); } if (num == 61) { return(true); } this.iterator.Unget(); if (bOrQ != 81) { return(false); } } else if (num == 61 && flag) { num = this.iterator.Get(); if (num == -1) { return(false); } if (num == 63) { goto Block_33; } this.iterator.Unget(); } flag = false; } } return(false); Block_33: this.iterator.Unget(); this.iterator.Unget(); return(false); }
// 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); }