public MimeWriter(System.IO.Stream data, bool forceMime, EncodingOptions encodingOptions) { if (data == null) throw new System.ArgumentNullException(nameof(data)); if (!data.CanWrite) throw new System.ArgumentException("Stream must support writing", nameof(data)); this.forceMime = forceMime; this.data = data; this.encodingOptions = encodingOptions; shimStream = new WriterQueueStream(this); }
internal override long WriteTo(System.IO.Stream stream, EncodingOptions encodingOptions, MimeOutputFilter filter, ref MimeStringLength currentLineLength, ref byte[] scratchBuffer) { var nameLength = this.WriteName(stream, ref scratchBuffer); currentLineLength.IncrementBy((int) nameLength); var merge = false; if (!this.IsDirty && this.RawLength != 0) { if (this.IsProtected) { var num = nameLength + Header.WriteLines(lines, stream); currentLineLength.SetAs(0); return num; } if (!this.IsHeaderLineTooLong(nameLength, out merge)) { var num = nameLength + Header.WriteLines(lines, stream); currentLineLength.SetAs(0); return num; } } var mimeStringList = lines; if (merge) mimeStringList = Header.MergeLines(mimeStringList); return nameLength + Header.QuoteAndFold(stream, mimeStringList, 4026531840U, false, mimeStringList.Length > 0, encodingOptions.AllowUTF8, 0, ref currentLineLength, ref scratchBuffer) + Header.WriteLineEnd(stream, ref currentLineLength); }
internal override long WriteTo(System.IO.Stream stream, EncodingOptions encodingOptions, MimeOutputFilter filter, ref MimeStringLength currentLineLength, ref byte[] scratchBuffer) { var num1 = this.WriteName(stream, ref scratchBuffer); currentLineLength.IncrementBy((int) num1); if (!this.IsDirty && this.RawLength != 0 && this.IsProtected) { var num2 = Header.WriteLines(this.Lines, stream); var num3 = num1 + num2; currentLineLength.SetAs(0); return num3; } if (!parsed) this.Parse(); var num4 = num1 + DateHeader.WriteDateHeaderValue(stream, utcDateTime, timeZoneOffset, ref currentLineLength); currentLineLength.SetAs(0); return num4; }
internal override long WriteValue(System.IO.Stream stream, EncodingOptions encodingOptions, MimeOutputFilter filter, ref MimeStringLength currentLineLength, ref byte[] scratchBuffer) { if (disp.Length == 0) disp = "attachment"; return base.WriteValue(stream, encodingOptions, filter, ref currentLineLength, ref scratchBuffer); }
internal MimeStringList GetDisplayNameToWrite(EncodingOptions encodingOptions) { var mimeStringList = displayNameFragments; if (mimeStringList.GetLength(4026531839U) == 0 && decodedDisplayName != null && decodedDisplayName.Length != 0) { mimeStringList = MimeCommon.EncodeValue( (encodingOptions.EncodingFlags & EncodingFlags.QuoteDisplayNameBeforeRfc2047Encoding) == EncodingFlags.None || !this.IsQuotingRequired(decodedDisplayName, encodingOptions.AllowUTF8) || !MimeCommon.IsEncodingRequired(decodedDisplayName, encodingOptions.AllowUTF8) ? decodedDisplayName : this.QuoteString(decodedDisplayName), encodingOptions, ValueEncodingStyle.Phrase); displayNameFragments = mimeStringList; } else if ((EncodingFlags.ForceReencode & encodingOptions.EncodingFlags) != EncodingFlags.None) mimeStringList = MimeCommon.EncodeValue(this.DisplayName, encodingOptions, ValueEncodingStyle.Phrase); return mimeStringList; }
internal override long WriteTo(System.IO.Stream stream, EncodingOptions encodingOptions, MimeOutputFilter filter, ref MimeStringLength currentLineLength, ref byte[] scratchBuffer) { var nameLength = this.WriteName(stream, ref scratchBuffer); currentLineLength.IncrementBy((int) nameLength); MimeStringList mimeStringList; if (this.RawLength == 0 && decodedValue != null && decodedValue.Length != 0) mimeStringList = this.GetEncodedValue(encodingOptions, ValueEncodingStyle.Normal); else if ((EncodingFlags.ForceReencode & encodingOptions.EncodingFlags) != EncodingFlags.None) { this.ForceParse(); mimeStringList = this.GetEncodedValue(encodingOptions, ValueEncodingStyle.Normal); } else { var merge = false; if (!this.IsDirty && this.RawLength != 0) { if (this.IsProtected) { var num = nameLength + Header.WriteLines(this.Lines, stream); currentLineLength.SetAs(0); return num; } if (!this.IsHeaderLineTooLong(nameLength, out merge)) { var num = nameLength + Header.WriteLines(this.Lines, stream); currentLineLength.SetAs(0); return num; } } mimeStringList = this.Lines; if (merge) mimeStringList = Header.MergeLines(mimeStringList); } return nameLength + Header.QuoteAndFold(stream, mimeStringList, 4026531840U, false, mimeStringList.Length > 0, encodingOptions.AllowUTF8, 0, ref currentLineLength, ref scratchBuffer) + Header.WriteLineEnd(stream, ref currentLineLength); }
internal MimeStringList GetEncodedValue(EncodingOptions encodingOptions, ValueEncodingStyle encodingStyle) { if (string.IsNullOrEmpty(decodedValue)) return this.Lines; return MimeCommon.EncodeValue(decodedValue, encodingOptions, encodingStyle); }
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)); var mimeStringList = new MimeStringList(); Globalization.Charset charset; if (encodingOptions.CharsetName != null) charset = encodingOptions.GetEncodingCharset(); else { var codePageDetector = new Globalization.OutboundCodePageDetector(); codePageDetector.AddText(value); if (!Globalization.Charset.TryGetCharset(codePageDetector.GetCodePage(), out charset)) charset = DefaultEncodingOptions.GetEncodingCharset(); } var charClasses = Schema.Mime.Encoders.ByteEncoder.Tables.CharClasses.QEncode; if (style == ValueEncodingStyle.Phrase) charClasses |= Schema.Mime.Encoders.ByteEncoder.Tables.CharClasses.QPhraseUnsafe; else if (style == ValueEncodingStyle.Comment) charClasses |= Schema.Mime.Encoders.ByteEncoder.Tables.CharClasses.QCommentUnsafe; var allowQEncoding = false; CalculateMethodAndChunkSize methodAndChunkSize; if (charset.Kind == Globalization.CodePageKind.Sbcs) { methodAndChunkSize = calculateMethodAndChunkSizeSbcs; if (charset.AsciiSupport >= Globalization.CodePageAsciiSupport.Fine) allowQEncoding = true; } else if (charset.Kind == Globalization.CodePageKind.Dbcs) { methodAndChunkSize = calculateMethodAndChunkSizeDbcs; if (charset.AsciiSupport >= Globalization.CodePageAsciiSupport.Fine) allowQEncoding = true; } else if (charset.CodePage == 65001) { methodAndChunkSize = calculateMethodAndChunkSizeUtf8; allowQEncoding = true; } else { methodAndChunkSize = charset.CodePage == 1200 || charset.CodePage == 1201 ? calculateMethodAndChunkSizeUnicode16 : (charset.CodePage == 12000 || charset.CodePage == 12001 ? calculateMethodAndChunkSizeUnicode32 : calculateMethodAndChunkSizeMbcs); } var num1 = 75; var num2 = 7 + charset.Name.Length; var num3 = num1 - num2; if (num3 < 32) { num1 = num2 + 32; num3 = 32; } var byteBuffer = Internal.ScratchPad.GetByteBuffer(num3); var encoding = charset.GetEncoding(); var numArray1 = new byte[5 + charset.Name.Length]; var num4 = 0; var numArray2 = numArray1; var index1 = num4; var num5 = 1; var num6 = index1 + num5; var num7 = 61; numArray2[index1] = (byte) num7; var numArray3 = numArray1; var index2 = num6; var num8 = 1; var bytesOffset = index2 + num8; var num9 = 63; numArray3[index2] = (byte) num9; var num10 = bytesOffset + Internal.ByteString.StringToBytes(charset.Name, numArray1, bytesOffset, false); var numArray4 = numArray1; var index3 = num10; var num11 = 1; var num12 = index3 + num11; var num13 = 63; numArray4[index3] = (byte) num13; var numArray5 = numArray1; var index4 = num12; var num14 = 1; var num15 = index4 + num14; var num16 = 88; numArray5[index4] = (byte) num16; var numArray6 = numArray1; var index5 = num15; var num17 = 1; var num18 = index5 + num17; var num19 = 63; numArray6[index5] = (byte) num19; var mimeString = new MimeString(numArray1); var num20 = 0; byte[] numArray7 = null; var count = 0; var num21 = num3/4; while (num20 != value.Length) { byte method; int chunkSize; methodAndChunkSize(allowQEncoding, charClasses, encoding, value, num20, num3, out method, out chunkSize); label_25: int bytes; int outputOffset; while (true) { do { do { try { bytes = encoding.GetBytes(value, num20, chunkSize, byteBuffer, 0); } catch (System.ArgumentException ex) { if (chunkSize < 2) throw; chunkSize -= chunkSize > 10 ? 3 : 1; if (MimeCommon.IsLowSurrogate(value[num20 + chunkSize])) { if (MimeCommon.IsHighSurrogate(value[num20 + chunkSize - 1])) --chunkSize; } goto label_25; } if (bytes != 0) { if (numArray7 == null || numArray7.Length - count < num1 + 1) { if (numArray7 != null) { mimeStringList.Append(new MimeString(numArray7, 0, count)); count = 0; } numArray7 = new byte[System.Math.Min(((value.Length - num20)/chunkSize + 1)*(num1 + 1), 4096/(num1 + 1)*(num1 + 1))]; } var destinationIndex = count; if (mimeStringList.Count > 0 || destinationIndex > 0) numArray7[destinationIndex++] = 32; outputOffset = destinationIndex + mimeString.CopyTo(numArray7, destinationIndex); numArray7[outputOffset - 2] = method; if (method == 81) { var num22 = outputOffset; int index6; for (index6 = 0; index6 < bytes && outputOffset - num22 + 1 <= num3; ++index6) { var num23 = byteBuffer[index6]; if (MimeCommon.QEncodingRequired((char) num23, charClasses)) { if (outputOffset - num22 + 3 <= num3) { var numArray8 = numArray7; var index7 = outputOffset; var num24 = 1; var num25 = index7 + num24; var num26 = 61; numArray8[index7] = (byte) num26; var numArray9 = numArray7; var index8 = num25; var num27 = 1; var num28 = index8 + num27; int num29 = Schema.Mime.Encoders.ByteEncoder.NibbleToHex[num23 >> 4]; numArray9[index8] = (byte) num29; var numArray10 = numArray7; var index9 = num28; var num30 = 1; outputOffset = index9 + num30; int num31 = Schema.Mime.Encoders.ByteEncoder.NibbleToHex[num23 & 15]; numArray10[index9] = (byte) num31; } else break; } else { if (num23 == 32) num23 = 95; numArray7[outputOffset++] = num23; } } if (index6 != bytes) { if (chunkSize < 2) throw new System.InvalidOperationException("unexpected thing just happened"); chunkSize -= chunkSize > 10 ? 3 : 1; } else goto label_56; } else goto label_55; } else goto label_57; } while (!MimeCommon.IsLowSurrogate(value[num20 + chunkSize])); } while (!MimeCommon.IsHighSurrogate(value[num20 + chunkSize - 1])); --chunkSize; } label_55: outputOffset += MimeCommon.Base64EncodeChunk(byteBuffer, 0, bytes, numArray7, outputOffset); label_56: var numArray11 = numArray7; var index10 = outputOffset; var num32 = 1; var num33 = index10 + num32; var num34 = 63; numArray11[index10] = (byte) num34; var numArray12 = numArray7; var index11 = num33; var num35 = 1; var num36 = index11 + num35; var num37 = 61; numArray12[index11] = (byte) num37; count = num36; label_57: num20 += chunkSize; } if (numArray7 != null) mimeStringList.Append(new MimeString(numArray7, 0, count)); return mimeStringList; }