⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smlparse.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	    }
	    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 + -