📄 rtsppars.cpp
字号:
int
RTSPParser::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;
}
int
RTSPParser::parseWWWAuthenticateHeaderValues(const char* pValue,
MIMEHeader* pHeader)
{
/*
* Not needed anymore, authentication model has changed
*
*/
return 0;
}
int
RTSPParser::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 + -