📄 parseutil.cpp
字号:
} HttpHeaderValue* data; data = (HttpHeaderValue *) node->data; data->toString( s ); node = list.next( node ); }}// can't include ctype.h because of a xerces bugstatic bool IsAlpha( char c ){ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');}// returns true if the tag matches language tag syntax// (1*8ALPHA * ("-" 1*8ALPHA)) | *static bool ValidLanguageTag( const char* tag ){ int i; char c; int count; if ( strcmp(tag, "*") == 0 ) { return true; } i = 0; while ( true ) { // match 1..8 alpha for ( count = 0; count < 8; count++ ) { c = tag[i++]; if ( !IsAlpha(c) ) { if ( count == 0 ) { return false; // no alpha found } i--; // put back char break; // okay; valid alpha str } } c = tag[i++]; if ( c == '\0' ) { return true; // end of valid tag } if ( c != '-' ) { return false; // expected '-' } } return false; // this line never executes}// parses a header from input stream; returns header type and// and value// on success: headerID > 0 and returnValue != NULL// headerID == -1 and returnValue = UnknownHeader// on failure: returnValue == NULLstatic HttpHeaderValue* ParseHeader( IN Tokenizer& scanner, OUT int& headerID ){ int id; Token* token; xstring name; // read header name ParseHeaderName( scanner, name ); // map name to id id = NameToID( name.c_str(), HeaderNameTable, NUM_HEADERS, false ); if ( id < 0 ) { // header type currently not known; process raw id = HDR_UNKNOWN; scanner.pushBack(); // return unknown header name } // skip past colon; if ( id != HDR_UNKNOWN ) { SkipColonLWS( scanner ); } // now pointing at first non-whitespace token after colon HttpHeaderValue *header = NULL; switch ( id ) { case HDR_ACCEPT: header = new CommaSeparatedList( true, CreateMediaRange ); break; case HDR_ACCEPT_CHARSET: case HDR_ACCEPT_ENCODING: header = new CommaSeparatedList( true, CreateIdentifierQValue, 1 ); break; case HDR_ACCEPT_LANGUAGE: header = new CommaSeparatedList( true, CreateLanguageTag, 1 ); break; case HDR_AGE: case HDR_CONTENT_LENGTH: case HDR_MAX_FORWARDS: header = new HttpNumber; break; case HDR_ALLOW: case HDR_CONNECTION: case HDR_CONTENT_ENCODING: case HDR_TRANSFER_ENCODING: header = new CommaSeparatedList( false, CreateIdentifierValue ); break; case HDR_CACHE_CONTROL: header = new CommaSeparatedList( false, CreateCacheDirective ); break; case HDR_CONTENT_LANGUAGE: header = new CommaSeparatedList( false, CreateLanguageTag ); break; case HDR_CONTENT_LOCATION: case HDR_LOCATION: header = new UriType; break; case HDR_CONTENT_TYPE: header = new MediaRange; break; case HDR_DATE: case HDR_EXPIRES: case HDR_IF_MODIFIED_SINCE: case HDR_IF_UNMODIFIED_SINCE: case HDR_LAST_MODIFIED: header = new HttpDateValue; break; case HDR_HOST: header = new HostPortValue; break; case HDR_RETRY_AFTER: header = new HttpDateOrSeconds; break; /* --trimming down parser case HDR_UPNP_NTS: header = new NTSType; break; */ case HDR_UNKNOWN: header = new UnknownHeader; break; default: header = new RawHeaderValue; } if ( header == NULL ) { throw OutOfMemoryException( "ParseHeader()" ); } try { header->load( scanner ); // skip whitespace after value SkipOptionalLWS( scanner ); // end of header -- crlf token = scanner.getToken(); if ( token->tokType != Token::CRLF ) { throw HttpParseException(); } } catch ( HttpParseException& /* e */ ) { SkipHeader( scanner ); // bad header -- ignore it id = -2; delete header; header = NULL; } headerID = id; return header;}// precond: scanner pointing to the line after the start linestatic void ParseHeaders( IN Tokenizer& scanner, OUT HttpHeaderList& list ){ Token *token; int id; HttpHeaderValue* headerValue; HttpHeader* header; while ( true ) { token = scanner.getToken(); if ( token->tokType == Token::CRLF ) { // end of headers break; } else if ( token->tokType == Token::END_OF_STREAM ) { // bad format scanner.pushBack(); throw HttpParseException( "ParseHeaders(): unexpected end of msg" ); break; } else { // token was probably start of a header scanner.pushBack(); } headerValue = ParseHeader( scanner, id ); if ( headerValue != NULL ) { header = new HttpHeader; if ( header == NULL ) { throw OutOfMemoryException( "ParseHeaders()" ); } header->type = id; header->value = headerValue; list.addAfterTail( header ); } }}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HttpHeaderQValuevoid HttpQHeaderValue::toString( xstring& s ){ if ( qIsUsed ) { char buf[100]; sprintf( buf, ";q=%1.3f", q ); s += buf; }}void HttpQHeaderValue::loadOptionalQValue( IN Tokenizer& scanner ){ q = 1.0; // default value // try getting q try { Token* token; if ( qIsUsed ) { SkipOptionalLWS( scanner ); token = scanner.getToken(); if ( token->s != ';' ) { scanner.pushBack(); //DBG( printf("HttpQHeaderValue: did not find ;\n"); ) throw 1; } SkipOptionalLWS( scanner ); q = LoadQValue( scanner ); } } catch ( int /* code */ ) { // no q value //DBG( printf("HttpQHeaderValue: did not find semicolon\n"); ) }}// HttpNumbervoid HttpNumber::toString( xstring& s ){ char buf[50]; sprintf( buf, "%d", num ); s += buf;}void HttpNumber::load( Tokenizer& scanner ){ num = loadNum( scanner, 10 ); }// HttpHexNumbervoid HttpHexNumber::toString( xstring& s ){ char buf[50]; sprintf( buf, "%X", num ); s += buf;}void HttpHexNumber::load( Tokenizer& scanner ){ num = loadNum( scanner, 16 );}// MediaExtensionvoid MediaExtension::toString( xstring& s ){ s += ';'; s += name; s += "="; s += value;}// match: ext = valuevoid MediaExtension::load( Tokenizer& scanner ){ Token* token; HttpParseException e("MediaExtension::load()", scanner.getLineNum() ); token = scanner.getToken(); if ( token->tokType != Token::IDENTIFIER ) { throw e; } name = token->s; SkipOptionalLWS( scanner ); token = scanner.getToken(); if ( token->s != "=" ) { throw e; } SkipOptionalLWS( scanner ); token = scanner.getToken(); if ( token->tokType != Token::IDENTIFIER && token->tokType != Token::QUOTED_STRING ) { throw e; } value = token->s;}// MediaParamvoid MediaParam::load( Tokenizer& scanner ){ Token* token; token = scanner.getToken(); if ( token->s != ';' ) { scanner.pushBack(); throw HttpParseException( "MediaParam::load(): ; missing", scanner.getLineNum() ); } SkipOptionalLWS( scanner ); token = scanner.getToken(); if ( token->s == 'q' ) { scanner.pushBack(); q = LoadQValue( scanner ); } SkipOptionalLWS( scanner ); while ( true ) { MediaExtension* ext; token = scanner.getToken(); if ( token->s != ';' ) { scanner.pushBack(); break; // no more extensions } ext = new MediaExtension(); if ( ext == NULL ) { throw OutOfMemoryException( "MediaParam::load()" ); } SkipOptionalLWS( scanner ); ext->load( scanner ); extList.addAfterTail( ext ); }}void MediaParam::toString( xstring& s ){ HttpQHeaderValue::toString( s ); // print q HttpHeaderValue* value; HttpHeaderValueNode* node; node = extList.getFirstItem(); while ( node != NULL ) { value = (HttpHeaderValue *)node->data; value->toString( s ); node = extList.next( node ); }}// MediaRangevoid MediaRange::toString( xstring& s ){ s += type; s += '/'; s += subtype; mparam.toString( s );}void MediaRange::load( Tokenizer& scanner ){ Token* token; token = scanner.getToken(); if ( token->tokType != Token::IDENTIFIER ) { scanner.pushBack(); throw HttpParseException( "MediaRange::load(): type expected", scanner.getLineNum() ); } type = token->s; SkipOptionalLWS( scanner ); token = scanner.getToken(); if ( token->s != '/' ) { scanner.pushBack(); throw HttpParseException( "MediaRange::load(): / expected", scanner.getLineNum() ); } SkipOptionalLWS( scanner ); token = scanner.getToken(); if ( token->tokType != Token::IDENTIFIER || (type == '*' && token->s != '*') ) { scanner.pushBack(); throw HttpParseException( "MediaRange::load(): subtype expected", scanner.getLineNum() ); } subtype = token->s; mparam.load( scanner );}// returns: 0 same, -1 this < r, 1 this > r, -2 unrelated// returns true if 'this' range has higher precedence than rint MediaRange::compare( const MediaRange& r ) const{ if ( mparam.q > r.mparam.q ) { return 1; } else if ( mparam.q < r.mparam.q ) { return -1; } else // equal { bool t = false, rt = false; t = (type == '*'); rt = (type == '*'); if ( t && !rt ) return -1; else if ( !t && rt ) return 1; else if ( type == r.type ) { if ( subtype == r.subtype ) { return 0; } else if ( subtype == '*' && r.subtype != '*' ) { return 1; } else if ( subtype != '*' && r.subtype == '*' ) { return -1; } else { return 0; } } else if ( type != r.type ) { return -2; } } return -2;}// MediaRangeListvoid MediaRangeList::toString( xstring& s ){ HeaderValueListToString( mediaList, s );}/*static void ReadCommaSeperatedList( IN Tokenizer& scanner, OUT HttpHeaderValueList& list, IN int minItems, IN int maxItems, IN ReadHttpValueCallback callback, IN AddValueToListCallback addCallback = NULL )*/// add media range in a sorted mannerstatic void AddMediaRangeToList( HttpHeaderValueList& list, HttpHeaderValue *value ){ MediaRange* b = (MediaRange*) value; MediaRange* a; HttpHeaderValueNode* node; int inserted = false; int comp = 0; node = list.getFirstItem(); while ( node != NULL ) { a = (MediaRange*) node->data; comp = a->compare( *b ); if ( comp == 1 || comp == 0 ) { list.addBefore( node, b ); inserted = true; break; } else if ( comp == -1 ) { list.addAfter( node, b ); inserted = true; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -