internal static long QuoteAndFold(Stream stream, MimeStringList fragments, uint inputMask, bool quoteOutput, bool addSpaceAtStart, bool allowUTF8, int lastLineReserve, ref MimeStringLength currentLineLength, ref byte[] scratchBuffer) { long num = 0L; Header.LineBuffer lineBuffer = default(Header.LineBuffer); lineBuffer.Length = new MimeStringLength(0); lineBuffer.LengthTillLastLWSP = new MimeStringLength(-1); if (scratchBuffer == null || scratchBuffer.Length < 998) { scratchBuffer = new byte[998]; } lineBuffer.Bytes = scratchBuffer; MimeScan.Token token = quoteOutput ? (MimeScan.Token.Spec | MimeScan.Token.Fwsp) : MimeScan.Token.Fwsp; bool flag = false; if (addSpaceAtStart && currentLineLength.InBytes != 0) { num += Header.WriteToken(Header.Space, 0, new MimeStringLength(1), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); flag = true; } if (quoteOutput) { num += Header.WriteToken(Header.DoubleQuote, 0, new MimeStringLength(1), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); } for (int i = 0; i < fragments.Count; i++) { MimeString mimeString = fragments[i]; int num2 = 0; int num3 = 0; byte[] data = mimeString.GetData(out num2, out num3); if ((mimeString.Mask & inputMask) != 0U) { do { int valueInChars = 0; int num4 = MimeScan.FindNextOf(token, data, num2, num3, out valueInChars, allowUTF8); if (num4 > 0) { num += Header.WriteToken(data, num2, new MimeStringLength(valueInChars, num4), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); num2 += num4; num3 -= num4; } if (num3 != 0) { byte b = data[num2]; if ((b == 34 || b == 92) && (mimeString.Mask & 3758096383U) != 0U) { num += Header.WriteToken(new byte[] { 92, data[num2] }, 0, new MimeStringLength(2), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); num2++; num3--; } else { num += Header.WriteToken(new byte[] { data[num2] }, 0, new MimeStringLength(1), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); num2++; num3--; } } }while (num3 != 0); } } if (quoteOutput) { num += Header.WriteToken(Header.DoubleQuote, 0, new MimeStringLength(1), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); } if (lastLineReserve > 0) { num += Header.WriteToken(null, 0, new MimeStringLength(lastLineReserve), stream, ref currentLineLength, ref lineBuffer, ref flag, allowUTF8); } if (lineBuffer.Length.InBytes > 0) { stream.Write(lineBuffer.Bytes, 0, lineBuffer.Length.InBytes); num += (long)lineBuffer.Length.InBytes; currentLineLength.IncrementBy(lineBuffer.Length); } return(num); }
private static long WriteToken(byte[] token, int tokenOffset, MimeStringLength tokenLength, Stream stream, ref MimeStringLength currentLineLength, ref Header.LineBuffer lineBuffer, ref bool autoAddedLastLWSP, bool allowUTF8) { long num = 0L; bool flag = token != null && tokenLength.InChars == 1 && MimeScan.IsFWSP(token[tokenOffset]); if (!flag && currentLineLength.InChars + lineBuffer.Length.InChars + tokenLength.InChars > 78 && lineBuffer.LengthTillLastLWSP.InBytes >= 0) { if (lineBuffer.LengthTillLastLWSP.InBytes > 0) { stream.Write(lineBuffer.Bytes, 0, lineBuffer.LengthTillLastLWSP.InBytes); num += (long)lineBuffer.LengthTillLastLWSP.InBytes; currentLineLength.IncrementBy(lineBuffer.LengthTillLastLWSP); } if (currentLineLength.InBytes > 0) { num += Header.WriteLineEnd(stream, ref currentLineLength); } if (autoAddedLastLWSP) { autoAddedLastLWSP = false; lineBuffer.LengthTillLastLWSP.IncrementBy(1); } if (lineBuffer.LengthTillLastLWSP.InBytes != lineBuffer.Length.InBytes) { Buffer.BlockCopy(lineBuffer.Bytes, lineBuffer.LengthTillLastLWSP.InBytes, lineBuffer.Bytes, 0, lineBuffer.Length.InBytes - lineBuffer.LengthTillLastLWSP.InBytes); lineBuffer.Length.DecrementBy(lineBuffer.LengthTillLastLWSP); if (lineBuffer.Length.InBytes > 0 && MimeScan.IsFWSP(lineBuffer.Bytes[0])) { lineBuffer.LengthTillLastLWSP.SetAs(0); } else { lineBuffer.LengthTillLastLWSP.SetAs(-1); } } else { lineBuffer.Length.SetAs(0); lineBuffer.LengthTillLastLWSP.SetAs(-1); } bool flag2 = false; if (lineBuffer.Length.InBytes > 0) { if (!MimeScan.IsFWSP(lineBuffer.Bytes[0])) { flag2 = true; } } else if (!flag) { flag2 = true; } if (flag2) { stream.Write(Header.LineStartWhitespace, 0, Header.LineStartWhitespace.Length); num += (long)Header.LineStartWhitespace.Length; currentLineLength.IncrementBy(Header.LineStartWhitespace.Length); } } if (currentLineLength.InBytes + lineBuffer.Length.InBytes + tokenLength.InBytes > 998) { if (lineBuffer.Length.InBytes > 0) { stream.Write(lineBuffer.Bytes, 0, lineBuffer.Length.InBytes); num += (long)lineBuffer.Length.InBytes; currentLineLength.IncrementBy(lineBuffer.Length); lineBuffer.Length.SetAs(0); autoAddedLastLWSP = false; lineBuffer.LengthTillLastLWSP.SetAs(-1); } if (token != null) { while (currentLineLength.InBytes + tokenLength.InBytes > 998) { int num2 = Math.Max(0, 998 - currentLineLength.InBytes); int num3 = 0; int num4 = 0; if (allowUTF8) { int num5; for (int i = 0; i < tokenLength.InBytes; i += num5) { byte b = token[tokenOffset + i]; num5 = 1; if (b >= 128 && !MimeScan.IsUTF8NonASCII(token, tokenOffset + i, tokenOffset + tokenLength.InBytes, out num5)) { num5 = 1; } if (num4 + num5 > num2) { break; } num3++; num4 += num5; } } else { num3 = num2; num4 = num2; } stream.Write(token, tokenOffset, num4); num += (long)num4; currentLineLength.IncrementBy(num3, num4); tokenOffset += num4; tokenLength.DecrementBy(num3, num4); num += Header.WriteLineEnd(stream, ref currentLineLength); if (!flag) { stream.Write(Header.LineStartWhitespace, 0, Header.LineStartWhitespace.Length); num += (long)Header.LineStartWhitespace.Length; currentLineLength.IncrementBy(Header.LineStartWhitespace.Length); } } } } if (token != null) { Buffer.BlockCopy(token, tokenOffset, lineBuffer.Bytes, lineBuffer.Length.InBytes, tokenLength.InBytes); if (flag && (lineBuffer.Length.InBytes == 0 || !MimeScan.IsFWSP(lineBuffer.Bytes[lineBuffer.Length.InBytes - 1]))) { autoAddedLastLWSP = false; lineBuffer.LengthTillLastLWSP.SetAs(lineBuffer.Length); } lineBuffer.Length.IncrementBy(tokenLength); } return(num); }