System.Net.ChunkParse.SkipPastCRLF C# (CSharp) Method

SkipPastCRLF() static private method

static private SkipPastCRLF ( IReadChunkBytes Source ) : int
Source IReadChunkBytes
return int
        SkipPastCRLF(IReadChunkBytes Source) {
            int         BytesRead;
            int         Current;
            bool        Escape;
            bool        InQS;
            bool        HaveCR;
            bool        HaveLF;

            BytesRead = 0;
            Escape = false;
            InQS = false;
            HaveCR = false;
            HaveLF = false;

            GlobalLog.Enter("SkipPastCRLF");

            // Loop through the buffer, looking at each byte. We have a
            // pseudo state machine going here, and the action we take
            // with each byte depends on the state.

            Current = Source.NextByte;
            BytesRead++;

            while (Current != -1) {

                // If we saw a CR last time, it must be followed by an unescaped
                // LF, otherwise it's an error. If it is followed by a LF, and
                // we're not in a quoted string, then we've found our termination.
                // If we are in a quoted string, this could be the start of a LWS
                // production. Remember that, and next time through we'll
                // check to make sure that this is an LWS production.

                if (HaveCR) {
                    if (Current != '\n') {
                        // CR w/o a trailing LF is an error.
                        GlobalLog.Leave("SkipPastCRLF", 0);
                        return 0;
                    }
                    else {
                        if (Escape) {
                            // We have an CR, but they're trying to escape the
                            // LF. This is an error.

                            GlobalLog.Leave("SkipPastCRLF", 0);
                            return 0;
                        }

                        // If we're not in a quoted string, we're done.

                        if (!InQS) {
                            // We've found the terminating CRLF pair.
                            GlobalLog.Leave("SkipPastCRLF", 0);
                            return BytesRead;
                        }
                        else {
                            // We're in a quoted string, so set HaveLF
                            // so we remember to check for a LWS production next
                            // time.

                            HaveLF = true;

                            // We've proceessed this byte, set Escape so we don't
                            // do it again.

                            Escape = true;
                        }
                    }

                    // We're past the CR now, don't remember it any more.

                    HaveCR = false;
                }
                else {
                    // If HaveLF is set, we must be in a quoted string and have
                    // seen a CRLF pair. Make sure this character is a space or
                    // tab.

                    if (HaveLF) {
                        // We have a LF. For this to be valid, we have to have a
                        // space or tab be the next character.

                        if (Current != ' ' && Current != '\t') {
                            // Not a continuation, so return an error.
                            GlobalLog.Leave("SkipPastCRLF", 0);
                            return 0;
                        }

                        Escape = true;  // Don't process this byte again.
                        HaveLF = false;
                    }
                }

                // If we're escaping, just skip the next character.
                if (!Escape) {
                    switch (Current) {
                        case '"':
                            if (InQS) {
                                InQS = false;
                            }
                            else {
                                InQS = true;
                            }
                            break;
                        case '\\':
                            if (InQS) {
                                Escape = true;
                            }
                            break;
                        case '\r':
                            HaveCR = true;
                            break;

                        case '\n':

                            // If we get here, we have a LF without a preceding CR.
                            // This is an error.

                            GlobalLog.Leave("SkipPastCRLF", 0);
                            return 0;

                        default:
                            break;
                    }
                }
                else {
                    // We're escaping, do nothing but rest the Escape flag.

                    Escape = false;
                }

                Current = Source.NextByte;
                BytesRead++;
            }

            // If we get here, we never saw the terminating CRLF, so return -1.

            GlobalLog.Leave("SkipPastCRLF", -1);
            return -1;
        }