📄 smlpkt.cpp
字号:
CSmilPacketParser::getAtom(const char*& pBuf, UINT32 len,
CSmilPacketTag*& pTag)
{
CSmilPacketParser::SMILPacketParseResult retCode = SMILUnknown;
const char* pEnd;
const char* pCur;
pTag = 0;
pEnd = pBuf + len;
pCur = pBuf;
if(*pCur == '(')
{
pCur++;
pBuf = pCur;
retCode = SMILOpenList;
}
else if(*pCur == ')')
{
pCur++;
pBuf = pCur;
retCode = SMILCloseList;
}
else
{
// skip whitespace
while(isspace(*pCur) && (pCur < pEnd))
{
pCur++;
}
if(pCur >= pEnd)
{
pBuf = pCur;
retCode = SMILNoValue;
}
else if(*pCur == ')')
{
pCur++;
pBuf = pCur;
retCode = SMILCloseList;
}
else if(*pCur == '(')
{
pCur++;
pBuf = pCur;
retCode = SMILOpenList;
}
else
{
char* tmpBuf = new char [MAX_STRING_LEN + 2]; /* Flawfinder: ignore */ // one for null, one for luck
char* pTmpBuf = tmpBuf;
if(*pCur == '"')
{
pCur++;
int iLen = 0;
while((*pCur != '"') && (pCur < pEnd) && (++iLen < MAX_STRING_LEN))
{
if(*pCur == '\\')
{
pCur++;
*pTmpBuf++ = *pCur++;
}
else
{
*pTmpBuf++ = *pCur++;
}
}
if(*pCur != '"')
{
pBuf = pCur;
retCode = SMILMissingQuote;
}
else
{
*pTmpBuf = 0;
pCur++;
}
}
else
{
while((pCur<pEnd) && !isspace(*pCur) && (*pCur != ')') &&
(*pCur != '(') )
{
if(*pCur == '\\')
{
pCur++;
*pTmpBuf++ = *pCur++;
}
else
{
*pTmpBuf++ = *pCur++;
}
}
*pTmpBuf = 0;
}
if( retCode != SMILMissingQuote )
{
pTag = new CSmilPacketTag;
pTag->m_name = tmpBuf;
pBuf = pCur;
retCode = SMILString;
}
HX_VECTOR_DELETE(tmpBuf);
}
}
return retCode;
}
CSmilPacket*
CSmilPacketParser::parse(IHXBuffer* pBuffer,
REF(CSmilPacketParser::SMILPacketParseResult) pktPrsRslt)
{
BOOL bErrorOccurred = FALSE;
CSmilPacketTag* pTag = 0;
HX_RESULT pnr = HXR_OK;
if(m_pRootNode)
{
deleteNode(m_pRootNode);
}
m_pRootNode = new Node;
Node* pCurNode = m_pRootNode;
Node* pCurList = m_pRootNode;
CHXStack* pStack = new CHXStack;
CBigByteQueue* pQueue = new CBigByteQueue(pBuffer->GetSize());
pQueue->EnQueue((void*)pBuffer->GetBuffer(), pBuffer->GetSize());
BOOL bFirst = TRUE;
for(;;)
{
UINT32 bytesUsed;
UINT32 bytesAvail = pQueue->GetQueuedItemCount();
if(bytesAvail <= 0)
{
break;
}
BYTE* pBuf = new BYTE[bytesAvail];
BYTE* p = pBuf;
pQueue->DeQueue(pBuf, bytesAvail);
bytesUsed = bytesAvail;
if(pTag)
{
delete pTag;
pTag = 0;
}
SMILPacketParseResult rc = getAtom((const char*&)p, bytesAvail, pTag);
// /Fixes PR 32297 (release-build-only crash):
// In case rc is SMILMissingQuote, quit and return an error,
// otherwise a 0-sized buffer gets created later on that is the
// subject of an access violation:
INT32 lSizeToEnqueue = bytesAvail - (p - pBuf);
HX_ASSERT(lSizeToEnqueue >= 0); // /If < 0, something is messed up.
if (0 == lSizeToEnqueue && SMILMissingQuote == rc)
{
pktPrsRslt = rc;
bErrorOccurred = TRUE;
goto cleanup;
}
pQueue->EnQueue(p, (UINT32)(bytesAvail - (p - pBuf)));
switch(rc)
{
case SMILOpenList:
{
Node* pNode = new Node;
if(pCurNode == m_pRootNode)
{
pCurNode->car = pNode;
}
else
{
pCurNode->cdr = pNode;
}
pStack->Push(pNode);
pCurNode = pNode;
}
break;
case SMILString:
{
if(bFirst)
{
bFirst = FALSE;
}
else
{
Node* pNode = new Node;
if(!pCurNode->m_bIsSymbol)
{
if(!pCurNode->car)
pCurNode->car = pNode;
else
pCurNode->cdr = pNode;
}
else
{
pCurNode->cdr = pNode;
}
pCurNode = pNode;
}
pCurNode->m_name = pTag->m_name;
pCurNode->m_bIsSymbol = TRUE;
}
break;
case SMILCloseList:
{
pCurNode = (Node*)pStack->Pop();
}
break;
default:
break;
}
HX_VECTOR_DELETE(pBuf);
}
cleanup:
if(pTag)
{
delete pTag;
}
delete pQueue;
delete pStack;
if (bErrorOccurred)
{
return NULL;
}
return evalNode(getRoot());
}
void
CSmilPacketParser::deleteNode(Node* pNode)
{
if(!pNode)
{
return;
}
deleteNode(pNode->car);
deleteNode(pNode->cdr);
delete pNode;
}
void
CSmilPacketParser::eval(Node* pNode, CSmilPacket* pPacket)
{
if(!pNode)
return;
BOOL bFirst = TRUE;
const char* pName = 0;
const char* pValue[MAX_ARGS] = {0};
int i = 0;
while(pNode && i < MAX_ARGS)
{
if(pNode->m_bIsSymbol)
{
if(bFirst)
{
pName = (const char*)pNode->m_name;
bFirst = FALSE;
i = 0;
}
else
{
pValue[i] = (const char*)pNode->m_name;
i++;
}
}
else
{
eval(pNode->car, pPacket);
}
pNode = pNode->cdr;
}
if(pName)
{
pPacket->assign(pName, pValue, i);
}
}
CSmilPacket*
CSmilPacketParser::evalNode(Node* pNode)
{
if(!pNode || !pNode->m_bIsSymbol)
{
return 0;
}
CSmilPacket* pPacket = 0;
// const char* pID = 0;
const char* pName = 0;
pName = (const char*)pNode->m_name;
pNode = pNode->cdr;
if(pNode)
{
// if(pNode->m_bIsSymbol)
// {
// pID = (const char*)pNode->m_name;
// pNode = pNode->cdr;
// }
// else
// {
// pID = "<anonymous>";
// }
if(strcmp(pName, "smil-document") == 0)
{
pPacket = new CSmilDocumentPacket;
}
else if(strcmp(pName, "add-channel") == 0)
{
pPacket = new CSmilAddChannelPacket;
}
else if(strcmp(pName, "add-group") == 0)
{
pPacket = new CSmilAddGroupPacket;
}
else if(strcmp(pName, "play-group") == 0)
{
pPacket = new CSmilPlayGroupPacket;
}
else if(strcmp(pName, "add-source") == 0)
{
pPacket = new CSmilAddSourcePacket;
}
else if(strcmp(pName, "source-added") == 0)
{
pPacket = new CSmilSourceAddedPacket;
}
else if(strcmp(pName, "end-layout") == 0)
{
pPacket = new CSmilEndLayoutPacket;
}
else if(strcmp(pName, "meta") == 0)
{
pPacket = new CSmilMetaValuesPacket;
}
if(pPacket)
{
eval(pNode, pPacket);
}
return pPacket;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -