StringParser详解

static char* string1 = "RTSP 200 OK\r\nContent-Type: MeowMix\r\n\t   \n3450";

		StrPtrLen theString(string1, strlen(string1));

		StringParser victim(&theString);

		StrPtrLen rtsp;
		SInt32 theInt = victim.ConsumeInteger();
		if (theInt != 0)
			return false;
		victim.ConsumeWord(&rtsp);
		if ((rtsp.Len != 4) && (strncmp(rtsp.Ptr, "RTSP", 4) != 0))
			return false;

		victim.ConsumeWhitespace();
		theInt = victim.ConsumeInteger();
		if (theInt != 200)
			return false;

		return true;

/*
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 *
 */
/*
    File:       StringParser.h

    Contains:   A couple of handy utilities for parsing a stream.  
                    
    

*/


#ifndef __STRINGPARSER_H__
#define __STRINGPARSER_H__

#include "StrPtrLen.h"
#include "MyAssert.h"

#define STRINGPARSERTESTING 0


class StringParser
{
    public:
        
        StringParser(StrPtrLen *inStream)
            :   fStartGet(inStream == NULL ? NULL : inStream->Ptr),
                fEndGet(inStream == NULL ? NULL : inStream->Ptr + inStream->Len),
                fCurLineNumber(1),
                fStream(inStream) {}
        ~StringParser() {}
        
        // Built-in masks for common stop conditions
        static UInt8 sDigitMask[];      // stop when you hit a digit
        static UInt8 sWordMask[];       // stop when you hit a word
        static UInt8 sEOLMask[];        // stop when you hit an eol
        static UInt8 sEOLWhitespaceMask[]; // stop when you hit an EOL or whitespace
        static UInt8 sWhitespaceMask[]; // skip over whitespace

        //GetBuffer:
        //Returns a pointer to the string object
        StrPtrLen*      GetStream() { return fStream; }
        

		//判断当前字符是否是stopChar,如果是,则向后跳过一个字符
        Bool16          Expect(char stopChar);
		//如果当前字符是\r (alone), \n (alone), \r\n,跳过
        Bool16          ExpectEOL();
        
        //Returns the next word
        void            ConsumeWord(StrPtrLen* outString = NULL)
                            { ConsumeUntil(outString, sNonWordMask); }

		//判断当前字符是否是inStopChar,如果不是则向后跳过一个字符,直到等于inStopChar为止,
		//截取跳过的这段字符赋值给outString(不为空时)。
        void            ConsumeUntil(StrPtrLen* outString, char inStopChar);

		//截取当前位置的整数保存到outString,函数返回整数值
		//跳过当前字符开始的数字保存到outString(判断当前字符是否是数字,是则判断下一个字符,直到不是为止,
		//将其保存到outString)函数返回该数字
        UInt32          ConsumeInteger(StrPtrLen* outString = NULL);
		//取当前位置的float保存到outString,函数返回float
        Float32         ConsumeFloat();

        Float32         ConsumeNPT();

        //Keeps on going until non-whitespace
        void            ConsumeWhitespace()
                            { ConsumeUntil(NULL, sWhitespaceMask); }
        
        //Assumes 'stop' is a 255-char array of booleans. Set this array
        //to a mask of what the stop characters are. true means stop character.
        //You may also pass in one of the many prepackaged masks defined above.
        void            ConsumeUntil(StrPtrLen* spl, UInt8 *stop);


        //+ rt 8.19.99
        //returns whatever is avaliable until non-whitespace
        void            ConsumeUntilWhitespace(StrPtrLen* spl = NULL)
                            { ConsumeUntil( spl, sEOLWhitespaceMask); }

        void            ConsumeUntilDigit(StrPtrLen* spl = NULL)
                            { ConsumeUntil( spl, sDigitMask); }

		void			ConsumeLength(StrPtrLen* spl, SInt32 numBytes);

		void			ConsumeEOL(StrPtrLen* outString);

        //GetThru:
        //Works very similar to ConsumeUntil except that it moves past the stop token,
        //and if it can't find the stop token it returns false
        inline Bool16       GetThru(StrPtrLen* spl, char stop);
        inline Bool16       GetThruEOL(StrPtrLen* spl);
        inline Bool16       ParserIsEmpty(StrPtrLen* outString);
        //Returns the current character, doesn't move past it.
        inline char     PeekFast() { if (fStartGet) return *fStartGet; else return '\0'; }
        char operator[](int i) { Assert((fStartGet+i) < fEndGet);return fStartGet[i]; }
        
        //Returns some info about the stream
        UInt32          GetDataParsedLen() 
            { Assert(fStartGet >= fStream->Ptr); return (UInt32)(fStartGet - fStream->Ptr); }
        UInt32          GetDataReceivedLen()
            { Assert(fEndGet >= fStream->Ptr); return (UInt32)(fEndGet - fStream->Ptr); }
        UInt32          GetDataRemaining()
            { Assert(fEndGet >= fStartGet); return (UInt32)(fEndGet - fStartGet); }
        char*           GetCurrentPosition() { return fStartGet; }
        int         GetCurrentLineNumber() { return fCurLineNumber; }
        
        // A utility for extracting quotes from the start and end of a parsed
        // string. (Warning: Do not call this method if you allocated your own  
        // pointer for the Ptr field of the StrPtrLen class.) - [sfu]
        // 
        // Not sure why this utility is here and not in the StrPtrLen class - [jm]
        static void UnQuote(StrPtrLen* outString);


#if STRINGPARSERTESTING
        static Bool16       Test();
#endif

    private:

		//向前移动一个字符
        void        AdvanceMark();
        
        //built in masks for some common stop conditions
        static UInt8 sNonWordMask[];

        char*       fStartGet;
        char*       fEndGet;
        int         fCurLineNumber;
        StrPtrLen*  fStream;
        
};


Bool16 StringParser::GetThru(StrPtrLen* outString, char inStopChar)
{
    ConsumeUntil(outString, inStopChar);
    return Expect(inStopChar);
}

Bool16 StringParser::GetThruEOL(StrPtrLen* outString)
{
    ConsumeUntil(outString, sEOLMask);
    return ExpectEOL();
}

Bool16 StringParser::ParserIsEmpty(StrPtrLen* outString)
{
    if (NULL == fStartGet || NULL == fEndGet)
    {
        if (NULL != outString)
        {   outString->Ptr = NULL;
            outString->Len = 0;
        }
        
        return true;
    }
    
    Assert(fStartGet <= fEndGet);
    
    return false; // parser ok to parse
}


#endif // __STRINGPARSER_H__




/*
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 *
 */
/*
    File:       StringParser.cpp

    Contains:   Implementation of StringParser class.  
                    
    
    
*/

#include "StringParser.h"

UInt8 StringParser::sNonWordMask[] =
{
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //0-9 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //10-19 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //20-29
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //30-39 
    1, 1, 1, 1, 1, 0, 1, 1, 1, 1, //40-49 - is a word
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //50-59
    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, //60-69 //stop on every character except a letter
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
    0, 1, 1, 1, 1, 0, 1, 0, 0, 0, //90-99 _ is a word
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, //120-129
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //130-139
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //140-149
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //150-159
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //160-169
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //170-179
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //180-189
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //190-199
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //200-209
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //210-219
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //220-229
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //230-239
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //240-249
    1, 1, 1, 1, 1, 1             //250-255
};

UInt8 StringParser::sWordMask[] =
{
    // Inverse of the above
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-9 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-19 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30-39 
    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, //40-49 - is a word
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-59
    0, 0, 0, 0, 0, 1, 1, 1, 1, 1, //60-69 //stop on every character except a letter
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //70-79
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //80-89
    1, 0, 0, 0, 0, 1, 0, 1, 1, 1, //90-99 _ is a word
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //100-109
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //110-119
    1, 1, 1, 0, 0, 0, 0, 0, 0, 0, //120-129
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
    0, 0, 0, 0, 0, 0             //250-255
};

UInt8 StringParser::sDigitMask[] =
{
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-9
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10-19 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30-39
    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, //40-49 //stop on every character except a number
    1, 1, 1, 1, 1, 1, 1, 1, 0, 0, //50-59
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //60-69 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //90-99
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
    0, 0, 0, 0, 0, 0             //250-255
};

UInt8 StringParser::sEOLMask[] =
{
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0-9   
    1, 0, 0, 1, 0, 0, 0, 0, 0, 0, //10-19    //'\r' & '\n' are stop conditions
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30-39 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-49
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-59
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //60-69  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //90-99
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
    0, 0, 0, 0, 0, 0             //250-255
};

UInt8 StringParser::sWhitespaceMask[] =
{
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, //0-9      // stop on '\t'
    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, //10-19    // '\r', \v', '\f' & '\n'
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //20-29
    1, 1, 0, 1, 1, 1, 1, 1, 1, 1, //30-39   //  ' '
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //40-49
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //50-59
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //60-69
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //70-79
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //80-89
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //90-99
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //100-109
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //110-119
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //120-129
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //130-139
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //140-149
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //150-159
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //160-169
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //170-179
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //180-189
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //190-199
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //200-209
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //210-219
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //220-229
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //230-239
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //240-249
    1, 1, 1, 1, 1, 1             //250-255
};

UInt8 StringParser::sEOLWhitespaceMask[] =
{
    0, 0, 0, 0, 0, 0, 0, 0, 0, 1, //0-9     // \t is a stop
    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, //10-19    //'\r' & '\n' are stop conditions
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20-29
    0, 0, 1, 0, 0, 0, 0, 0, 0, 0, //30-39   ' '  is a stop
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40-49
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //50-59
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //60-69  
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //90-99
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //120-129
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //130-139
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140-149
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150-159
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160-169
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170-179
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180-189
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190-199
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200-209
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210-219
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220-229
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230-239
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240-249
    0, 0, 0, 0, 0, 0             //250-255
};



void StringParser::ConsumeUntil(StrPtrLen* outString, char inStop)
{
    if (this->ParserIsEmpty(outString))
        return;

    char *originalStartGet = fStartGet;

    while ((fStartGet < fEndGet) && (*fStartGet != inStop))
        AdvanceMark();
        
    if (outString != NULL)
    {
        outString->Ptr = originalStartGet;
        outString->Len = fStartGet - originalStartGet;
    }
}

void StringParser::ConsumeUntil(StrPtrLen* outString, UInt8 *inMask)
{
    if (this->ParserIsEmpty(outString))
        return;
        
    char *originalStartGet = fStartGet;

    while ((fStartGet < fEndGet) && (!inMask[(unsigned char) (*fStartGet)]))
        AdvanceMark();

    if (outString != NULL)
    {
        outString->Ptr = originalStartGet;
        outString->Len = fStartGet - originalStartGet;
    }
}

void StringParser::ConsumeLength(StrPtrLen* spl, SInt32 inLength)
{
    if (this->ParserIsEmpty(spl))
        return;

    //sanity check to make sure we aren't being told to run off the end of the
    //buffer
    if ((fEndGet - fStartGet) < inLength)
        inLength = fEndGet - fStartGet;
    
    if (spl != NULL)
    {
        spl->Ptr = fStartGet;
        spl->Len = inLength;
    }
    if (inLength > 0)
    {
        for (short i=0; i<inLength; i++)
            AdvanceMark();
    }
    else
        fStartGet += inLength;  // ***may mess up line number if we back up too much
}


UInt32 StringParser::ConsumeInteger(StrPtrLen* outString)
{
    if (this->ParserIsEmpty(outString))
        return 0;

    UInt32 theValue = 0;
    char *originalStartGet = fStartGet;
    
    while ((fStartGet < fEndGet) && (*fStartGet >= '0') && (*fStartGet <= '9'))
    {
        theValue = (theValue * 10) + (*fStartGet - '0');
        AdvanceMark();
    }

    if (outString != NULL)
    {
        outString->Ptr = originalStartGet;
        outString->Len = fStartGet - originalStartGet;
    }
    return theValue;
}

Float32 StringParser::ConsumeFloat()
{
    if (this->ParserIsEmpty(NULL))
        return 0.0;

    Float32 theFloat = 0;
    while ((fStartGet < fEndGet) && (*fStartGet >= '0') && (*fStartGet <= '9'))
    {
        theFloat = (theFloat * 10) + (*fStartGet - '0');
        AdvanceMark();
    }
    if ((fStartGet < fEndGet) && (*fStartGet == '.'))
        AdvanceMark();
    Float32 multiplier = (Float32) .1;
    while ((fStartGet < fEndGet) && (*fStartGet >= '0') && (*fStartGet <= '9'))
    {
        theFloat += (multiplier * (*fStartGet - '0'));
        multiplier *= (Float32).1;

        AdvanceMark();
    }
    return theFloat;
}

Float32 StringParser::ConsumeNPT()
{
    if (this->ParserIsEmpty(NULL))
	    return 0.0;

    Float32 valArray[4] = {0, 0, 0, 0};
    Float32 divArray[4] = {1, 1, 1, 1};
    UInt32 valType = 0; // 0 == npt-sec, 1 == npt-hhmmss
    UInt32 index;
    
    for (index = 0; index < 4; index ++)
    {
        while ((fStartGet < fEndGet) && (*fStartGet >= '0') && (*fStartGet <= '9'))
        {
            valArray[index] = (valArray[index] * 10) + (*fStartGet - '0');
            divArray[index] *= 10;
            AdvanceMark();
        }
        
        if (fStartGet >= fEndGet || valType == 0 && index >= 1)
            break;
            
        if (*fStartGet == '.' && valType == 0 && index == 0)
            ;
        else if (*fStartGet == ':' && index < 2)
            valType = 1;
        else if (*fStartGet == '.' && index == 2)
            ;
        else
            break;
        AdvanceMark();
    }
    
    if (valType == 0)
        return valArray[0] + (valArray[1] / divArray[1]);
    else
        return (valArray[0] * 3600) + (valArray[1] * 60) + valArray[2] + (valArray[3] / divArray[3]);
}
Bool16  StringParser::Expect(char stopChar)
{
    if (this->ParserIsEmpty(NULL))
        return false;

    if (fStartGet >= fEndGet)
        return false;
    if(*fStartGet != stopChar)
        return false;
    else
    {
        AdvanceMark();
        return true;
    }
}
Bool16 StringParser::ExpectEOL()
{
    if (this->ParserIsEmpty(NULL))
        return false;

    //This function processes all legal forms of HTTP / RTSP eols.
    //They are: \r (alone), \n (alone), \r\n
    Bool16 retVal = false;
    if ((fStartGet < fEndGet) && ((*fStartGet == '\r') || (*fStartGet == '\n')))
    {
        retVal = true;
        AdvanceMark();
        //check for a \r\n, which is the most common EOL sequence.
        if ((fStartGet < fEndGet) && ((*(fStartGet - 1) == '\r') && (*fStartGet == '\n')))
            AdvanceMark();
    }
    return retVal;
}

void StringParser::ConsumeEOL(StrPtrLen* outString)
{
    if (this->ParserIsEmpty(outString))
        return;

	//This function processes all legal forms of HTTP / RTSP eols.
	//They are: \r (alone), \n (alone), \r\n
	char *originalStartGet = fStartGet;
	
	if ((fStartGet < fEndGet) && ((*fStartGet == '\r') || (*fStartGet == '\n')))
	{
		AdvanceMark();
		//check for a \r\n, which is the most common EOL sequence.
		if ((fStartGet < fEndGet) && ((*(fStartGet - 1) == '\r') && (*fStartGet == '\n')))
			AdvanceMark();
	}

	if (outString != NULL)
	{
		outString->Ptr = originalStartGet;
		outString->Len = fStartGet - originalStartGet;
	}
}

void StringParser::UnQuote(StrPtrLen* outString)
{
    // If a string is contained within double or single quotes 
    // then UnQuote() will remove them. - [sfu]
    
    // sanity check
    if (outString->Ptr == NULL || outString->Len < 2)
        return;
        
    // remove begining quote if it's there.
    if (outString->Ptr[0] == '"' || outString->Ptr[0] == '\'')
    {
        outString->Ptr++; outString->Len--;
    }
    // remove ending quote if it's there.
    if ( outString->Ptr[outString->Len-1] == '"' || 
         outString->Ptr[outString->Len-1] == '\'' )
    {
        outString->Len--;
    }
}

void StringParser::AdvanceMark()
{
     if (this->ParserIsEmpty(NULL))
        return;

   if ((*fStartGet == '\n') || ((*fStartGet == '\r') && (fStartGet[1] != '\n')))
    {
        // we are progressing beyond a line boundary (don't count \r\n twice)
        fCurLineNumber++;
    }
    fStartGet++;
}

#if STRINGPARSERTESTING
Bool16 StringParser::Test()
{
    static char* string1 = "RTSP 200 OK\r\nContent-Type: MeowMix\r\n\t   \n3450";
    
    StrPtrLen theString(string1, strlen(string1));
    
    StringParser victim(&theString);
    
    StrPtrLen rtsp;
    SInt32 theInt = victim.ConsumeInteger();
    if (theInt != 0)
        return false;
    victim.ConsumeWord(&rtsp);
    if ((rtsp.len != 4) && (strncmp(rtsp.Ptr, "RTSP", 4) != 0))
        return false;
        
    victim.ConsumeWhiteSpace();
    theInt = victim.ConsumeInteger();
    if (theInt != 200)
        return false;
        
    return true;
}
#endif



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaopengsun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值