📄 smlparse.cpp
字号:
}
else if(strcmp(pName, "repeat") == 0)
{
const char* pRepeatCount = (const char*)pBuf->GetBuffer();
if(strcmp(pRepeatCount, "indefinite") == 0)
{
pSource->m_ulRepeatValue = MAX_UINT32;
}
else
{
pSource->m_ulRepeatValue = atol(pRepeatCount);
}
}
pBuf->Release();
if(HXR_OK != rc)
{
goto exit;
}
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
rc = adjustDuration(pSource);
exit:
if(HXR_OK != rc)
{
HX_DELETE(pSource);
}
return pSource;
}
CSmil1SeqElement*
CSmil1Parser::makeSeqElement(SMIL1Node* pNode)
{
HX_RESULT rc = HXR_OK;
CSmil1SeqElement* pElement =
new CSmil1SeqElement(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "dur") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrDur);
}
else if(strcmp(pName, "begin") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrBegin);
}
else if(strcmp(pName, "end") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrEnd);
}
else if(strcmp(pName, "title") == 0)
{
pElement->m_title = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "repeat") == 0)
{
pElement->m_ulRepeatValue = atol((const char*)pBuf->GetBuffer());
}
pBuf->Release();
if(HXR_OK != rc)
{
goto exit;
}
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
rc = adjustDuration(pElement);
exit:
if(HXR_OK != rc)
{
HX_DELETE(pElement);
}
return pElement;
}
CSmil1ParElement*
CSmil1Parser::makeParElement(SMIL1Node* pNode)
{
HX_RESULT rc = HXR_OK;
CSmil1ParElement* pElement =
new CSmil1ParElement(pNode);
if(pNode->m_pValues)
{
const char* pName = 0;
IHXBuffer* pBuf = 0;
rc = pNode->m_pValues->GetFirstPropertyCString(pName, pBuf);
while(HXR_OK == rc)
{
if(strcmp(pName, "dur") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrDur);
}
else if(strcmp(pName, "begin") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrBegin);
}
else if(strcmp(pName, "end") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrEnd);
}
else if(strcmp(pName, "endsync") == 0)
{
rc = parseDuration((const char*)pBuf->GetBuffer(), pElement,
SMILSyncAttrEndsync);
}
else if(strcmp(pName, "title") == 0)
{
pElement->m_title = (const char*)pBuf->GetBuffer();
}
else if(strcmp(pName, "repeat") == 0)
{
pElement->m_ulRepeatValue = atol((const char*)pBuf->GetBuffer());
}
pBuf->Release();
if(HXR_OK != rc)
{
goto exit;
}
rc = pNode->m_pValues->GetNextPropertyCString(pName, pBuf);
}
}
rc = adjustDuration(pElement);
exit:
if(HXR_OK != rc)
{
HX_DELETE(pElement);
}
return pElement;
}
HX_RESULT
CSmil1Parser::insertElementByTimestamp(CSmil1Element* pPacket)
{
LISTPOSITION lPos = m_pPacketQueue->GetHeadPosition();
LISTPOSITION lPrev = lPos;
while(lPos)
{
CSmil1Element* pPkt = (CSmil1Element*)m_pPacketQueue->GetNext(lPos);
if(pPkt->m_ulTimestamp > pPacket->m_ulTimestamp)
{
m_pPacketQueue->InsertBefore(lPrev, pPacket);
return HXR_OK;
}
lPrev = lPos;
}
m_pPacketQueue->AddTail(pPacket);
return HXR_OK;
}
HX_RESULT
CSmil1Parser::mapID(SMIL1Node* pNode, BOOL bOverWrite)
{
HX_RESULT rc = HXR_OK;
void* pTmp = 0;
if(!bOverWrite && m_pIDMap->Lookup((const char*)pNode->m_id, (void*&)pTmp))
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorDuplicateID, pNode->m_id,
pNode->m_ulTagStartLine);
}
else
{
(*m_pIDMap)[(const char*)pNode->m_id] = pNode;
}
return rc;
}
//This function is needed to fix PR 13319. If you have a repeat of greater
// than 1 in a <seq>, we need a way to map the IDs of the children created
// when the additional <seq>(s) are created
HX_RESULT
CSmil1Parser::mapChildrenIDs(SMIL1NodeList* pNodeList, BOOL bOverWrite)
{
HX_RESULT rc = HXR_OK;
if (!pNodeList)
{
return rc;
}
CHXSimpleList::Iterator i;
for(i=pNodeList->Begin();rc == HXR_OK && i!=pNodeList->End();++i)
{
SMIL1Node* pNode = (SMIL1Node*)(*i);
rc = mapID(pNode, bOverWrite);
HX_ASSERT(rc == HXR_OK);
if(pNode->m_pNodeList)
{
rc = mapChildrenIDs(pNode->m_pNodeList, bOverWrite);
}
}
return rc;
}
HX_RESULT
CSmil1Parser::markRepeatReplica(SMIL1NodeList* pNodeList, RepeatTag repeatTag)
{
HX_RESULT rc = HXR_OK;
if(!pNodeList)
{
return rc;
}
CHXSimpleList::Iterator i;
for(i=pNodeList->Begin();rc == HXR_OK && i!=pNodeList->End();++i)
{
SMIL1Node* pNode = (SMIL1Node*)(*i);
pNode->m_repeatTag = repeatTag;
if(pNode->m_pNodeList)
{
rc = markRepeatReplica(pNode->m_pNodeList, repeatTag);
}
}
return rc;
}
HX_RESULT
CSmil1Parser::createElements()
{
HX_RESULT rc = HXR_OK;
SMIL1Node* pSMIL1Node = findFirstNode(SMILSmil);
if(!pSMIL1Node) // dangerwillrobinson!!!
{
rc = HXR_FAIL;
CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
errHandler.ReportError(SMILErrorNotSMIL, NULL, 0);
return rc;
}
rc = addToNamespaceScope(pSMIL1Node);
if (SUCCEEDED(rc))
{
// XXXJEFFA Hardcode "cv" namespace prefix for Redstone alpha 7
rc = addGlobalNamespace((const char*) SYSTEM_COMPONENT_NAMESPACE, "cv");
}
if (FAILED(rc))
{
HX_ASSERT(FALSE);
return rc;
}
SMIL1Node* pHeadNode = findFirstNode(SMILHead);
if(pHeadNode)
{
rc = markTestAttributeNodes(pHeadNode->m_pNodeList);
if (SUCCEEDED(rc))
{
rc = addToNamespaceScope(pHeadNode);
}
if(SUCCEEDED(rc))
{
rc = createHeadElements(pHeadNode->m_pNodeList);
}
if (SUCCEEDED(rc))
{
rc = removeFromNamespaceScope(pHeadNode);
}
}
if(rc == HXR_OK)
{
SMIL1Node* pBodyNode = findFirstNode(SMILBody);
if(pBodyNode &&
pBodyNode->m_pNodeList)
{
rc = addToNamespaceScope(pBodyNode);
if (SUCCEEDED(rc))
{
SMIL1Node* pTopNode = getTimelineDescendent(pBodyNode, NULL);
if(pTopNode &&
pTopNode->m_tag != SMILSeq)
{
createSeqWrapper(pBodyNode->m_pNodeList);
}
//[SMIL 1.0 compliance] fix for PR 23050:
// if first descendent of body is a <switch> and its first child
// is a <seq> that did not get chosen in the switch, then we
// would be tricked into thinking we already had a valid outer
// seq, but we wouldn't. Let's put one there in this case,
// noting that we don't yet know if that seq is valid or not.
// However, it doesn't matter either way:
if(pTopNode && SMILSeq == pTopNode->m_tag &&
pTopNode->m_pParent &&
pTopNode->m_pParent->m_tag == SMILSwitch)
{
createSeqWrapper(pBodyNode->m_pNodeList);
}
if(HXR_OK != markTestAttributeNodes(pBodyNode->m_pNodeList) ||
HXR_OK != expandRepeatElements(pBodyNode->m_pNodeList) ||
HXR_OK != createBodyElements(pBodyNode->m_pNodeList) ||
HXR_OK != assignGroupIndexes(pBodyNode->m_pNodeList) ||
HXR_OK != constructTimelineElements(pBodyNode->m_pNodeList) ||
HXR_OK != setInitialDelays(pBodyNode->m_pNodeList) ||
// HXR_OK != updateEventElements(pBodyNode->m_pNodeList) ||
#ifdef _DEBUG
HXR_OK != printBodyElements(pBodyNode->m_pNodeList) ||
#endif
HXR_OK != insertGroups())
{
rc = HXR_FAIL;
}
}
if (SUCCEEDED(rc))
{
rc = removeFromNamespaceScope(pBodyNode);
}
}
if(rc == HXR_OK && !m_bContainsSource)
{
rc = HXR_OK;
//[SMIL 1.0 compliance] fixes PR 27672:
// don't call SMILErrorNoBodyElements error as it is not one
// per the SMIL 1.0 spec.
}
}
return rc;
}
HX_RESULT
CSmil1Parser::createSeqWrapper(SMIL1NodeList* pNodeList)
{
// create a default <seq></seq> wrapper within the <body></body>
HX_RESULT rc = HXR_OK;
SMIL1Node* pSeqNode = new SMIL1Node;
pSeqNode->m_name = "seq";
pSeqNode->m_pParent = pNodeList->m_pParentNode;
pSeqNode->m_id = assignID("seq");
pSeqNode->m_tag = SMILSeq;
pSeqNode->m_pNodeList = new SMIL1NodeList;
// Must put the node in the id map - otherwise
// we leak the node
mapID(pSeqNode, TRUE);
// move children from bodyNode list to seq list
int count = pNodeList->GetCount();
SMIL1Node* pEndBodyNode = NULL;
while( count > 0) // don't reparent </body> tag
{
SMIL1Node* pChildNode = (SMIL1Node*)pNodeList->RemoveHead();
//XXXJHUG don't reparent the </body> tag...
if ( pChildNode->m_id != "CLOSE-body" )
{
pChildNode->m_pParent = pSeqNode;
pSeqNode->m_pNodeList->AddTail(pChildNode);
}
else
{
pEndBodyNode = pChildNode;
}
--count;
}
SMIL1Node* pEndSeqNode = new SMIL1Node;
pEndSeqNode->m_name = "seq";
pEndSeqNode->m_id = "CLOSE-seq";
pEndSeqNode->m_pParent = pSeqNode;
pEndSeqNode->m_tag = SMILEndSeq;
pSeqNode->m_pNodeList->AddTail(pEndSeqNode);
// now add it to the <body> parent...
pNodeList->AddHead(pSeqNode);
pNodeList->AddTail(pEndBodyNode);
return rc;
}
#if 0
//XXXBAB - useful for debugging
void
CSmil1Parser::PrintNode(SMIL1Node* pNode, FILE* fp, int level)
{
for(int tab=0;tab<level;++tab)
{
fprintf(fp, "\t");
}
fprintf(fp, "%s\n", (const char*)pNode->m_id);
if(pNode->m_pNodeList)
{
CHXSimpleList::Iterator i = pNode->m_pNodeList->Begin();
for(; i != pNode->m_pNodeList->End(); ++i)
{
SMIL1Node* pChildNode = (SMIL1Node*)(*i);
PrintNode(pChildNode, fp, level+1);
}
}
}
void
CSmil1Parser::PrintNodes()
{
FILE* fp = fopen("nodes.txt", "w");
SMIL1Node* pNode = (SMIL1Node*)m_pNodeList->GetHead();
PrintNode(pNode, fp, 0);
fclose(fp);
}
#endif
HX_RESULT
CSmil1Parser::printBodyElements(SMIL1NodeList* pNodeList)
{
// debugging code...
HX_RESULT rc = HXR_OK;
//#define XXXEH_FOR_DEBUGGING_ONLY
#if defined(XXXEH_FOR_DEBUGGING_ONLY)
static int level = 0;
if(!pNodeList)
{
return rc;
}
CHXSimpleList::Iterator i;
for(i=pNodeList->Begin();i!=pNodeList->End();++i)
{
if(HXR_OK != rc)
{
return rc;
}
SMIL1Node* pNode = (SMIL1Node*)(*i);
FILE* fp=fopen("c:\\temp\\smil.txt", "a+");
if (!fp)
{
break;
}
for(int i=0;i<level;++i)
{
fprintf(fp, "\t");
}
UINT32 ulDelay = (UINT32)-1;
if(pNode->m_pElement &&
pNode->m_pElement->m_pTimelineElement)
{
ulDelay = pNode->m_pElement->m_pTimelineElement->getDelay();
}
fprintf(fp, "%s tag %d group %d repeatid %s delay %d deleted %d\n", (const char*)pNode->m_id,
pNode->m_tag, pNode->m_nGroup, (const char*)pNode->m_repeatid, ulDelay, pNode->m_bDelete);
fclose(fp);
if(pNode->m_pNodeList)
{
++level;
rc = printBodyElements(pNode->m_pNodeList);
--level;
}
}
#endif
return rc;
}
HX_RESULT
CSmil1Parser::insertGroups()
{
HX_RESULT rc = HXR_OK;
if(!m_pAddGroupMap)
{
rc = HXR_UNEXPECTED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -