⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpparser.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 5 页
字号:
*	INOUT scanner_t* scanner ;  Scanner Object											*	IN int base :				Base of number in the string; *								valid values: 10 or 16	*	OUT int* value ;			Number stored here									*																		* Description: Matches an unsigned integer value in the input. The		*	integer is returned in 'value'. Except for PARSE_OK result, the		*	scanner's cursor is moved back to its original position on error.	*																		* Returns:																*   PARSE_OK															*   PARSE_NO_MATCH		-- got different kind of token					*   PARSE_FAILURE		-- bad input									*   PARSE_INCOMPLETE													************************************************************************/static XINLINE intmatch_int( INOUT scanner_t * scanner,           IN int base,           OUT int *value ){    memptr token;    token_type_t tok_type;    parse_status_t status;    int num;    char *end_ptr;    size_t save_pos;    save_pos = scanner->cursor;    status = scanner_get_token( scanner, &token, &tok_type );    if( status == PARSE_OK ) {        if( tok_type == TT_IDENTIFIER ) {            errno = 0;            num = strtol( token.buf, &end_ptr, base );            if( ( num < 0 )                // all and only those chars in token should be used for num                || ( end_ptr != token.buf + token.length )                || ( ( num == LONG_MIN || num == LONG_MAX )                     && ( errno == ERANGE ) )                 ) {                status = PARSE_NO_MATCH;            }            *value = num;       // save result        } else {            status = PARSE_NO_MATCH;    // token must be an identifier        }    }    if( status != PARSE_OK ) {        // restore scanner position for bad values        scanner->cursor = save_pos;    }    return status;}/************************************************************************* Function: read_until_crlf												*																		* Parameters:															*	INOUT scanner_t* scanner ;	Scanner Object											*	OUT memptr* str ;			Buffer to copy scanner buffer contents to*																		* Description: Reads data until end of line; the crlf at the end of		*	line is not consumed. On error, scanner is not restored. On			*	success, 'str' points to a string that runs until eol				*																		* Returns:																*   PARSE_OK															*   PARSE_FAILURE														*   PARSE_INCOMPLETE													************************************************************************/static XINLINE intread_until_crlf( INOUT scanner_t * scanner,                 OUT memptr * str ){    memptr token;    token_type_t tok_type;    parse_status_t status;    size_t start_pos;    start_pos = scanner->cursor;    str->buf = scanner_get_str( scanner );    // read until we hit a crlf    do {        status = scanner_get_token( scanner, &token, &tok_type );    } while( status == PARSE_OK && tok_type != TT_CRLF );    if( status == PARSE_OK ) {        // pushback crlf in stream        scanner->cursor -= token.length;        // str should include all strings except crlf at the end        str->length = scanner->cursor - start_pos;    }    return status;}/************************************************************************* Function: skip_to_end_of_header										*																		* Parameters:															*	INOUT scanner_t* scanner ; Scanner Object*																		* Description: Skip to end of header									*																		* Returns:																*   PARSE_OK															*   PARSE_FAILURE														*   PARSE_INCOMPLETE													************************************************************************/static XINLINE intskip_to_end_of_header( INOUT scanner_t * scanner ){    memptr dummy_raw_value;    parse_status_t status;    status = match_raw_value( scanner, &dummy_raw_value );    return status;}/************************************************************************* Function: match_char													*																		* Parameters:															*	INOUT scanner_t* scanner ;  Scanner Object											*	IN char c ;					Character to be compared with 															*	IN xboolean case_sensitive; Flag indicating whether comparison should *								be case sensitive*																		* Description: Compares a character to the next char in the scanner;	*	on error, scanner chars are not restored							*																		* Returns:																*   PARSE_OK															*   PARSE_NO_MATCH														*   PARSE_INCOMPLETE													************************************************************************/static XINLINE parse_status_tmatch_char( INOUT scanner_t * scanner,            IN char c,            IN xboolean case_sensitive ){    char scan_char;    if( scanner->cursor >= scanner->msg->length ) {        return PARSE_INCOMPLETE;    }    // read next char from scanner    scan_char = scanner->msg->buf[scanner->cursor++];    if( case_sensitive ) {        return c == scan_char ? PARSE_OK : PARSE_NO_MATCH;    } else {        return tolower( c ) == tolower( scan_char ) ?            PARSE_OK : PARSE_NO_MATCH;    }}////////////////////////////////////////////////////////////////////////// args for ...//   %d,    int *     (31-bit positive integer)//   %x,    int *     (31-bit postive number encoded as hex)//   %s,    memptr*  (simple identifier)//   %q,    memptr*  (quoted string)//   %S,    memptr*  (non-whitespace string)//   %R,    memptr*  (raw value)//   %U,    uri_type* (url)//   %L,    memptr*  (string until end of line)//   %P,    int * (current index of the string being scanned)//// no args for//   ' '    LWS*//   \t     whitespace//   "%%"   matches '%'//   "% "   matches ' '//   %c     matches CRLF//   %i     ignore case in literal matching//   %n     case-sensitive matching in literals//   %w     optional whitespace; (similar to '\t', //                  except whitespace is optional)//   %0     (zero) match null-terminator char '\0' //              (can only be used as last char in fmt)//              use only in matchstr(), not match()//   other chars match literally//// returns://   PARSE_OK//   PARSE_INCOMPLETE//   PARSE_FAILURE      -- bad input//   PARSE_NO_MATCH     -- input does not match pattern/*************************************************************************	Function :	vfmatch**	Parameters :*		INOUT scanner_t* scanner ;  Scanner Object	*		IN const char* fmt ;		Pattern Format *		va_list argp ;				List of variable arguments**	Description :	Extracts variable parameters depending on the passed *		in format parameter. Parses data also based on the passed in *		format parameter.**	Return : int ;*		PARSE_OK*		PARSE_INCOMPLETE*		PARSE_FAILURE		- bad input*		PARSE_NO_MATCH		- input does not match pattern**	Note :************************************************************************/static intvfmatch( INOUT scanner_t * scanner,         IN const char *fmt,         va_list argp ){    char c;    const char *fmt_ptr = fmt;    parse_status_t status;    memptr *str_ptr;    memptr temp_str;    int *int_ptr;    uri_type *uri_ptr;    size_t save_pos;    int stat;    xboolean case_sensitive = TRUE;    memptr token;    token_type_t tok_type;    int base;    assert( scanner != NULL );    assert( fmt != NULL );    // save scanner pos; to aid error recovery    save_pos = scanner->cursor;    status = PARSE_OK;    while( ( ( c = *fmt_ptr++ ) != 0 ) && ( status == PARSE_OK )         ) {        if( c == '%' ) {            c = *fmt_ptr++;            switch ( c ) {                case 'R':      // raw value                    str_ptr = va_arg( argp, memptr * );                    assert( str_ptr != NULL );                    status = match_raw_value( scanner, str_ptr );                    break;                case 's':      // simple identifier                    str_ptr = va_arg( argp, memptr * );                    assert( str_ptr != NULL );                    status = scanner_get_token( scanner, str_ptr,                                                &tok_type );                    if( status == PARSE_OK && tok_type != TT_IDENTIFIER ) {                        // not an identifier                        status = PARSE_NO_MATCH;                    }                    break;                case 'c':      // crlf                    status = scanner_get_token( scanner,                                                &token, &tok_type );                    if( status == PARSE_OK && tok_type != TT_CRLF ) {                        // not CRLF token                        status = PARSE_NO_MATCH;                    }                    break;                case 'd':      // integer                case 'x':      // hex number                    int_ptr = va_arg( argp, int * );                    assert( int_ptr != NULL );                    base = ( c == 'd' ? 10 : 16 );                    status = match_int( scanner, base, int_ptr );                    break;                case 'S':      // non-whitespace string                case 'U':      // uri                    if( c == 'S' ) {                        str_ptr = va_arg( argp, memptr * );                    } else {                        str_ptr = &temp_str;                    }                    assert( str_ptr != NULL );                    status = match_non_ws_string( scanner, str_ptr );                    if( c == 'U' && status == PARSE_OK ) {                        uri_ptr = va_arg( argp, uri_type * );                        assert( uri_ptr != NULL );                        stat = parse_uri( str_ptr->buf, str_ptr->length,                                          uri_ptr );                        if( stat != HTTP_SUCCESS ) {                            status = PARSE_NO_MATCH;                        }                    }                    break;                case 'L':      // string till eol                    str_ptr = va_arg( argp, memptr * );                    assert( str_ptr != NULL );                    status = read_until_crlf( scanner, str_ptr );                    break;                case ' ':      // match space                case '%':      // match percentage symbol                    status = match_char( scanner, c, case_sensitive );                    break;                case 'n':      // case-sensitive match                    case_sensitive = TRUE;                    break;                case 'i':      // ignore case                    case_sensitive = FALSE;                    break;                case 'q':      // quoted string                    str_ptr = ( memptr * ) va_arg( argp, memptr * );                    status =                        scanner_get_token( scanner, str_ptr, &tok_type );                    if( status == PARSE_OK && tok_type != TT_QUOTEDSTRING ) {                        status = PARSE_NO_MATCH;    // not a quoted string                    }                    break;                case 'w':      // optional whitespace                    status = scanner_get_token( scanner,                                                &token, &tok_type );                    if( status == PARSE_OK && tok_type != TT_WHITESPACE ) {                        // restore non-whitespace token                        scanner->cursor -= token.length;                    }                    break;                case 'P':      // current pos of scanner                    int_ptr = va_arg( argp, int * );                    assert( int_ptr != NULL );                    *int_ptr = scanner->cursor;                    break;                    // valid only in matchstr()                case '0':      // end of msg?                    // check that we are 1 beyond last char                    if( scanner->cursor == scanner->msg->length &&                        scanner->msg->buf[scanner->cursor] == '\0' ) {                        status = PARSE_OK;                    } else {                        status = PARSE_NO_MATCH;                    }                    break;                default:                    assert( 0 );    // unknown option            }        } else {            switch ( c ) {                case ' ':      // LWS*                    status = skip_lws( scanner );                    break;                case '\t':     // Whitespace                    status = scanner_get_token( scanner,                                                &token, &tok_type );                    if( status == PARSE_OK && tok_type != TT_WHITESPACE ) {                        // not whitespace token                        status = PARSE_NO_MATCH;                    }                    break;                default:       // match characters                    {                        status = match_char( scanner, c, case_sensitive );                    }            }        }    }    if( status != PARSE_OK ) {        // on error, restore original scanner pos        scanner->cursor = save_pos;    }    return status;}/************************************************************************* Function: match														*																		* Parameters:															*	INOUT scanner_t* scanner ; Scanner Object											*	IN const char* fmt;			Pattern format													*	...																	*																		* Description: matches a variable parameter list and takes necessary	*	actions based on the data type specified.							*																		* Returns:																*   PARSE_OK															*   PARSE_NO_MATCH														*   PARSE_INCOMPLETE													************************************************************************/static intmatch( INOUT scanner_t * scanner,       IN const char *fmt,       ... ){    int ret_code;    va_list args;    va_start( args, fmt );    ret_code = vfmatch( scanner, fmt, args );    va_end( args );    return ret_code;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -