private static State ParseBodyPart(
            byte[] buffer,
            int bytesReady,
            ref int bytesConsumed,
            ref BodyPartState bodyPartState,
            long maximumMessageLength,
            ref long totalBytesConsumed,
            CurrentBodyPartStore currentBodyPart)
        {
            Contract.Assert((bytesReady - bytesConsumed) >= 0, "ParseBodyPart()|(bytesReady - bytesConsumed) < 0");
            Contract.Assert(maximumMessageLength <= 0 || totalBytesConsumed <= maximumMessageLength, "ParseBodyPart()|Message already read exceeds limit.");

            // Remember where we started.
            int segmentStart;
            int initialBytesParsed = bytesConsumed;

            // Set up parsing status with what will happen if we exceed the buffer.
            State parseStatus  = State.DataTooBig;
            long  effectiveMax = maximumMessageLength <= 0 ? Int64.MaxValue : (maximumMessageLength - totalBytesConsumed + bytesConsumed);

            if (bytesReady < effectiveMax)
            {
                parseStatus  = State.NeedMoreData;
                effectiveMax = bytesReady;
            }

            currentBodyPart.ResetBoundaryOffset();

            Contract.Assert(bytesConsumed < effectiveMax, "We have already consumed more than the max header length.");

            switch (bodyPartState)
            {
            case BodyPartState.BodyPart:
                while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                {
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                // Move past the CR
                bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterFirstCarriageReturn;

            case BodyPartState.AfterFirstCarriageReturn:
                if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.LF);

                // Move past the CR
                bodyPartState = BodyPartState.AfterFirstLineFeed;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterFirstLineFeed;

            case BodyPartState.AfterFirstLineFeed:
                if (buffer[bytesConsumed] == MimeMultipartParser.CR)
                {
                    // Remember potential boundary
                    currentBodyPart.ResetBoundary();
                    currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstCarriageReturn;
                }

                if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                // Move past the Dash
                bodyPartState = BodyPartState.AfterFirstDash;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterFirstDash;

            case BodyPartState.AfterFirstDash:
                if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                // Move past the Dash
                bodyPartState = BodyPartState.Boundary;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.Boundary;

            case BodyPartState.Boundary:
                segmentStart = bytesConsumed;
                while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                {
                    if (++bytesConsumed == effectiveMax)
                    {
                        currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart);
                        goto quit;
                    }
                }

                if (bytesConsumed > segmentStart)
                {
                    currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart);
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                // Move past the CR
                bodyPartState = BodyPartState.AfterSecondCarriageReturn;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterSecondCarriageReturn;

            case BodyPartState.AfterSecondCarriageReturn:
                if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.LF);

                // Move past the LF
                bytesConsumed++;

                bodyPartState = BodyPartState.BodyPart;
                if (currentBodyPart.IsBoundaryValid())
                {
                    parseStatus = State.BodyPartCompleted;
                }
                else
                {
                    currentBodyPart.ResetBoundary();
                    if (bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.BodyPart;
                }

                goto quit;
            }

quit:
            if (initialBytesParsed < bytesConsumed)
            {
                int boundaryLength = currentBodyPart.BoundaryDelta;
                if (boundaryLength > 0 && parseStatus != State.BodyPartCompleted)
                {
                    currentBodyPart.HasPotentialBoundaryLeftOver = true;
                }

                int bodyPartEnd = bytesConsumed - initialBytesParsed - boundaryLength;

                currentBodyPart.BodyPart = new ArraySegment <byte>(buffer, initialBytesParsed, bodyPartEnd);
            }

            totalBytesConsumed += bytesConsumed - initialBytesParsed;
            return(parseStatus);
        }
        private static State ParseBodyPart(
            byte[] buffer,
            int bytesReady,
            ref int bytesConsumed,
            ref BodyPartState bodyPartState,
            long maximumMessageLength,
            ref long totalBytesConsumed,
            CurrentBodyPartStore currentBodyPart)
        {
            Contract.Assert((bytesReady - bytesConsumed) >= 0, "ParseBodyPart()|(bytesReady - bytesConsumed) < 0");
            Contract.Assert(maximumMessageLength <= 0 || totalBytesConsumed <= maximumMessageLength, "ParseBodyPart()|Message already read exceeds limit.");

            // Remember where we started.
            int segmentStart;
            int initialBytesParsed = bytesConsumed;

            // Set up parsing status with what will happen if we exceed the buffer.
            State parseStatus = State.DataTooBig;
            long effectiveMax = maximumMessageLength <= 0 ? Int64.MaxValue : (maximumMessageLength - totalBytesConsumed + bytesConsumed);
            if (bytesReady < effectiveMax)
            {
                parseStatus = State.NeedMoreData;
                effectiveMax = bytesReady;
            }

            currentBodyPart.ResetBoundaryOffset();

            Contract.Assert(bytesConsumed < effectiveMax, "We have already consumed more than the max header length.");

            switch (bodyPartState)
            {
                case BodyPartState.BodyPart:
                    while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                    {
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstCarriageReturn;

                case BodyPartState.AfterFirstCarriageReturn:
                    if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.LF);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterFirstLineFeed;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstLineFeed;

                case BodyPartState.AfterFirstLineFeed:
                    if (buffer[bytesConsumed] == MimeMultipartParser.CR)
                    {
                        // Remember potential boundary
                        currentBodyPart.ResetBoundary();
                        currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                        // Move past the CR
                        bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.AfterFirstCarriageReturn;
                    }

                    if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                    // Move past the Dash
                    bodyPartState = BodyPartState.AfterFirstDash;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstDash;

                case BodyPartState.AfterFirstDash:
                    if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                    // Move past the Dash
                    bodyPartState = BodyPartState.Boundary;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.Boundary;

                case BodyPartState.Boundary:
                    segmentStart = bytesConsumed;
                    while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                    {
                        if (++bytesConsumed == effectiveMax)
                        {
                            currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart);
                            goto quit;
                        }
                    }

                    if (bytesConsumed > segmentStart)
                    {
                        currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart);
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterSecondCarriageReturn;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterSecondCarriageReturn;

                case BodyPartState.AfterSecondCarriageReturn:
                    if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.LF);

                    // Move past the LF
                    bytesConsumed++;

                    bodyPartState = BodyPartState.BodyPart;
                    if (currentBodyPart.IsBoundaryValid())
                    {
                        parseStatus = State.BodyPartCompleted;
                    }
                    else
                    {
                        currentBodyPart.ResetBoundary();
                        if (bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }

                    goto quit;
            }

        quit:
            if (initialBytesParsed < bytesConsumed)
            {
                int boundaryLength = currentBodyPart.BoundaryDelta;
                if (boundaryLength > 0 && parseStatus != State.BodyPartCompleted)
                {
                    currentBodyPart.HasPotentialBoundaryLeftOver = true;
                }

                int bodyPartEnd = bytesConsumed - initialBytesParsed - boundaryLength;

                currentBodyPart.BodyPart = new ArraySegment<byte>(buffer, initialBytesParsed, bodyPartEnd);
            }

            totalBytesConsumed += bytesConsumed - initialBytesParsed;
            return parseStatus;
        }
示例#3
0
        private static State ParseBodyPart(
            byte[] buffer,
            int bytesReady,
            ref int bytesConsumed,
            ref BodyPartState bodyPartState,
            long maximumMessageLength,
            ref long totalBytesConsumed,
            CurrentBodyPartStore currentBodyPart)
        {
            Contract.Assert((bytesReady - bytesConsumed) >= 0, "ParseBodyPart()|(bytesReady - bytesConsumed) < 0");
            Contract.Assert(maximumMessageLength <= 0 || totalBytesConsumed <= maximumMessageLength, "ParseBodyPart()|Message already read exceeds limit.");

            // Remember where we started.
            int segmentStart;
            int initialBytesParsed = bytesConsumed;

            if (bytesReady == 0 && bodyPartState == BodyPartState.AfterBoundary && currentBodyPart.IsFinal)
            {
                // We've seen the end of the stream - the final body part has no trailing CRLF
                return(State.BodyPartCompleted);
            }

            // Set up parsing status with what will happen if we exceed the buffer.
            State parseStatus  = State.DataTooBig;
            long  effectiveMax = maximumMessageLength <= 0 ? Int64.MaxValue : (maximumMessageLength - totalBytesConsumed + bytesConsumed);

            if (effectiveMax == 0)
            {
                // effectiveMax is based on our max message size - if we've arrrived at the max size, then we need
                // to stop parsing.
                return(State.DataTooBig);
            }

            if (bytesReady <= effectiveMax)
            {
                parseStatus  = State.NeedMoreData;
                effectiveMax = bytesReady;
            }

            currentBodyPart.ResetBoundaryOffset();

            Contract.Assert(bytesConsumed < effectiveMax, "We have already consumed more than the max header length.");

            switch (bodyPartState)
            {
            case BodyPartState.BodyPart:
                while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                {
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                // Move past the CR
                bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterFirstCarriageReturn;

            case BodyPartState.AfterFirstCarriageReturn:
                if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.LF);

                // Move past the CR
                bodyPartState = BodyPartState.AfterFirstLineFeed;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterFirstLineFeed;

            case BodyPartState.AfterFirstLineFeed:
                if (buffer[bytesConsumed] == MimeMultipartParser.CR)
                {
                    // Remember potential boundary
                    currentBodyPart.ResetBoundary();
                    currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstCarriageReturn;
                }

                if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                // Move past the Dash
                bodyPartState = BodyPartState.AfterFirstDash;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.AfterFirstDash;

            case BodyPartState.AfterFirstDash:
                if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    goto case BodyPartState.BodyPart;
                }

                // Remember potential boundary
                currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                // Move past the Dash
                bodyPartState = BodyPartState.Boundary;
                if (++bytesConsumed == effectiveMax)
                {
                    goto quit;
                }

                goto case BodyPartState.Boundary;

            case BodyPartState.Boundary:
                segmentStart = bytesConsumed;
                while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                {
                    if (++bytesConsumed == effectiveMax)
                    {
                        if (currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                        {
                            if (currentBodyPart.IsBoundaryComplete())
                            {
                                // At this point we've seen the end of a boundary segment that is aligned at the end
                                // of the buffer - this might be because we have another segment coming or it might
                                // truly be the end of the message.
                                bodyPartState = BodyPartState.AfterBoundary;
                            }
                        }
                        else
                        {
                            currentBodyPart.ResetBoundary();
                            bodyPartState = BodyPartState.BodyPart;
                        }
                        goto quit;
                    }
                }

                if (bytesConsumed > segmentStart)
                {
                    if (!currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }
                }

                goto case BodyPartState.AfterBoundary;

            case BodyPartState.AfterBoundary:

                // This state means that we just saw the end of a boundary. It might by a 'normal' boundary, in which
                // case it's followed by optional whitespace and a CRLF. Or it might be the 'final' boundary and will
                // be followed by '--', optional whitespace and an optional CRLF.
                if (buffer[bytesConsumed] == MimeMultipartParser.Dash && !currentBodyPart.IsFinal)
                {
                    currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);
                    if (++bytesConsumed == effectiveMax)
                    {
                        bodyPartState = BodyPartState.AfterSecondDash;
                        goto quit;
                    }

                    goto case BodyPartState.AfterSecondDash;
                }

                // Capture optional whitespace
                segmentStart = bytesConsumed;
                while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                {
                    if (++bytesConsumed == effectiveMax)
                    {
                        if (!currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                        {
                            // It's an unexpected character
                            currentBodyPart.ResetBoundary();
                            bodyPartState = BodyPartState.BodyPart;
                        }

                        goto quit;
                    }
                }

                if (bytesConsumed > segmentStart)
                {
                    if (!currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }
                }

                if (buffer[bytesConsumed] == MimeMultipartParser.CR)
                {
                    currentBodyPart.AppendBoundary(MimeMultipartParser.CR);
                    if (++bytesConsumed == effectiveMax)
                    {
                        bodyPartState = BodyPartState.AfterSecondCarriageReturn;
                        goto quit;
                    }

                    goto case BodyPartState.AfterSecondCarriageReturn;
                }
                else
                {
                    // It's an unexpected character
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    goto case BodyPartState.BodyPart;
                }

            case BodyPartState.AfterSecondDash:
                if (buffer[bytesConsumed] == MimeMultipartParser.Dash)
                {
                    currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);
                    bytesConsumed++;

                    if (currentBodyPart.IsBoundaryComplete())
                    {
                        Debug.Assert(currentBodyPart.IsFinal);

                        // If we get in here, it means we've see the trailing '--' of the last boundary - in order to consume all of the
                        // remaining bytes, we don't mark the parse as complete again - wait until this method is called again with the
                        // empty buffer to do that.
                        bodyPartState = BodyPartState.AfterBoundary;
                        parseStatus   = State.NeedMoreData;
                        goto quit;
                    }
                    else
                    {
                        currentBodyPart.ResetBoundary();
                        if (bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }
                }
                else
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    goto case BodyPartState.BodyPart;
                }

            case BodyPartState.AfterSecondCarriageReturn:
                if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                {
                    currentBodyPart.ResetBoundary();
                    bodyPartState = BodyPartState.BodyPart;
                    goto case BodyPartState.BodyPart;
                }

                currentBodyPart.AppendBoundary(MimeMultipartParser.LF);
                bytesConsumed++;

                bodyPartState = BodyPartState.BodyPart;
                if (currentBodyPart.IsBoundaryComplete())
                {
                    parseStatus = State.BodyPartCompleted;
                    goto quit;
                }
                else
                {
                    currentBodyPart.ResetBoundary();
                    if (bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.BodyPart;
                }
            }

quit:
            if (initialBytesParsed < bytesConsumed)
            {
                int boundaryLength = currentBodyPart.BoundaryDelta;
                if (boundaryLength > 0 && parseStatus != State.BodyPartCompleted)
                {
                    currentBodyPart.HasPotentialBoundaryLeftOver = true;
                }

                int bodyPartEnd = bytesConsumed - initialBytesParsed - boundaryLength;

                currentBodyPart.BodyPart = new ArraySegment <byte>(buffer, initialBytesParsed, bodyPartEnd);
            }

            totalBytesConsumed += bytesConsumed - initialBytesParsed;
            return(parseStatus);
        }
        private static State ParseBodyPart(
            byte[] buffer,
            int bytesReady,
            ref int bytesConsumed,
            ref BodyPartState bodyPartState,
            long maximumMessageLength,
            ref long totalBytesConsumed,
            CurrentBodyPartStore currentBodyPart)
        {
            Contract.Assert((bytesReady - bytesConsumed) >= 0, "ParseBodyPart()|(bytesReady - bytesConsumed) < 0");
            Contract.Assert(maximumMessageLength <= 0 || totalBytesConsumed <= maximumMessageLength, "ParseBodyPart()|Message already read exceeds limit.");

            // Remember where we started.
            int segmentStart;
            int initialBytesParsed = bytesConsumed;

            if (bytesReady == 0 && bodyPartState == BodyPartState.AfterBoundary && currentBodyPart.IsFinal)
            {
                // We've seen the end of the stream - the final body part has no trailing CRLF
                return State.BodyPartCompleted;
            }

            // Set up parsing status with what will happen if we exceed the buffer.
            State parseStatus = State.DataTooBig;
            long effectiveMax = maximumMessageLength <= 0 ? Int64.MaxValue : (maximumMessageLength - totalBytesConsumed + bytesConsumed);
            if (effectiveMax == 0)
            {
                // effectiveMax is based on our max message size - if we've arrrived at the max size, then we need
                // to stop parsing.
                return State.DataTooBig;
            }

            if (bytesReady <= effectiveMax)
            {
                parseStatus = State.NeedMoreData;
                effectiveMax = bytesReady;
            }

            currentBodyPart.ResetBoundaryOffset();

            Contract.Assert(bytesConsumed < effectiveMax, "We have already consumed more than the max header length.");

            switch (bodyPartState)
            {
                case BodyPartState.BodyPart:
                    while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                    {
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstCarriageReturn;

                case BodyPartState.AfterFirstCarriageReturn:
                    if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.LF);

                    // Move past the CR
                    bodyPartState = BodyPartState.AfterFirstLineFeed;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstLineFeed;

                case BodyPartState.AfterFirstLineFeed:
                    if (buffer[bytesConsumed] == MimeMultipartParser.CR)
                    {
                        // Remember potential boundary
                        currentBodyPart.ResetBoundary();
                        currentBodyPart.AppendBoundary(MimeMultipartParser.CR);

                        // Move past the CR
                        bodyPartState = BodyPartState.AfterFirstCarriageReturn;
                        if (++bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.AfterFirstCarriageReturn;
                    }

                    if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                    // Move past the Dash
                    bodyPartState = BodyPartState.AfterFirstDash;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.AfterFirstDash;

                case BodyPartState.AfterFirstDash:
                    if (buffer[bytesConsumed] != MimeMultipartParser.Dash)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }

                    // Remember potential boundary
                    currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);

                    // Move past the Dash
                    bodyPartState = BodyPartState.Boundary;
                    if (++bytesConsumed == effectiveMax)
                    {
                        goto quit;
                    }

                    goto case BodyPartState.Boundary;

                case BodyPartState.Boundary:
                    segmentStart = bytesConsumed;
                    while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                    {
                        if (++bytesConsumed == effectiveMax)
                        {
                            if (currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                            {
                                if (currentBodyPart.IsBoundaryComplete())
                                {
                                    // At this point we've seen the end of a boundary segment that is aligned at the end
                                    // of the buffer - this might be because we have another segment coming or it might
                                    // truly be the end of the message.
                                    bodyPartState = BodyPartState.AfterBoundary;
                                }
                            }
                            else
                            {
                                currentBodyPart.ResetBoundary();
                                bodyPartState = BodyPartState.BodyPart;
                            }
                            goto quit;
                        }
                    }
                    
                    if (bytesConsumed > segmentStart)
                    {
                        if (!currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                        {
                            currentBodyPart.ResetBoundary();
                            bodyPartState = BodyPartState.BodyPart;
                            goto case BodyPartState.BodyPart;
                        }
                    }

                    goto case BodyPartState.AfterBoundary;

                case BodyPartState.AfterBoundary:

                    // This state means that we just saw the end of a boundary. It might by a 'normal' boundary, in which
                    // case it's followed by optional whitespace and a CRLF. Or it might be the 'final' boundary and will 
                    // be followed by '--', optional whitespace and an optional CRLF.
                    if (buffer[bytesConsumed] == MimeMultipartParser.Dash && !currentBodyPart.IsFinal)
                    {
                        currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);
                        if (++bytesConsumed == effectiveMax)
                        {
                            bodyPartState = BodyPartState.AfterSecondDash;
                            goto quit;
                        }

                        goto case BodyPartState.AfterSecondDash;
                    }

                    // Capture optional whitespace
                    segmentStart = bytesConsumed;
                    while (buffer[bytesConsumed] != MimeMultipartParser.CR)
                    {
                        if (++bytesConsumed == effectiveMax)
                        {
                            if (!currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                            {
                                // It's an unexpected character
                                currentBodyPart.ResetBoundary();
                                bodyPartState = BodyPartState.BodyPart;
                            }

                            goto quit;
                        }
                    }

                    if (bytesConsumed > segmentStart)
                    {
                        if (!currentBodyPart.AppendBoundary(buffer, segmentStart, bytesConsumed - segmentStart))
                        {
                            currentBodyPart.ResetBoundary();
                            bodyPartState = BodyPartState.BodyPart;
                            goto case BodyPartState.BodyPart;
                        }
                    }

                    if (buffer[bytesConsumed] == MimeMultipartParser.CR)
                    {
                        currentBodyPart.AppendBoundary(MimeMultipartParser.CR);
                        if (++bytesConsumed == effectiveMax)
                        {
                            bodyPartState = BodyPartState.AfterSecondCarriageReturn;
                            goto quit;
                        }

                        goto case BodyPartState.AfterSecondCarriageReturn;
                    }
                    else
                    {
                        // It's an unexpected character
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }

                case BodyPartState.AfterSecondDash:
                    if (buffer[bytesConsumed] == MimeMultipartParser.Dash)
                    {
                        currentBodyPart.AppendBoundary(MimeMultipartParser.Dash);
                        bytesConsumed++;
                        
                        if (currentBodyPart.IsBoundaryComplete())
                        {
                            Debug.Assert(currentBodyPart.IsFinal);

                            // If we get in here, it means we've see the trailing '--' of the last boundary - in order to consume all of the 
                            // remaining bytes, we don't mark the parse as complete again - wait until this method is called again with the 
                            // empty buffer to do that.
                            bodyPartState = BodyPartState.AfterBoundary;
                            parseStatus = State.NeedMoreData;
                            goto quit;
                        }
                        else
                        {
                            currentBodyPart.ResetBoundary();
                            if (bytesConsumed == effectiveMax)
                            {
                                goto quit;
                            }

                            goto case BodyPartState.BodyPart;
                        }
                    }
                    else
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }

                case BodyPartState.AfterSecondCarriageReturn:
                    if (buffer[bytesConsumed] != MimeMultipartParser.LF)
                    {
                        currentBodyPart.ResetBoundary();
                        bodyPartState = BodyPartState.BodyPart;
                        goto case BodyPartState.BodyPart;
                    }

                    currentBodyPart.AppendBoundary(MimeMultipartParser.LF);
                    bytesConsumed++;

                    bodyPartState = BodyPartState.BodyPart;
                    if (currentBodyPart.IsBoundaryComplete())
                    {
                        parseStatus = State.BodyPartCompleted;
                        goto quit;
                    }
                    else
                    {
                        currentBodyPart.ResetBoundary();
                        if (bytesConsumed == effectiveMax)
                        {
                            goto quit;
                        }

                        goto case BodyPartState.BodyPart;
                    }
            }

        quit:
            if (initialBytesParsed < bytesConsumed)
            {
                int boundaryLength = currentBodyPart.BoundaryDelta;
                if (boundaryLength > 0 && parseStatus != State.BodyPartCompleted)
                {
                    currentBodyPart.HasPotentialBoundaryLeftOver = true;
                }

                int bodyPartEnd = bytesConsumed - initialBytesParsed - boundaryLength;

                currentBodyPart.BodyPart = new ArraySegment<byte>(buffer, initialBytesParsed, bodyPartEnd);
            }

            totalBytesConsumed += bytesConsumed - initialBytesParsed;
            return parseStatus;
        }