📄 rtsppars.cpp
字号:
MIMEInputStream input(pValue, strlen(pValue)); MIMEScanner scanner(input); MIMEToken nextTok = scanner.nextToken(); pHeader->addHeaderValue(new MIMEHeaderValue(nextTok.value())); return 0;}intRTSPParser::parseAlertValue(const char* pValue, MIMEHeader* pHeader){ MIMEInputStream input(pValue, strlen(pValue)); MIMEScanner scanner(input); MIMEToken nextTok; MIMEHeaderValue* pHeaderValue = new MIMEHeaderValue; // Parse Alert number nextTok = scanner.nextToken(";"); if (nextTok.hasValue()) { pHeaderValue->addParameter(nextTok.value(), ""); } // Parse Alert text nextTok = scanner.nextToken(""); if (nextTok.hasValue()) { pHeaderValue->addParameter(nextTok.value(), ""); } pHeader->addHeaderValue(pHeaderValue); return 0;}/* * Parse header values as list of comma separated values */int RTSPParser::defaultParseHeaderValues(const char* pValue, MIMEHeader* pHeader){ MIMEInputStream input(pValue, strlen(pValue)); MIMEScanner scanner(input); MIMEToken nextTok = scanner.nextToken(","); while(nextTok.hasValue()) { parseHeaderValue(nextTok.value(), pHeader); if((nextTok.lastChar() == MIMEToken::T_EOL) || (nextTok.lastChar() == MIMEToken::T_EOF)) return 0; nextTok = scanner.nextToken(","); } return 0;}intRTSPParser::parseWWWAuthenticateHeaderValues(const char* pValue, MIMEHeader* pHeader){/* * Not needed anymore, authentication model has changed * */ return 0;}intRTSPParser::parseDigestAuthorizationHeaderValues(const char* pValue, MIMEHeader* pHeader){/* * Not needed anymore, authentication model has changed * */ return 0;}/* * construct a MIMEHeader and add header values to it * format: 'HeaderName: option, option=value;option=value, option' */MIMEHeader* RTSPParser::parseHeader(CHXString& str){ MIMEHeader* pHeader = 0; MIMEInputStream input(str); MIMEScanner scanner(input); MIMEToken nextTok = scanner.nextToken(":"); if(nextTok.hasValue()) { pHeader = new MIMEHeader(nextTok.value()); nextTok = scanner.nextToken("\n"); if(strcasecmp(pHeader->name(), "Range") == 0) { parseRangeValue(nextTok.value(), pHeader); } else if ( (strcasecmp(pHeader->name(), "WWW-Authenticate") == 0) || (strcasecmp(pHeader->name(), "Authenticate") == 0) || (strcasecmp(pHeader->name(), "Authorization") == 0) || // XXX HP get the absolute redirect URL which could // contain ',' and would be treated as field separater // in defaultParseHeaderValues() (strcasecmp(pHeader->name(), "Location") == 0) || (strcasecmp(pHeader->name(), "Content-base") == 0) ) { MIMEHeaderValue* pHeaderValue = new MIMEHeaderValue; if(pHeaderValue) { pHeaderValue->addParameter(nextTok.value()); pHeader->addHeaderValue(pHeaderValue); } } else if((strcasecmp(pHeader->name(), "PEP-Info") == 0) || (strcasecmp(pHeader->name(), "C-PEP-Info") == 0)) { parsePEPInfoHeaderValues(nextTok.value(), pHeader); } else if(strcasecmp(pHeader->name(), "RTP-Info") == 0) { parseRTPInfoHeaderValues(nextTok.value(), pHeader); } else if(strcasecmp(pHeader->name(), "BackChannel") == 0) { parseBackChannelValue(nextTok.value(), pHeader); } else if(strcasecmp(pHeader->name(), "Alert") == 0) { parseAlertValue(nextTok.value(), pHeader); } else { defaultParseHeaderValues(nextTok.value(), pHeader); } } return pHeader;}/* * Parse request line in format 'METHOD URL VERSION SEQ_NO' */RTSPRequestMessage*RTSPParser::parseRequestLine(CHXString& str){ int majorVersion, minorVersion; RTSPRequestMessage* pReqMsg = 0; MIMEInputStream input(str); MIMEScanner scanner(input); // build message MIMEToken nextTok = scanner.nextToken(); const char* pMsgName = nextTok.value(); if(strcasecmp(pMsgName, "SETUP") == 0) { pReqMsg = new RTSPSetupMessage; } else if(strcasecmp(pMsgName, "REDIRECT") == 0) { pReqMsg = new RTSPRedirectMessage; } else if(strcasecmp(pMsgName, "PLAY") == 0) { pReqMsg = new RTSPPlayMessage; } else if(strcasecmp(pMsgName, "PAUSE") == 0) { pReqMsg = new RTSPPauseMessage; } else if(strcasecmp(pMsgName, "SET_PARAMETER") == 0) { pReqMsg = new RTSPSetParamMessage; } else if(strcasecmp(pMsgName, "GET_PARAMETER") == 0) { pReqMsg = new RTSPGetParamMessage; } else if(strcasecmp(pMsgName, "TEARDOWN") == 0) { pReqMsg = new RTSPTeardownMessage; } else if(strcasecmp(pMsgName, "DESCRIBE") == 0) { pReqMsg = new RTSPDescribeMessage; } else if(strcasecmp(pMsgName, "OPTIONS") == 0) { pReqMsg = new RTSPOptionsMessage; } else if(strcasecmp(pMsgName, "RECORD") == 0) { pReqMsg = new RTSPRecordMessage; } else if(strcasecmp(pMsgName, "ANNOUNCE") == 0) { pReqMsg = new RTSPAnnounceMessage; } else { pReqMsg = new RTSPUnknownMessage; } // get URL nextTok = scanner.nextToken(" "); pReqMsg->setURL(nextTok.value()); // get version info nextTok = scanner.nextToken(); if(parseProtocolVersion(nextTok.value(), majorVersion, minorVersion)) { pReqMsg->setVersion(majorVersion, minorVersion); } else { pReqMsg->setVersion(0,0); // indicate bad version } return pReqMsg;}/* * Parse response line in format 'VERSION ERR_CODE SEQ_NO ERR_MSG' */RTSPResponseMessage*RTSPParser::parseResponseLine(CHXString& str){ int majorVersion, minorVersion; RTSPResponseMessage* pRespMsg = 0; MIMEInputStream input(str); MIMEScanner scanner(input); MIMEToken nextTok = scanner.nextToken(); pRespMsg = new RTSPResponseMessage; if(parseProtocolVersion(nextTok.value(), majorVersion, minorVersion)) { pRespMsg->setVersion(majorVersion, minorVersion); } else { pRespMsg->setVersion(0,0); // indicate bad version } // get error code nextTok = scanner.nextToken(); pRespMsg->setErrorCode(nextTok.value()); // get error message nextTok = scanner.nextToken("\n"); pRespMsg->setErrorMsg(nextTok.value()); return pRespMsg;}/* * Parse response message */RTSPMessage* RTSPParser::parseResponse(){ RTSPResponseMessage* pRespMsg = 0; LISTPOSITION pos = m_msglines.GetHeadPosition(); CHXString* pStr = (CHXString*)m_msglines.GetNext(pos); pRespMsg = parseResponseLine(*pStr); if(!pRespMsg) return 0; while(pos) { pStr = (CHXString*)m_msglines.GetNext(pos); MIMEHeader* pHeader = parseHeader(*pStr); if(pHeader) pRespMsg->addHeader(pHeader); } // get sequence number UINT32 seqNo = 0; pRespMsg->getHeaderValue("CSeq", seqNo); pRespMsg->setSeqNo(seqNo); return pRespMsg;}/* * Parse request message */RTSPMessage* RTSPParser::parseRequest(){ RTSPRequestMessage* pReqMsg = 0; LISTPOSITION pos = m_msglines.GetHeadPosition(); CHXString* pStr = (CHXString*)m_msglines.GetNext(pos); pReqMsg = parseRequestLine(*pStr); if(!pReqMsg) return 0; while(pos) { pStr = (CHXString*)m_msglines.GetNext(pos); MIMEHeader* pHeader = parseHeader(*pStr); if(pHeader) pReqMsg->addHeader(pHeader); } // get sequence number UINT32 seqNo = 0; pReqMsg->getHeaderValue("CSeq", seqNo); pReqMsg->setSeqNo(seqNo); return pReqMsg;}/* * Add each line in message to list m_msglines. * Look for two carriage returns to delimit * message header. */UINT32 RTSPParser::scanMessageHeader(const char* pMsg, UINT32 nMsgLen){ // first, get rid of any leading whitespace and <CR><LF> chars const char* pCh = pMsg; while(*pCh == '\n' || *pCh == '\r' || *pCh == ' ' || *pCh == '\t') { pCh++; } UINT32 offset = pCh - pMsg; if(offset > nMsgLen) { return 0; } MIMEInputStream input(pCh, nMsgLen - offset); MIMEScanner scanner(input); MIMEToken tok; int gotEOL = 0; UINT32 scanOffset = 0; do { tok = scanner.nextToken("\n"); if(tok.lastChar() == MIMEToken::T_EOL) { if(gotEOL && !tok.hasValue()) { scanOffset = scanner.offset(); break; } else { gotEOL = 1; } } else { gotEOL = 0; } m_msglines.AddTail((void*)(new CHXString((const char*)tok.value()))); } while(tok.lastChar() != MIMEToken::T_EOF); if(scanOffset == 0) { return 0; } else { return scanOffset + offset; }}/* * Parse message pointed to by pMsg with length nMsgLen. * If not a complete message, return 0, otherwise return * RTSPMessage pointer. */RTSPMessage* RTSPParser::parse(const char* pMsg, UINT32& nMsgLen){ RTSPMessage* pRTSPMsg = 0; clearMessageLines(); INT32 msgOffset = scanMessageHeader(pMsg, nMsgLen); if(msgOffset > 0) { if(m_msglines.GetCount() == 0) { nMsgLen = 0; return 0; } CHXString* str = (CHXString*)m_msglines.GetHead(); if(strncasecmp((*str), "RTSP/", 5) == 0) { pRTSPMsg = parseResponse(); } else { pRTSPMsg = parseRequest(); } if(pRTSPMsg) { UINT32 contentLength = 0; if(pRTSPMsg->getHeaderValue("Content-length", contentLength)) { if((UINT32)msgOffset + contentLength <= (UINT32)nMsgLen) { CHXString content(&pMsg[msgOffset], HX_SAFEUINT(contentLength)); pRTSPMsg->setContent(content); nMsgLen = msgOffset + contentLength; } else // content-length not satisfied { // XXXBAB - update nMsglen as number of bytes needed // to complete message delete pRTSPMsg; pRTSPMsg = 0; nMsgLen = 0; } } else { nMsgLen = msgOffset; } } } else { nMsgLen = 0; } return pRTSPMsg;}/* * Delete contents of m_msglines */void RTSPParser::clearMessageLines(){ LISTPOSITION pos = m_msglines.GetHeadPosition(); while(pos) { CHXString* str = (CHXString*)m_msglines.GetNext(pos); delete str; } m_msglines.RemoveAll();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -