Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }