smlparse.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:137k
源码类别:

Symbian

开发平台:

C/C++

  1.     SMIL1NodeList* pNodeList = pSwitchNode->m_pNodeList;
  2.     if(!pNodeList)
  3.     {
  4. return rc;
  5.     }
  6.     SMIL1Node* pSelectedNode = 0;
  7.     CHXSimpleList* pRejectedNodeList = new CHXSimpleList;
  8.     CHXSimpleList::Iterator i;
  9.     for(i=pNodeList->Begin();i!=pNodeList->End();++i)
  10.     {
  11. SMIL1Node* pNode = (SMIL1Node*)(*i);
  12. if(!pNode->m_bDelete)
  13. {
  14.     if(testAttributeFailed(pNode))
  15.     {
  16. pRejectedNodeList->AddTail(pNode);
  17.     }
  18.     else
  19.     {
  20. pSelectedNode = pNode; 
  21. //[SMIL 1.0 Compliance] Fixes PR 26732:
  22. //Now, update selected node's id to that of the switch so
  23. // that anchors pointing to the switch id will reference
  24. // the node of the switch that was selected.  Note that
  25. // we can't fix this the other way around, namely to rename
  26. // all anchors' id strings to that of the selected node
  27. // since not all of them have been parsed/set yet:
  28. HX_ASSERT(pSelectedNode->m_id.GetLength() > 0  && 
  29.     pSwitchNode->m_id.GetLength() > 0);
  30. if (pSelectedNode->m_id.GetLength() > 0 &&  
  31.     pSwitchNode->m_id.GetLength() > 0)
  32. {
  33.     pSelectedNode->m_id = pSwitchNode->m_id;
  34.     (*m_pIDMap)[(const char*)pSelectedNode->m_id] =
  35.     pSelectedNode;
  36.     pSwitchNode->m_id = assignID("switch");
  37.     (*m_pIDMap)[(const char*)pSwitchNode->m_id] =
  38.     pSwitchNode;
  39. }
  40. break;
  41.     }
  42. }
  43.     }
  44.     HX_DELETE(pRejectedNodeList);
  45.     // delete non-selected nodes
  46.     for(i=pNodeList->Begin();i!=pNodeList->End();++i)
  47.     {
  48. SMIL1Node* pNode = (SMIL1Node*)(*i);
  49. if(pNode != pSelectedNode)
  50. {
  51.     pNode->m_bDelete = TRUE;
  52. }
  53.     }
  54.     return rc;
  55. }
  56. HX_RESULT
  57. CSmil1Parser::markTestAttributeNodes(SMIL1NodeList* pNodeList)
  58. {
  59.     HX_RESULT rc = HXR_OK;
  60.     if(!pNodeList)
  61.     {
  62. return rc;
  63.     }
  64.     CHXSimpleList::Iterator i;
  65.     for(i=pNodeList->Begin();i!=pNodeList->End() && SUCCEEDED(rc);++i)
  66.     {
  67. SMIL1Node* pNode = (SMIL1Node*)(*i);
  68. rc = addToNamespaceScope(pNode);
  69. if (FAILED(rc))
  70. {
  71.     return rc;
  72. }
  73. if(pNode->m_tag == SMILSwitch)
  74. {
  75.     selectSwitchNodes(pNode);
  76. }
  77. else
  78. {
  79.     if(testAttributeFailed(pNode))
  80.     {
  81. pNode->m_bDelete = TRUE;
  82.     }
  83. }
  84. //Fix for PR 21303: we need to keep drilling down
  85. // through the tree even if we've just called
  86. // selectSwitchNodes() to delete all but one
  87. // child of the switch; the descendants of that
  88. // child may have attributes as well that need
  89. // to be checked:
  90. //(For efficiency, only do the following code if
  91. // the node is not already slated for deletion
  92. // because a deletable node's children will be
  93. // deleted anyway):
  94. if (!pNode->m_bDelete)
  95. {
  96.     rc = markTestAttributeNodes(pNode->m_pNodeList);
  97. }
  98. if (SUCCEEDED(rc))
  99. {
  100.     rc = removeFromNamespaceScope(pNode);
  101. }
  102.     }
  103.     return rc;
  104. }
  105. BOOL
  106. CSmil1Parser::firstDependentChild(SMIL1Node* pNode)
  107. {
  108.     if(getFirstNodeChild(pNode->m_pDependency) == pNode)
  109.     {
  110. return TRUE;
  111.     }
  112.     return FALSE;
  113. }
  114. BOOL
  115. CSmil1Parser::hasParParent(SMIL1Node* pNode)
  116. {
  117.     // walk up parent chain until we find a PAR
  118.     BOOL rc = FALSE;
  119.     while(pNode)
  120.     {
  121. pNode = pNode->m_pParent;
  122. if(pNode && pNode->m_tag == SMILPar)
  123. {
  124.     rc = TRUE;
  125.     break;
  126. }
  127.     }
  128.     return rc;
  129. }
  130. SMIL1NodeTag
  131. CSmil1Parser::getSyncTag(SMIL1Node* pNode)
  132. {
  133.     // walk up parent chain until we either find
  134.     // a PAR or a SEQ
  135.     SMIL1NodeTag tag = SMILSeq; // assume a SEQ
  136.     while(pNode)
  137.     {
  138. pNode = pNode->m_pParent;
  139. if(pNode && pNode->m_tag == SMILPar)
  140. {
  141.     tag = SMILPar;
  142.     break;
  143. }
  144. else if(pNode && pNode->m_tag == SMILSeq)
  145. {
  146.     tag = SMILSeq;
  147.     break;
  148. }
  149.     }
  150.     return tag;
  151. }
  152. SMIL1Node*
  153. CSmil1Parser::getSyncParent(SMIL1Node* pNode)
  154. {
  155.     SMIL1Node* pReturnNode = NULL;
  156.     while(pNode)
  157.     {
  158. pNode = pNode->m_pParent;
  159. if(pNode && 
  160.     (pNode->m_tag == SMILPar ||
  161.      pNode->m_tag == SMILSeq))
  162. {
  163.     pReturnNode = pNode;
  164.     break;
  165. }
  166.     }
  167.     return pReturnNode;
  168. }
  169. BOOL
  170. CSmil1Parser::inSeq(SMIL1Node* pNode)
  171. {
  172.     SMIL1NodeTag tag = getSyncTag(pNode);
  173.     return tag == SMILSeq;
  174. }
  175. HX_RESULT
  176. CSmil1Parser::createHeadElements(SMIL1NodeList* pNodeList)
  177. {
  178.     HX_RESULT rc = HXR_OK;
  179.     if(!pNodeList)
  180.     {
  181. return rc;
  182.     }
  183.     CHXSimpleList::Iterator i;
  184.     for(i=pNodeList->Begin();i!=pNodeList->End();++i)
  185.     {
  186. if(HXR_OK != rc)
  187. {
  188.     return rc;
  189. }
  190. SMIL1Node* pNode = (SMIL1Node*)(*i);
  191. if(pNode->m_bDelete) // skip this puppy
  192. {
  193.     continue;
  194. }
  195. rc = addToNamespaceScope(pNode);
  196. if (FAILED(rc))
  197. {
  198.     return rc;
  199. }
  200. switch(pNode->m_tag)
  201. {
  202.     case SMILRegion:
  203.     {
  204. //[SMIL 1.0 compliance] Fixes PR 25798: a region element may
  205. // only be contained inside a layout element:
  206. if (m_bSMIL10FullCompliance  &&  pNode->m_pParent  &&
  207. pNode->m_pParent->m_name.GetLength()  &&
  208. strcmp((const char*)pNode->m_pParent->m_name,
  209. "layout"))
  210. {
  211.     CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
  212.     errHandler.ReportError(SMILErrorUnexpectedTag,
  213.     (const char*)pNode->m_name,
  214.     pNode->m_ulTagStartLine);
  215.     return HXR_FAIL;
  216. }
  217.     }
  218.     break;
  219.     case SMILMeta:
  220.     {
  221. CSmil1Meta* pMeta = makeMeta(pNode);
  222. if(pMeta)
  223. {
  224.     pNode->m_pElement = pMeta;
  225.     pMeta->m_ulDelay = 0;
  226.     pMeta->m_ulTimestamp = INITIAL_STREAM0_TIMESTAMP;
  227.     insertElementByTimestamp(pMeta);
  228. }
  229. else
  230. {
  231.     return HXR_FAIL;
  232. }
  233.     }
  234.     break;
  235.     case SMILBasicLayout:
  236.     {
  237. const char* pLayoutName = (const char*)pNode->m_id;
  238. BOOL bHasRegions = FALSE;
  239. SMIL1Node* pLayoutNode = pNode->getFirstChild();
  240. while(pLayoutNode && !pLayoutNode->m_bDelete)
  241. {
  242.     switch(pLayoutNode->m_tag)
  243.     {
  244. case SMILRootLayout:
  245. {
  246.     CSmil1RootLayout* pRootLayout = 
  247. makeRootLayout(pLayoutNode);
  248.     if(pRootLayout)
  249.     {
  250. pLayoutNode->m_pElement = pRootLayout;
  251. pRootLayout->m_ulDelay = 0;
  252. pRootLayout->m_ulTimestamp =
  253.     INITIAL_STREAM0_TIMESTAMP;
  254. insertElementByTimestamp(pRootLayout);
  255.     }
  256.     else
  257.     {
  258. return HXR_FAIL;
  259.     }
  260. }
  261. break;
  262. case SMILRegion:
  263. {
  264.     CSmil1Region* pRegion = 
  265. makeRegion(pLayoutNode);
  266.     if(pRegion)
  267.     {
  268. pLayoutNode->m_pElement = pRegion;
  269. bHasRegions = TRUE;
  270. pRegion->m_ulDelay = 0;
  271. pRegion->m_ulTimestamp = 
  272.     INITIAL_STREAM0_TIMESTAMP;
  273. insertElementByTimestamp(pRegion);
  274.     }
  275.     else
  276.     {
  277. return HXR_FAIL;
  278.     }
  279. }
  280. break;
  281. case SMILMeta:
  282. {
  283.     CSmil1Meta* pMeta = makeMeta(pLayoutNode);
  284.     if(pMeta)
  285.     {
  286. pNode->m_pElement = pMeta;
  287. pMeta->m_ulDelay = 0;
  288. pMeta->m_ulTimestamp = 
  289.     INITIAL_STREAM0_TIMESTAMP;
  290. insertElementByTimestamp(pMeta);
  291.     }
  292.     else
  293.     {
  294. return HXR_FAIL;
  295.     }
  296. }
  297. break;
  298. default:
  299. break;
  300.     }
  301.     pLayoutNode = pNode->getNextChild();
  302. }
  303. if(bHasRegions)
  304. {
  305.     // send end-layout packet at TS 0
  306.     m_pEndLayout = new CSmil1EndLayout;
  307.     m_pEndLayout->m_ulDelay = 0;
  308.     m_pEndLayout->m_ulTimestamp = INITIAL_STREAM0_TIMESTAMP;
  309.     insertElementByTimestamp(m_pEndLayout);
  310. }
  311.     }
  312.     break;
  313.     
  314.     case SMILRNRendererList:
  315.     {
  316. SMIL1Node* pRendererNode = pNode->getFirstChild();
  317. while(pRendererNode && 
  318.     pRendererNode->m_tag == SMILRendererPreFetch)
  319. {
  320.     CSmil1RendererPreFetch* pRenderer = 
  321. makeRendererPreFetch(pRendererNode);
  322.     pRendererNode->m_pElement = pRenderer;
  323.     pRenderer->m_ulDelay = 0;
  324.     pRenderer->m_ulTimestamp = INITIAL_STREAM0_TIMESTAMP;
  325.     insertElementByTimestamp(pRenderer);
  326.     pRendererNode = pNode->getNextChild();
  327. }
  328.     }
  329.     break;
  330.     default:
  331.     break;
  332. }
  333. rc = createHeadElements(pNode->m_pNodeList);
  334. if (SUCCEEDED(rc))
  335. {
  336.     rc = removeFromNamespaceScope(pNode);
  337. }
  338.     }
  339.     return rc;
  340. }
  341. HX_RESULT
  342. CSmil1Parser::setInitialDelays(SMIL1NodeList* pNodeList)
  343. {
  344.     HX_RESULT rc = HXR_OK;
  345.     UINT16 nGroup = (UINT16)-1;
  346.     if(!pNodeList)
  347.     {
  348. return rc;
  349.     }
  350.     CHXSimpleList::Iterator i = pNodeList->Begin();
  351.     for(;i!=pNodeList->End();++i)
  352.     {
  353. if(HXR_OK != rc)
  354. {
  355.     return rc;
  356. }
  357. SMIL1Node* pNode = (SMIL1Node*)(*i);
  358. if(pNode->m_bDelete) // skip this puppy
  359. {
  360.     continue;
  361. }
  362. else if(pNode->m_tag == SMILAAnchor ||
  363.         pNode->m_tag == SMILSwitch)
  364. {
  365.     pNode = getTimelineDescendent(pNode);
  366.     if(!pNode)
  367.     {
  368. continue;
  369.     }
  370. }
  371. setInitialDelay(pNode);
  372. switch(pNode->m_tag)
  373. {
  374.     case SMILSeq:
  375.     {
  376. setInitialDelayOnSeq(pNode);
  377.     }
  378.     break;
  379.     case SMILPar:
  380.     {
  381. SMIL1Node* pThisNode =
  382.     getTimelineDescendent(pNode, NULL);
  383. while(pThisNode)
  384. {
  385.     setInitialDelay(pThisNode);
  386.     pThisNode =
  387. getTimelineDescendent(pNode, pThisNode);
  388. }
  389.     }
  390.     break;
  391. }
  392.     }
  393.     return rc;
  394. }
  395. void
  396. CSmil1Parser::setInitialDelay(SMIL1Node* pNode)
  397. {
  398.     if(pNode->m_pElement &&
  399. pNode->m_pElement->m_pTimelineElement &&
  400. !pNode->m_pElement->m_pTimelineElement->initialDelaySet())
  401.     {
  402. pNode->m_pElement->m_pTimelineElement->setDelay(0);
  403.     }
  404.     if(pNode->m_pNodeList)
  405.     {
  406. if(pNode->m_tag == SMILSeq ||
  407.     pNode->m_tag == SMILPar)
  408. {
  409.     if(pNode->m_pElement &&
  410. pNode->m_pElement->m_pTimelineElement &&
  411. pNode->m_pElement->m_ulDuration != (UINT32)-1)
  412.     {
  413. pNode->m_pElement->m_pTimelineElement->setDuration(
  414.     pNode->m_pElement->m_ulDuration);
  415.     }
  416. }
  417. if(pNode->m_tag == SMILSeq)
  418. {
  419.     setInitialDelayOnSeq(pNode);
  420. }
  421. //If the element doesn't exist or it does but the timelineElement
  422. // doesn't exist, or it does but there is no delay event, or there is
  423. // one but the delay is already set, then it's ok to set call
  424. // setInitialDelay():
  425. else if ((!pNode->m_pElement  ||
  426. !pNode->m_pElement->m_pTimelineElement)  ||
  427. //[SMIL 1.0 Compliance] Helps fix PR 14420:
  428. //Don't call this if pNode has an unresolved delay event:
  429. (!pNode->m_pElement->m_pTimelineElement->delayEvent()  ||
  430. pNode->m_pElement->m_pTimelineElement->initialDelaySet() ) )
  431. {
  432.     SMIL1Node* pThisNode = 
  433. getTimelineDescendent(pNode, NULL);
  434.     while(pThisNode)
  435.     {
  436. setInitialDelay(pThisNode);
  437. pThisNode = getTimelineDescendent(pNode, pThisNode);
  438.     }
  439. }
  440.     }
  441. }
  442. void 
  443. CSmil1Parser::setInitialDelayOnSeq(SMIL1Node* pNode)
  444. {
  445.     UINT16 nGroup = (UINT16)-1;
  446.     
  447.     SMIL1Node* pThisNode = getTimelineDescendent(pNode, NULL);
  448.     while(pThisNode)
  449.     {
  450. if(pThisNode->m_nGroup != nGroup)
  451. {
  452.     nGroup = pThisNode->m_nGroup;
  453.     setInitialDelay(pThisNode);
  454. }
  455. pThisNode = getTimelineDescendent(pNode, pThisNode);
  456.     }
  457. }
  458. HX_RESULT
  459. CSmil1Parser::assignGroupIndexes(SMIL1NodeList* pNodeList)
  460. {
  461.     HX_RESULT rc = HXR_OK;
  462.     if(!pNodeList)
  463.     {
  464. return rc;
  465.     }
  466.     UINT16 nGroup = 0;
  467.     CHXSimpleList::Iterator i = pNodeList->Begin();
  468.     for(; i != pNodeList->End(); ++i)
  469.     {
  470. if(HXR_OK != rc)
  471. {
  472.     return rc;
  473. }
  474. SMIL1Node* pNode = (SMIL1Node*)(*i);
  475. if(pNode->m_bDelete) // skip this puppy
  476. {
  477.     continue;
  478. }
  479. else if(pNode->m_tag == SMILAAnchor ||
  480.         pNode->m_tag == SMILSwitch)
  481. {
  482.     pNode = getTimelineDescendent(pNode);
  483.     if(!pNode)
  484.     {
  485. continue;
  486.     }
  487. }
  488. switch(pNode->m_tag)
  489. {
  490.     case SMILSeq:
  491.     {
  492. SMIL1Node* pThisNode =
  493.     getTimelineDescendent(pNode, NULL);
  494. while(pThisNode)
  495. {
  496.     rc = assignGroupIndexOnSeq(pThisNode, nGroup);
  497.     if(HXR_OK == rc)
  498.     {
  499. pThisNode =
  500.     getTimelineDescendent(pNode, pThisNode);
  501. nGroup++;
  502.     }
  503.     else
  504.     {
  505. break;
  506.     }
  507. }
  508.     }
  509.     break;
  510.     case SMILPar:
  511.     {
  512. // top-level par, each child has group 0
  513. SMIL1Node* pThisNode =
  514.     getTimelineDescendent(pNode, NULL);
  515. while(pThisNode)
  516. {
  517.     rc = assignGroupIndexOnPar(pThisNode, nGroup);
  518.     if(HXR_OK == rc)
  519.     {
  520. pThisNode =
  521.     getTimelineDescendent(pNode, pThisNode);
  522.     }
  523.     else
  524.     {
  525. break;
  526.     }
  527. }
  528.     }
  529.     break;
  530.     default:
  531.     break;
  532. }
  533.     }
  534.     return rc;
  535. }
  536. HX_RESULT
  537. CSmil1Parser::assignGroupIndexOnPar(SMIL1Node* pNode,
  538.    UINT16 nGroup)
  539. {
  540.     HX_RESULT rc = HXR_OK;
  541.     if(pNode->m_bDelete)
  542.     {
  543. return rc;
  544.     }
  545.     pNode->m_nGroup = nGroup;
  546.     pNode->m_repeatid.AppendULONG(nGroup);
  547.     if (isMediaObject(pNode))
  548.     {
  549. addGroup(pNode);
  550.     }
  551.     else if (SMILSeq == pNode->m_tag ||
  552.      SMILPar == pNode->m_tag)
  553.     {
  554. // top-level par, each child has group 0
  555. SMIL1Node* pThisNode =
  556.     getTimelineDescendent(pNode, NULL);
  557. while(pThisNode)
  558. {
  559.     rc = assignGroupIndexOnPar(pThisNode, nGroup);
  560.     if(HXR_OK == rc)
  561.     {
  562. pThisNode =
  563.     getTimelineDescendent(pNode, pThisNode);
  564.     }
  565.     else
  566.     {
  567. break;
  568.     }
  569. }
  570.     }
  571.     return rc;
  572. }
  573. HX_RESULT
  574. CSmil1Parser::assignGroupIndexOnSeq(SMIL1Node* pNode,
  575.    UINT16& nGroup)
  576. {
  577.     HX_RESULT rc = HXR_OK;
  578.     if(pNode->m_bDelete)
  579.     {
  580. return rc;
  581.     }
  582.     pNode->m_nGroup = nGroup;
  583.     pNode->m_repeatid.AppendULONG(nGroup);
  584.     if (isMediaObject(pNode))
  585.     {
  586. addGroup(pNode);
  587.     }
  588.     else if (SMILSeq == pNode->m_tag)
  589.     {
  590. SMIL1Node* pThisNode =
  591.     getTimelineDescendent(pNode, NULL);
  592. while(pThisNode)
  593. {
  594.     rc = assignGroupIndexOnSeq(pThisNode, nGroup);
  595.     if(HXR_OK == rc)
  596.     {
  597. pThisNode = getTimelineDescendent(pNode, pThisNode);
  598. if (pThisNode)
  599. {
  600.     if (isMediaObject(pThisNode)    ||
  601. SMILSeq == pThisNode->m_tag ||
  602. SMILPar == pThisNode->m_tag)
  603.     {
  604. nGroup++;
  605.     }
  606. }
  607.     }
  608.     else
  609.     {
  610. break;
  611.     }
  612. }
  613.     }
  614.     else if (SMILPar == pNode->m_tag)
  615.     {
  616. SMIL1Node* pThisNode =
  617.     getTimelineDescendent(pNode, NULL);
  618. while(pThisNode)
  619. {
  620.     rc = assignGroupIndexOnPar(pThisNode, nGroup);
  621.     if(HXR_OK == rc)
  622.     {
  623. pThisNode =
  624.     getTimelineDescendent(pNode, pThisNode);
  625.     }
  626.     else
  627.     {
  628. break;
  629.     }
  630. }
  631.     }
  632.     return rc;
  633. }
  634. BOOL 
  635. CSmil1Parser::isMediaObject(SMIL1Node* pNode)
  636. {
  637.     BOOL bResult = FALSE;
  638.     if (NULL == pNode || pNode->m_bDelete)
  639.     {
  640. goto cleanup;
  641.     }
  642.     switch(pNode->m_tag)
  643.     {
  644. case SMILRef:
  645. case SMILText:
  646. case SMILImg:
  647. case SMILAudio:
  648. case SMILVideo:
  649. case SMILAnimation:
  650. case SMILTextstream:
  651. {
  652.     bResult = TRUE;
  653. }
  654. break;
  655. default:
  656. break;
  657.     }
  658. cleanup:
  659.     return bResult;
  660. }
  661. HX_RESULT
  662. CSmil1Parser::addGroup(SMIL1Node* pNode)
  663. {
  664.     HX_RESULT rc = HXR_OK;
  665.     // set group info information
  666.     CSmil1AddGroup* pAddGroup = 0;
  667.     if(m_pAddGroupMap->Lookup(pNode->m_nGroup, (void*&)pAddGroup))
  668.     {
  669. // we don't count self-replicated elements as they
  670. // share the same track ID
  671. if (pNode->m_repeatTag == RepeatUnknown)
  672. {
  673.     pAddGroup->m_nTotalTracks++;
  674.     if(pNode->m_pElement &&
  675.        pNode->m_pElement->m_ulDelay == 0)
  676.     {
  677. pAddGroup->m_nInitTracks++;
  678.     }
  679. }
  680.     }
  681.     else
  682.     {
  683. CSmil1AddGroup* pAddGroup = new CSmil1AddGroup;
  684. pAddGroup->m_nGroup = pNode->m_nGroup;
  685. // reference PAR properties in group
  686. if(pNode->m_pDependency &&
  687.    pNode->m_pDependency->m_tag == SMILPar &&
  688.    hasParParent(pNode))
  689. {
  690.     IHXValues* pValues = pNode->m_pDependency->m_pValues;
  691.     if(pValues)
  692.     {
  693. pAddGroup->m_pValues = pValues;
  694. pAddGroup->m_pValues->AddRef();
  695.     }
  696.     pAddGroup->m_ulDuration = 
  697. pNode->m_pDependency->m_pElement->m_ulDuration;
  698. }
  699. // XXXJHUG  -- If the group is from a Seq, we still want
  700. // to pass along the Title, author, copyright & abstract from
  701. // the dependant parrent sequence group.
  702. if (pNode->m_pDependency &&
  703.     pNode->m_pDependency->m_tag == SMILSeq)
  704. {
  705.     IHXValues* pValues = pNode->m_pDependency->m_pValues;
  706.     if(pValues)
  707.     {
  708. // XXXJH should use CCF
  709. pAddGroup->m_pValues = new CHXHeader();
  710. IHXBuffer* pBuf = NULL;
  711. const char* name = NULL;
  712. pAddGroup->m_pValues->AddRef();
  713. if (SUCCEEDED(pValues->GetFirstPropertyCString(name, pBuf)))
  714. {
  715.     do
  716.     {
  717. if (strcmp("title",name)==0 ||
  718.     strcmp("author",name)==0 ||
  719.     strcmp("abstract",name)==0 ||
  720.     strcmp("copyright",name)==0)
  721. {
  722.     pAddGroup->m_pValues->SetPropertyCString(name, pBuf);
  723. }
  724. HX_RELEASE(pBuf);
  725.     }
  726.     while(SUCCEEDED(pValues->GetNextPropertyCString(name, pBuf)));
  727. }
  728.     }
  729.     // the duration for a sequence is dependant on the elements
  730.     // within the sequence.
  731. }
  732. (*m_pAddGroupMap)[pNode->m_nGroup] = pAddGroup;
  733. pAddGroup->m_nTotalTracks = 1;
  734. if(pNode->m_pElement &&
  735.     pNode->m_pElement->m_ulDelay == 0)
  736. {
  737.     pAddGroup->m_nInitTracks = 1;
  738. }
  739.     }
  740.     return rc;
  741. }
  742. HX_RESULT
  743. CSmil1Parser::createBodyElements(SMIL1NodeList* pNodeList)
  744. {
  745.     HX_RESULT rc = HXR_OK;
  746.     if(!pNodeList)
  747.     {
  748. return rc;
  749.     }
  750.     if(!m_pNodeDependencies)
  751.     {
  752. m_pNodeDependencies = new CHXStack;
  753.     }
  754.     if(!m_pAnchorStack)
  755.     {
  756. m_pAnchorStack = new CHXStack;
  757.     }
  758.     if(!m_pTrackHintList)
  759.     {
  760. m_pTrackHintList = new CHXSimpleList;
  761.     }
  762.     UINT32 ulTrackHint = 1;
  763.     CHXSimpleList::Iterator i;
  764.     for(i=pNodeList->Begin();i!=pNodeList->End();++i)
  765.     {
  766. if(HXR_OK != rc)
  767. {
  768.     return rc;
  769. }
  770. SMIL1Node* pNode = (SMIL1Node*)(*i);
  771. if(pNode->m_bDelete) // skip this puppy
  772. {
  773.     continue;
  774. }
  775. rc = addToNamespaceScope(pNode);
  776. if (FAILED(rc))
  777. {
  778.     return rc;
  779. }
  780. switch(pNode->m_tag)
  781. {
  782.     case SMILSeq:
  783.     {
  784. CSmil1SeqElement* pElement = makeSeqElement(pNode);
  785. if(!pElement)
  786. {
  787.     return HXR_FAIL;
  788. }
  789. pNode->m_pElement = pElement;
  790. CSmil1TimelineSeq* pTimelineSeq =
  791.     new CSmil1TimelineSeq(pElement, this);
  792. pElement->m_pTimelineElement = pTimelineSeq;
  793. if(!m_pCurrentDependentNode) // at the top
  794. {
  795.     //pNode->m_nGroup = (UINT16)-1;   // top level
  796. }
  797. else
  798. {
  799.     pNode->m_pDependency = m_pCurrentDependentNode;
  800.     if(!hasParParent(pNode))
  801.     {
  802. //pNode->m_nGroup = 
  803. //    m_pCurrentDependentNode->m_nGroup + 1;
  804.     }
  805.     else
  806.     {
  807. //pNode->m_nGroup = 
  808. //    m_pCurrentDependentNode->m_nGroup;
  809.     }
  810. }
  811. m_pCurrentDependentNode = pNode;
  812. m_pNodeDependencies->Push(m_pCurrentDependentNode);
  813. ulTrackHint = 1;
  814. m_pTrackHintList->AddTail((void*)ulTrackHint);
  815.     }
  816.     break;
  817.     case SMILPar:
  818.     {
  819. CSmil1ParElement* pElement = makeParElement(pNode);
  820. if(!pElement)
  821. {
  822.     return HXR_FAIL;
  823. }
  824. pNode->m_pElement = pElement;
  825. CSmil1TimelinePar* pTimelinePar = 
  826.     new CSmil1TimelinePar(pElement, this);
  827. pElement->m_pTimelineElement = pTimelinePar;
  828. if(!m_pCurrentDependentNode) // at the top
  829. {
  830.     // pNode->m_nGroup = 0;
  831. }
  832. else
  833. {
  834.     pNode->m_pDependency = m_pCurrentDependentNode;
  835.     if(!hasParParent(pNode))
  836.     {
  837. //pNode->m_nGroup = 
  838. //    m_pCurrentDependentNode->m_nGroup + 1;
  839.     }
  840.     else
  841.     {
  842. //pNode->m_nGroup = m_pCurrentDependentNode->m_nGroup;
  843.     }
  844. }
  845. if(firstDependentChild(pNode) || m_pCurrentDependentNode == 0)
  846. {
  847.     ulTrackHint = 1;
  848.     m_pTrackHintList->AddTail((void*)ulTrackHint);
  849. }
  850. else
  851. {
  852.     if(m_pTrackHintList->GetCount() > 0)
  853.     {
  854. ulTrackHint = (UINT32)m_pTrackHintList->RemoveTail();
  855.     }
  856.     m_pTrackHintList->AddTail((void*)++ulTrackHint);
  857. }
  858. m_pCurrentDependentNode = pNode;
  859. m_pNodeDependencies->Push(m_pCurrentDependentNode);
  860.     }
  861.     break;
  862.     case SMILEndSeq:
  863.     {
  864. m_pCurrentDependentNode = 
  865.     (SMIL1Node*)m_pNodeDependencies->Pop();
  866. if(m_pTrackHintList->GetCount() > 0)
  867. {
  868.     m_pTrackHintList->RemoveTail();
  869. }
  870.     }
  871.     break;
  872.     case SMILEndPar:
  873.     {
  874. m_pCurrentDependentNode = 
  875.     (SMIL1Node*)m_pNodeDependencies->Pop();
  876. if(m_pTrackHintList->GetCount() > 0)
  877. {
  878.     m_pTrackHintList->RemoveTail();
  879. }
  880.     }
  881.     break;
  882.     case SMILAAnchor:
  883.     {
  884. CSmil1AAnchorElement* pElement = makeAAnchorElement(pNode);
  885. if(pElement)
  886. {
  887.     pNode->m_pElement = pElement;
  888.     m_pAnchorStack->Push(m_pCurrentAnchor);
  889.     m_pCurrentAnchor = pElement;
  890. }
  891.     }
  892.     break;
  893.     case SMILEndAAnchor:
  894.     {
  895. m_pCurrentAnchor = (CSmil1AAnchorElement*)m_pAnchorStack->Pop();
  896.     }
  897.     break;
  898.     case SMILAnchor:
  899.     {
  900. CSmil1AnchorElement* pElement = makeAnchorElement(pNode);
  901. if(pElement)
  902. {
  903.     pNode->m_pElement = pElement;
  904.     //[SMIL 1.0 compliance] Helps fix PR 26471:
  905.     // In order to get a notification that we have a resolved
  906.     // event-based begin time, we need to be a
  907.     // timeline element:
  908.     CSmil1TimelineAnchor* pTimelineAnchor = 
  909. new CSmil1TimelineAnchor(pElement, this);
  910.     pElement->m_pTimelineElement = pTimelineAnchor;
  911.     // add link to parent
  912.     SMIL1Node* pParent = pNode->m_pParent;
  913.     if(pParent->m_pElement)
  914.     {
  915. pParent->m_pElement->m_pHyperlinks->AddTail(pElement);
  916.     }
  917.     if(!m_pCurrentDependentNode)
  918.     { 
  919. //anchor should NEVER be top element:
  920. HX_ASSERT(m_pCurrentDependentNode);
  921.     } 
  922.     else 
  923.     { 
  924. pNode->m_pDependency = m_pCurrentDependentNode;
  925.     } 
  926.     if(firstDependentChild(pNode) || m_pCurrentDependentNode == 0)
  927.     { 
  928. ulTrackHint = 1;
  929. m_pTrackHintList->AddTail((void*)ulTrackHint);
  930.     } 
  931.     else 
  932.     { 
  933. if(m_pTrackHintList->GetCount() > 0)
  934. {
  935.     ulTrackHint = (UINT32)m_pTrackHintList->RemoveTail();
  936. }
  937. m_pTrackHintList->AddTail((void*)++ulTrackHint);
  938.     } 
  939.     m_pCurrentDependentNode = pNode;
  940.     m_pNodeDependencies->Push(m_pCurrentDependentNode);
  941.     //end of part of fix for PR 26471.
  942. }
  943.     }
  944.     break;
  945.     case SMILRef:
  946.     case SMILText:
  947.     case SMILImg:
  948.     case SMILAudio:
  949.     case SMILVideo:
  950.     case SMILAnimation:
  951.     case SMILTextstream:
  952.     {
  953. CSmil1Source* pSource = makeSource(pNode);
  954. if(!pSource)
  955. {
  956.     return HXR_FAIL;
  957. }
  958. m_bContainsSource = TRUE;
  959. pNode->m_pElement = pSource;
  960. CSmil1TimelineElement* pTimelineElement = 
  961.     new CSmil1TimelineElement(pSource, this);
  962. pNode->m_pElement->m_pTimelineElement = pTimelineElement;
  963. // attach any links
  964. if(m_pCurrentAnchor)
  965. {
  966.     pSource->m_pHyperlinks->AddTail(m_pCurrentAnchor);
  967. }
  968. if(!m_pCurrentDependentNode)
  969. {
  970.     // make it behave like it's in a SEQ
  971.     pNode->m_pDependency = 0;
  972.     //pNode->m_nGroup = 0;
  973.     m_pCurrentDependentNode = pNode;
  974.     ulTrackHint = 1;
  975.     m_pTrackHintList->AddTail((void*)ulTrackHint);
  976. }
  977. else
  978. {
  979.     pNode->m_pDependency = m_pCurrentDependentNode;
  980.     if(inSeq(pNode))
  981.     {
  982. if(firstDependentChild(pNode))
  983. {
  984.     ulTrackHint = 1;
  985.     m_pTrackHintList->AddTail((void*)ulTrackHint);
  986. }
  987. else
  988. {
  989.     if(m_pTrackHintList->GetCount() > 0)
  990.     {
  991. ulTrackHint = 
  992.     (UINT32)m_pTrackHintList->RemoveTail();
  993.     }
  994.     m_pTrackHintList->AddTail((void*)++ulTrackHint);
  995. }
  996.     }
  997.     else
  998.     {
  999. if(firstDependentChild(pNode))
  1000. {
  1001.     ulTrackHint = 1;
  1002.     m_pTrackHintList->AddTail((void*)ulTrackHint);
  1003. }
  1004.     }
  1005.     if(inSeq(pNode) && !hasParParent(pNode))
  1006.     {
  1007. if(firstDependentChild(pNode))
  1008. {
  1009.     //pNode->m_nGroup = m_pCurrentDependentNode->m_nGroup;
  1010. }
  1011. else
  1012. {
  1013.     //pNode->m_nGroup = 
  1014. //m_pCurrentDependentNode->m_nGroup + 1;
  1015. }
  1016. m_pCurrentDependentNode = pNode;
  1017.     }
  1018.     else if(inSeq(pNode))
  1019.     {
  1020. //pNode->m_nGroup = m_pCurrentDependentNode->m_nGroup;
  1021. m_pCurrentDependentNode = pNode;
  1022.     }
  1023.     else // in PAR
  1024.     {
  1025. // pNode->m_nGroup = m_pCurrentDependentNode->m_nGroup;
  1026.     }
  1027. }
  1028. // set track hint info
  1029. BOOL bFirstHint = TRUE;
  1030. CHXSimpleList::Iterator hintIter = m_pTrackHintList->Begin();
  1031. for(; hintIter != m_pTrackHintList->End(); ++hintIter)
  1032. {
  1033.     char tmpBuf[20]; /* Flawfinder: ignore */
  1034.     UINT32 ulTrackHint = (UINT32)(*hintIter);
  1035.     if(bFirstHint)
  1036.     {
  1037. sprintf(tmpBuf, "%d", ulTrackHint); /* Flawfinder: ignore */
  1038. bFirstHint = FALSE;
  1039.     }
  1040.     else
  1041.     {
  1042. sprintf(tmpBuf, ".%d", ulTrackHint); /* Flawfinder: ignore */
  1043.     }
  1044.     pNode->m_trackHint += tmpBuf;
  1045. }
  1046.     }
  1047.     break;
  1048.     default:
  1049.     break;
  1050. }
  1051. rc = createBodyElements(pNode->m_pNodeList);
  1052. if (SUCCEEDED(rc))
  1053. {
  1054.     rc = removeFromNamespaceScope(pNode);
  1055. }
  1056.     }
  1057.     return rc;
  1058. }
  1059. HX_RESULT
  1060. CSmil1Parser::expandRepeatElements(SMIL1NodeList* pNodeList)
  1061. {
  1062.     // walk through tree and expand any "repeat" attributes
  1063.     
  1064.     HX_RESULT rc = HXR_OK;
  1065.     if(!pNodeList)
  1066.     {
  1067. return rc;
  1068.     }
  1069.     LISTPOSITION lPos = pNodeList->GetHeadPosition();
  1070.     while (lPos && HXR_OK == rc)
  1071.     {
  1072. SMIL1Node* pNode = (SMIL1Node*)pNodeList->GetAt(lPos);
  1073. if(pNode->m_bDelete) // skip this puppy
  1074. {
  1075.     pNodeList->GetNext(lPos);
  1076.     continue;
  1077. }
  1078. if(pNode->m_pValues)
  1079. {
  1080.     const char* pName = 0;
  1081.     IHXBuffer* pBuf = 0;
  1082.     if (!pNode->m_bRepeatHandled &&
  1083. HXR_OK == pNode->m_pValues->GetPropertyCString("repeat", pBuf))
  1084.     {
  1085. BOOL     bRepeatIndefinite = FALSE;
  1086. const char* pRepeatCount = (const char*)pBuf->GetBuffer();
  1087. if(pRepeatCount)
  1088. {
  1089.     INT32 lRepeatCount = 0;
  1090.     if(strcmp(pRepeatCount, "indefinite") == 0)
  1091.     {
  1092. bRepeatIndefinite = TRUE;
  1093. lRepeatCount = 2;
  1094.     }
  1095.     else
  1096.     {
  1097. lRepeatCount = atol(pRepeatCount);
  1098.     }
  1099.     if(lRepeatCount == 0)
  1100.     {
  1101. pNode->m_bDelete = TRUE;
  1102.     }
  1103.     else if(lRepeatCount > 1)
  1104.     {
  1105. // build a <seq>/</seq> around the repeated element...
  1106. SMIL1Node* pSeqNode = NULL;
  1107. SMIL1Node* pSeqEndNode = NULL;
  1108. createParent(pNode, SMILSeq, pSeqNode, pSeqEndNode);
  1109. SMIL1Node* pNodeCopy = NULL;
  1110. BOOL   bOverWrite = TRUE;
  1111. for(INT32 lCount = 0; lCount < lRepeatCount;
  1112.     ++lCount)
  1113. {
  1114.     // we want to keep the original ids for the
  1115.     // 1st repeat so that we don't break any links
  1116.     if (0 == lCount)
  1117.     {
  1118. pNodeCopy = new SMIL1Node(*pNode, TRUE, this);
  1119. bOverWrite = TRUE;
  1120.     }
  1121.     else
  1122.     {
  1123. pNodeCopy = new SMIL1Node(*pNode, FALSE, this);
  1124. bOverWrite = FALSE;
  1125.     }
  1126.     pNodeCopy->m_pParent = pSeqNode;
  1127.     pNodeCopy->m_pNodeList->m_pParentNode = pNodeCopy;
  1128.     pNodeCopy->m_bRepeatHandled = TRUE;
  1129.     // after the 1st repeat, mark the rest of repeats
  1130.     // as replica(used in counting tracks etc.)
  1131.     if (lCount > 0)
  1132.     {
  1133. if (bRepeatIndefinite)
  1134. {
  1135.     if (pNodeCopy->m_tag == SMILSeq ||
  1136. pNodeCopy->m_tag == SMILPar)
  1137.     {
  1138. // set indefinite repeat tag on seq
  1139. // will be used in constructing timeline elements
  1140. pSeqNode->m_repeatTag = RepeatIndefiniteOnMe;
  1141. pNodeCopy->m_repeatTag = RepeatIndefiniteOnGroup;
  1142. markRepeatReplica(pNodeCopy->m_pNodeList, RepeatIndefiniteOnGroup);
  1143.     }
  1144.     else
  1145.     {
  1146. pNodeCopy->m_repeatTag = RepeatIndefiniteOnMe;
  1147.     }
  1148. }
  1149. else
  1150. {
  1151.     pNodeCopy->m_repeatTag = RepeatReplica;
  1152.     
  1153.     if (pNodeCopy->m_tag == SMILSeq ||
  1154. pNodeCopy->m_tag == SMILPar)
  1155.     {
  1156. markRepeatReplica(pNodeCopy->m_pNodeList, RepeatReplica);
  1157.     }
  1158. }
  1159.     }
  1160.     mapID(pNodeCopy, bOverWrite);
  1161.     //Fix for PR 13119: internal elements (source
  1162.     // elements, especially) of a repeated <seq> or
  1163.     // <par> tag were not getting mapped and thus
  1164.     // never played, so we need to map the IDs of
  1165.     // all in the m_pNodeList of the pNodeCopy:
  1166.     mapChildrenIDs(pNodeCopy->m_pNodeList, bOverWrite);
  1167.     pSeqNode->m_pNodeList->AddTail(pNodeCopy);
  1168. }
  1169. pSeqNode->m_pNodeList->AddTail(pSeqEndNode);
  1170. // special case to ensure all repeated elements
  1171. // are within the same group(share the same timeline)
  1172. if (!hasParParent(pSeqNode))
  1173. {
  1174.     SMIL1Node* pParNode = NULL;
  1175.     SMIL1Node* pParEndNode = NULL;
  1176.     createParent(pSeqNode, SMILPar, pParNode, pParEndNode);
  1177.     pParNode->m_repeatTag = pSeqNode->m_repeatTag;
  1178.     pParNode->m_pNodeList->AddTail(pSeqNode);     
  1179.     pParNode->m_pNodeList->AddTail(pParEndNode);
  1180.     // now add the list to the parent...
  1181.     pNodeList->InsertBefore(lPos, pParNode);
  1182.     pNode->m_bDelete = TRUE; // delete original node
  1183.     pNode = pParNode;
  1184. }
  1185. else
  1186. {
  1187.     // now add the list to the parent...
  1188.     pNodeList->InsertBefore(lPos, pSeqNode);
  1189.     pNode->m_bDelete = TRUE; // delete original node
  1190.     pNode = pSeqNode;
  1191. }
  1192.     }
  1193. }
  1194.     }
  1195. }
  1196. // breadth first
  1197. rc = expandRepeatElements(pNode->m_pNodeList);
  1198. pNodeList->GetNext(lPos);
  1199.     }
  1200.     return rc;
  1201. }
  1202. HX_RESULT
  1203. CSmil1Parser::createParent (SMIL1Node* pChildNode, 
  1204.    SMIL1NodeTag tag,
  1205.    SMIL1Node*& pParent,
  1206.    SMIL1Node*& pParentEnd)
  1207. {
  1208.     HX_RESULT hr = HXR_OK;
  1209.     pParent = NULL;
  1210.     pParentEnd = NULL;
  1211.     if (!pChildNode)
  1212.     {
  1213. hr = HXR_FAILED;
  1214. goto cleanup;
  1215.     }
  1216.     pParent = new SMIL1Node;     
  1217.     pParent->m_pParent = pChildNode->m_pParent;
  1218.     pParent->m_tag = tag;
  1219.     
  1220.     pParent->m_pNodeList = new SMIL1NodeList;
  1221.     pParent->m_pNodeList->m_pParentNode = pParent;
  1222.     
  1223.     pParentEnd = new SMIL1Node;
  1224.     pParentEnd->m_pParent = pParent;
  1225.     if (SMILPar == tag)
  1226.     {
  1227. pParent->m_name = "par";
  1228. pParentEnd->m_name = "par";
  1229. pParentEnd->m_id = assignID("CLOSE-par");
  1230. pParentEnd->m_tag = SMILEndPar;
  1231.     }
  1232.     else if (SMILSeq == tag)
  1233.     {
  1234. pParent->m_name = "seq";
  1235. pParentEnd->m_name = "seq";
  1236. pParentEnd->m_id = assignID("CLOSE-seq");
  1237. pParentEnd->m_tag = SMILEndSeq;
  1238.     }
  1239.     else
  1240.     {
  1241. HX_ASSERT(FALSE);
  1242. hr = HXR_FAILED;
  1243. goto cleanup;
  1244.     }
  1245.     
  1246.     mapID(pParent, TRUE);
  1247.     mapID(pParentEnd, TRUE);
  1248. cleanup:
  1249.     return hr;
  1250. }
  1251. void
  1252. CSmil1Parser::resetTimeline()
  1253. {
  1254.     if (m_pTimelineElementManager)
  1255.     {
  1256.         m_pTimelineElementManager->resetTimeline();
  1257.     }
  1258. }
  1259. SMIL1Node*
  1260. CSmil1Parser::getTimelineDescendent(SMIL1Node* pParentNode)
  1261. {
  1262.     SMIL1Node* pDescendentNode = NULL;
  1263.     CHXSimpleList* pNodeList = pParentNode->m_pNodeList;
  1264.     if(!pNodeList)
  1265.     {
  1266. return pDescendentNode;
  1267.     }
  1268.     CHXSimpleList::Iterator i;
  1269.     for(i=pNodeList->Begin();i!=pNodeList->End();++i)
  1270.     {
  1271. SMIL1Node* pNode = (SMIL1Node*)(*i);
  1272. if(pNode->m_bDelete)
  1273. {
  1274.     continue;
  1275. }
  1276. if(pNode->m_tag == SMILAAnchor ||
  1277.    pNode->m_tag == SMILSwitch)
  1278. {
  1279.     pNode = getTimelineDescendent(pNode);
  1280.     if(pNode)
  1281.     {
  1282. pDescendentNode = pNode;
  1283. break;
  1284.     }
  1285. }
  1286. else
  1287. {
  1288.     if(pNode->m_tag == SMILSeq ||
  1289. pNode->m_tag == SMILPar ||
  1290. pNode->m_tag == SMILRef ||
  1291. pNode->m_tag == SMILText ||
  1292. pNode->m_tag == SMILImg ||
  1293. pNode->m_tag == SMILAudio ||
  1294. pNode->m_tag == SMILVideo ||
  1295. pNode->m_tag == SMILAnimation ||
  1296. pNode->m_tag == SMILTextstream ||
  1297. pNode->m_tag == SMILAnchor)
  1298.     {
  1299. pDescendentNode = pNode;
  1300. break;
  1301.     }
  1302. }
  1303.     }
  1304.     return pDescendentNode;
  1305. }
  1306. SMIL1Node*
  1307. CSmil1Parser::getTimelineDescendent(SMIL1Node* pParentNode, SMIL1Node* pSiblingNode)
  1308. {
  1309.     SMIL1Node* pFirstDescendent = getTimelineDescendent(pParentNode);
  1310.     if(!pSiblingNode)
  1311.     {
  1312. return pFirstDescendent;
  1313.     }
  1314.     // first, find parent of sibling
  1315.     SMIL1Node* pSiblingParent = pSiblingNode->m_pParent;
  1316.     while(pSiblingParent &&
  1317.   pSiblingParent->m_tag != SMILSeq &&
  1318.   pSiblingParent->m_tag != SMILPar)
  1319.     {
  1320. pSiblingParent = pSiblingParent->m_pParent;
  1321.     }
  1322.     if(!pSiblingParent)
  1323.     {
  1324. return NULL;
  1325.     }
  1326.     // now find the sibling, then next sibling will be 
  1327.     // returned. Brain damaged, but what are ya gonna do?
  1328.     BOOL bFoundSibling = FALSE;
  1329.     SMIL1Node* pNewSibling = NULL;
  1330.     CHXSimpleList::Iterator i = pSiblingParent->m_pNodeList->Begin();
  1331.     for(; i != pSiblingParent->m_pNodeList->End() && !pNewSibling; ++i)
  1332.     {
  1333. SMIL1Node* pThisNode = (SMIL1Node*)(*i);
  1334. if(pThisNode->m_bDelete)
  1335. {
  1336.     continue;
  1337. }
  1338. if(pThisNode->m_tag == SMILAAnchor ||
  1339.     pThisNode->m_tag == SMILSwitch)
  1340. {
  1341.     CHXSimpleList::Iterator j = pThisNode->m_pNodeList->Begin();
  1342.     for(; j != pThisNode->m_pNodeList->End(); ++j)
  1343.     {
  1344. SMIL1Node* pChildNode = (SMIL1Node*)(*j);
  1345. if(pChildNode->m_bDelete)
  1346. {
  1347.     continue;
  1348. }
  1349. if(pChildNode == pSiblingNode)
  1350. {
  1351.     bFoundSibling = TRUE;
  1352.     break;
  1353. }
  1354. else if(bFoundSibling)
  1355. {
  1356.     pNewSibling = pChildNode;
  1357.     break;
  1358. }
  1359.     }
  1360. }
  1361. else
  1362. {
  1363.     if(pThisNode == pSiblingNode)
  1364.     {
  1365. bFoundSibling = TRUE;
  1366.     }
  1367.     else if(bFoundSibling)
  1368.     {
  1369. pNewSibling = pThisNode;
  1370. break;
  1371.     }
  1372. }
  1373.     }
  1374.     return pNewSibling;
  1375. }
  1376. HX_RESULT
  1377. CSmil1Parser::constructTimelineElements(SMIL1NodeList* pNodeList)
  1378. {
  1379.     HX_RESULT rc = HXR_OK;
  1380.     if(!pNodeList)
  1381.     {
  1382. return rc;
  1383.     }
  1384.     CHXSimpleList::Iterator i;
  1385.     for(i=pNodeList->Begin();i!=pNodeList->End();++i)
  1386.     {
  1387. if(HXR_OK != rc)
  1388. {
  1389.     return rc;
  1390. }
  1391. SMIL1Node* pNode = (SMIL1Node*)(*i);
  1392. if(pNode->m_bDelete) // skip this puppy
  1393. {
  1394.     continue;
  1395. }
  1396. switch(pNode->m_tag)
  1397. {
  1398.     case SMILSeq:
  1399.     {
  1400. SMIL1Node* pChildNode = getTimelineDescendent(pNode, NULL);
  1401. CSmil1TimelineElement* pPrevElement = NULL;
  1402. UINT16 uPrevGroup = (UINT16)-1;
  1403. while(pChildNode)
  1404. {
  1405.     if (pChildNode->m_pElement &&
  1406. pChildNode->m_pElement->m_pTimelineElement)
  1407.     {
  1408. pNode->m_pElement->m_pTimelineElement->addChild(
  1409. pChildNode->m_pElement->m_pTimelineElement);
  1410. if(pPrevElement &&
  1411.    uPrevGroup == pChildNode->m_nGroup)
  1412. {
  1413.     pPrevElement->setDependent(pChildNode->m_pElement->m_pTimelineElement);
  1414. }
  1415. pPrevElement = pChildNode->m_pElement->m_pTimelineElement;
  1416. uPrevGroup = pChildNode->m_nGroup;
  1417.     }
  1418.     // there is no dependent on pChildNode which would repeat 
  1419.     // itself indefinitely within the same seq
  1420.     if (pChildNode->m_repeatTag == RepeatIndefiniteOnMe)
  1421.     {
  1422. break;
  1423.     }
  1424.     
  1425.     pChildNode = getTimelineDescendent(pNode, pChildNode);
  1426. }
  1427.     }
  1428.     break;
  1429.     case SMILPar:
  1430.     {
  1431. SMIL1Node* pChildNode = getTimelineDescendent(pNode, NULL);
  1432. while(pChildNode)
  1433. {
  1434.     if(pChildNode->m_pElement &&
  1435.        pChildNode->m_pElement->m_pTimelineElement)
  1436.     {
  1437. pNode->m_pElement->m_pTimelineElement->addChild(
  1438.     pChildNode->m_pElement->m_pTimelineElement);
  1439.     }
  1440.     pChildNode = getTimelineDescendent(pNode, pChildNode);
  1441. }
  1442.     }
  1443.     break;
  1444.     default:
  1445.     break;
  1446. }
  1447. rc = constructTimelineElements(pNode->m_pNodeList);
  1448.     }
  1449.     return rc;
  1450. }
  1451. HX_RESULT
  1452. CSmil1Parser::handleNextElement(CSmil1ElementHandler* pHandler)
  1453. {
  1454.     HX_RESULT rc = HXR_OK;
  1455.     if(m_pPacketQueue->GetCount() > 0)
  1456.     {
  1457. CSmil1Element* pElement = (CSmil1Element*)m_pPacketQueue->RemoveHead();
  1458. pElement->m_pHandler = pHandler;
  1459. rc = pElement->handleElement();
  1460.     }
  1461.     else if(m_bTimestampsResolved)
  1462.     {
  1463. rc = HXR_STREAM_DONE;
  1464.     }
  1465.     else
  1466.     {
  1467. rc = HXR_NO_DATA;
  1468.     }
  1469.     return rc;
  1470. }
  1471. void
  1472. CSmil1Parser::initTagAttributes()
  1473. {
  1474.     if(!m_pTagAttributeMap)
  1475.     {
  1476. m_pTagAttributeMap = new CHXMapLongToObj;
  1477.     }
  1478.     CHXMapStringToOb* pStringMap = 0;
  1479.     // SMILSmil
  1480.     pStringMap = new CHXMapStringToOb;
  1481.     (*pStringMap)["id"] = 0;
  1482.     (*m_pTagAttributeMap)[SMILSmil] = pStringMap;
  1483.     // SMILHead
  1484.     pStringMap = new CHXMapStringToOb;
  1485.     (*pStringMap)["id"] = 0;
  1486.     (*m_pTagAttributeMap)[SMILHead] = pStringMap;
  1487.     // SMILBasicLayout
  1488.     pStringMap = new CHXMapStringToOb;
  1489.     (*pStringMap)["id"] = 0;
  1490.     (*pStringMap)["type"] = 0;
  1491.     (*m_pTagAttributeMap)[SMILBasicLayout] = pStringMap;
  1492.     // SMILRegion
  1493.     pStringMap = new CHXMapStringToOb;
  1494.     (*pStringMap)["id"] = 0;
  1495.     (*pStringMap)["title"] = 0;
  1496.     (*pStringMap)["height"] = 0;
  1497.     (*pStringMap)["width"] = 0;
  1498.     (*pStringMap)["background-color"] = 0;
  1499.     (*pStringMap)["left"] = 0;
  1500.     (*pStringMap)["top"] = 0;
  1501.     (*pStringMap)["z-index"] = 0;
  1502.     (*pStringMap)["fit"] = 0;
  1503.     (*pStringMap)["skip-content"] = 0;
  1504.     (*m_pTagAttributeMap)[SMILRegion] = pStringMap;
  1505.     // SMILRootLayout
  1506.     pStringMap = new CHXMapStringToOb;
  1507.     (*pStringMap)["id"] = 0;
  1508.     (*pStringMap)["title"] = 0;
  1509.     (*pStringMap)["height"] = 0;
  1510.     (*pStringMap)["width"] = 0;
  1511.     (*pStringMap)["background-color"] = 0;
  1512.     (*pStringMap)["overflow"] = 0;
  1513.     (*pStringMap)["skip-content"] = 0;
  1514.     (*m_pTagAttributeMap)[SMILRootLayout] = pStringMap;
  1515.     // SMILMeta
  1516.     pStringMap = new CHXMapStringToOb;
  1517.     (*pStringMap)["name"] = 0;
  1518.     (*pStringMap)["content"] = 0;
  1519.     (*pStringMap)["skip-content"] = 0;
  1520.     (*m_pTagAttributeMap)[SMILMeta] = pStringMap;
  1521.     // SMILBody
  1522.     pStringMap = new CHXMapStringToOb;
  1523.     (*pStringMap)["id"] = 0;
  1524.     (*m_pTagAttributeMap)[SMILBody] = pStringMap;
  1525.     // SMILPar
  1526.     pStringMap = new CHXMapStringToOb;
  1527.     (*pStringMap)["id"] = 0;
  1528.     (*pStringMap)["title"] = 0;
  1529.     (*pStringMap)["abstract"] = 0;
  1530.     (*pStringMap)["author"] = 0;
  1531.     (*pStringMap)["copyright"] = 0;
  1532.     (*pStringMap)["endsync"] = 0;
  1533.     (*pStringMap)["dur"] = 0;
  1534.     (*pStringMap)["repeat"] = 0;
  1535.     (*pStringMap)["region"] = 0;
  1536.     (*pStringMap)["begin"] = 0;
  1537.     (*pStringMap)["end"] = 0;
  1538.     (*pStringMap)["system-bitrate"] = 0;
  1539.     (*pStringMap)["system-language"] = 0;
  1540.     (*pStringMap)["system-required"] = 0;
  1541.     (*pStringMap)["system-screen-size"] = 0;
  1542.     (*pStringMap)["system-screen-depth"] = 0;
  1543.     (*pStringMap)["system-captions"] = 0;
  1544.     (*pStringMap)["system-overdub-or-caption"] = 0;
  1545.     (*m_pTagAttributeMap)[SMILPar] = pStringMap;
  1546.     // SMILSeq
  1547.     pStringMap = new CHXMapStringToOb;
  1548.     (*pStringMap)["id"] = 0;
  1549.     (*pStringMap)["title"] = 0;
  1550.     (*pStringMap)["abstract"] = 0;
  1551.     (*pStringMap)["author"] = 0;
  1552.     (*pStringMap)["copyright"] = 0;
  1553.     (*pStringMap)["dur"] = 0;
  1554.     (*pStringMap)["repeat"] = 0;
  1555.     (*pStringMap)["region"] = 0;
  1556.     (*pStringMap)["begin"] = 0;
  1557.     (*pStringMap)["end"] = 0;
  1558.     (*pStringMap)["system-bitrate"] = 0;
  1559.     (*pStringMap)["system-language"] = 0;
  1560.     (*pStringMap)["system-required"] = 0;
  1561.     (*pStringMap)["system-screen-size"] = 0;
  1562.     (*pStringMap)["system-screen-depth"] = 0;
  1563.     (*pStringMap)["system-captions"] = 0;
  1564.     (*pStringMap)["system-overdub-or-caption"] = 0;
  1565.     (*m_pTagAttributeMap)[SMILSeq] = pStringMap;
  1566.     // SMILSwitch
  1567.     pStringMap = new CHXMapStringToOb;
  1568.     (*pStringMap)["id"] = 0;
  1569.     (*pStringMap)["title"] = 0;
  1570.     (*m_pTagAttributeMap)[SMILSwitch] = pStringMap;
  1571.     // SMILRef
  1572.     pStringMap = new CHXMapStringToOb;
  1573.     (*pStringMap)["id"] = 0;
  1574.     (*pStringMap)["title"] = 0;
  1575.     (*pStringMap)["abstract"] = 0;
  1576.     (*pStringMap)["author"] = 0;
  1577.     (*pStringMap)["copyright"] = 0;
  1578.     (*pStringMap)["region"] = 0;
  1579.     (*pStringMap)["alt"] = 0;
  1580.     (*pStringMap)["longdesc"] = 0;
  1581.     (*pStringMap)["src"] = 0;
  1582.     (*pStringMap)["type"] = 0;
  1583.     (*pStringMap)["dur"] = 0;
  1584.     (*pStringMap)["repeat"] = 0;
  1585.     (*pStringMap)["fill"] = 0;
  1586.     (*pStringMap)["begin"] = 0;
  1587.     (*pStringMap)["end"] = 0;
  1588.     (*pStringMap)["clip-begin"] = 0;
  1589.     (*pStringMap)["clip-end"] = 0;
  1590.     (*pStringMap)["skip-content"] = 0;
  1591.     (*pStringMap)["system-bitrate"] = 0;
  1592.     (*pStringMap)["system-language"] = 0;
  1593.     (*pStringMap)["system-required"] = 0;
  1594.     (*pStringMap)["system-screen-size"] = 0;
  1595.     (*pStringMap)["system-screen-depth"] = 0;
  1596.     (*pStringMap)["system-captions"] = 0;
  1597.     (*pStringMap)["system-overdub-or-caption"] = 0;
  1598.     (*m_pTagAttributeMap)[SMILRef] = pStringMap;
  1599.     // SMILAAnchor
  1600.     pStringMap = new CHXMapStringToOb;
  1601.     (*pStringMap)["id"] = 0;
  1602.     (*pStringMap)["title"] = 0;
  1603.     (*pStringMap)["href"] = 0;
  1604.     (*pStringMap)["show"] = 0;
  1605.     (*m_pTagAttributeMap)[SMILAAnchor] = pStringMap;
  1606.     // SMILAnchor
  1607.     pStringMap = new CHXMapStringToOb;
  1608.     (*pStringMap)["id"] = 0;
  1609.     (*pStringMap)["title"] = 0;
  1610.     (*pStringMap)["href"] = 0;
  1611.     (*pStringMap)["show"] = 0;
  1612.     (*pStringMap)["begin"] = 0;
  1613.     (*pStringMap)["end"] = 0;
  1614.     (*pStringMap)["coords"] = 0;
  1615.     (*pStringMap)["fragment-id"] = 0;
  1616.     (*pStringMap)["skip-content"] = 0;
  1617.     (*pStringMap)["z-index"] = 0;
  1618.     (*m_pTagAttributeMap)[SMILAnchor] = pStringMap;
  1619.     // SMILRendererPreFetch
  1620.     pStringMap = new CHXMapStringToOb;
  1621.     (*pStringMap)["type"] = 0;
  1622.     (*m_pTagAttributeMap)[SMILRendererPreFetch] = pStringMap;
  1623. }
  1624. void
  1625. CSmil1Parser::deleteTagAttributes()
  1626. {
  1627.     if(m_pTagAttributeMap)
  1628.     {
  1629.         CHXMapLongToObj::Iterator i = m_pTagAttributeMap->Begin();
  1630. for(; i != m_pTagAttributeMap->End(); ++i)
  1631. {
  1632.     CHXMapStringToOb* pStringMap = (CHXMapStringToOb*)(*i);
  1633.     delete pStringMap;
  1634. }
  1635.     }
  1636.     HX_DELETE(m_pTagAttributeMap);
  1637. }
  1638. BOOL
  1639. CSmil1Parser::isLegalAttribute(SMIL1NodeTag tag, const char* pAttName)
  1640. {
  1641.     // use SMILRef for all media object checks
  1642.     if(tag == SMILText ||
  1643.        tag == SMILImg ||
  1644.        tag == SMILAudio ||
  1645.        tag == SMILVideo ||
  1646.        tag == SMILAnimation ||
  1647.        tag == SMILTextstream)
  1648.     {
  1649. tag = SMILRef;
  1650.     }
  1651.     CHXMapStringToOb* pStringMap = 0;
  1652.     if(m_pTagAttributeMap->Lookup(tag, (void*&)pStringMap))
  1653.     {
  1654. void* pVoid = 0;
  1655. if(pStringMap->Lookup(pAttName, pVoid))
  1656. {
  1657.     return TRUE;
  1658. }
  1659. else if (strcmp(pAttName, "xmlns") == 0 || 
  1660.     strncmp(pAttName, "xmlns:", 6) == 0)
  1661. {
  1662.     // accept any namespace declarations.
  1663.     return TRUE;
  1664. }
  1665. else
  1666. {
  1667.     BOOL bValidAttribute = FALSE;
  1668.     char* pColon = (char *)strchr(pAttName, ':');
  1669.     if(pColon)
  1670.     {
  1671. //check for valid namespace tag we can
  1672. // ignore
  1673. char* pTmpNam = new_string(pAttName);
  1674. char* pNamespace = strtok(pTmpNam, ":");
  1675. if(pNamespace)
  1676. {
  1677.     UINT32 ulTemp = 0;
  1678.     if(m_pActiveNamespaceMap &&
  1679.       (m_pActiveNamespaceMap->Lookup(pNamespace,
  1680.       (void*&)ulTemp)))
  1681.     {
  1682. // OK, we can ignore it...
  1683. bValidAttribute = TRUE;
  1684.     }
  1685. }
  1686. delete[] pTmpNam;
  1687.     }
  1688.     if(bValidAttribute)
  1689.     {
  1690. return TRUE;
  1691.     }
  1692. }
  1693.     }
  1694.     return FALSE;
  1695. }
  1696. BOOL
  1697. CSmil1Parser::isRelativeURL(const char* pURL)
  1698. {
  1699.     BOOL rc = TRUE;
  1700.     CHXURL urlObj(pURL);
  1701.     IHXValues* pHeader = urlObj.GetProperties();
  1702.     if(pHeader)
  1703.     {
  1704.         IHXBuffer* pBuffer = NULL;
  1705. if(HXR_OK == pHeader->GetPropertyBuffer(PROPERTY_SCHEME, pBuffer))
  1706. {
  1707.     // fully qualified URL
  1708.     rc = FALSE;
  1709.     HX_RELEASE(pBuffer);
  1710. }
  1711.     }
  1712.     HX_RELEASE(pHeader);
  1713.     return rc;
  1714. }
  1715. HX_RESULT
  1716. CSmil1Parser::storeNamespaces(SMIL1Node* pNode)
  1717. {
  1718.     HX_RESULT rc = HXR_OK;
  1719.     if (pNode->m_pValues)
  1720.     {
  1721. const char* pName = NULL;
  1722. IHXBuffer* pBuffer = NULL;
  1723. HX_RESULT res = pNode->m_pValues->GetFirstPropertyCString(pName, pBuffer);
  1724. while (SUCCEEDED(rc) && SUCCEEDED(res))
  1725. {
  1726.     if (strcmp(pName, "xmlns") == 0)
  1727.     {
  1728. if (!pNode->m_pNamespaceList)
  1729. {
  1730.     pNode->m_pNamespaceList = new CHXSimpleList;
  1731.     if (!pNode->m_pNamespaceList)
  1732.     {
  1733. rc = HXR_OUTOFMEMORY;
  1734. break;
  1735.     }
  1736. }
  1737. // duplicate atributes should allready be caught...
  1738. SMIL1Namespace* pNS = new SMIL1Namespace("", pBuffer);
  1739. pNode->m_pNamespaceList->AddHead(pNS);
  1740.     }
  1741.     else if (strncmp(pName, "xmlns:", 6) == 0)
  1742.     {
  1743. if (!pNode->m_pNamespaceList)
  1744. {
  1745.     pNode->m_pNamespaceList = new CHXSimpleList;
  1746.     if (!pNode->m_pNamespaceList)
  1747.     {
  1748. rc = HXR_OUTOFMEMORY;
  1749. break;
  1750.     }
  1751. }
  1752. char* nsPrefix = (char *)strchr(pName, ':');
  1753. ++nsPrefix;
  1754. SMIL1Namespace* pNS = new SMIL1Namespace(nsPrefix, pBuffer);
  1755. pNode->m_pNamespaceList->AddHead(pNS);
  1756.     }
  1757.     HX_RELEASE(pBuffer);
  1758.     res = pNode->m_pValues->GetNextPropertyCString(pName, pBuffer);
  1759. }
  1760.     }
  1761.     return rc;
  1762. }
  1763. HX_RESULT
  1764. CSmil1Parser::addToNamespaceScope(SMIL1Node* pNode)
  1765. {
  1766.     HX_RESULT rc = HXR_OK;
  1767.     if (!m_pActiveNamespaceMap)
  1768.     {
  1769. m_pActiveNamespaceMap = new CHXMapStringToOb;
  1770. if (!m_pActiveNamespaceMap)
  1771. {
  1772.     return HXR_OUTOFMEMORY;
  1773. }
  1774.     }
  1775.     if (pNode &&
  1776. pNode->m_pNamespaceList)
  1777.     {
  1778. for (CHXSimpleList::Iterator pIt = pNode->m_pNamespaceList->Begin();
  1779.      pIt != pNode->m_pNamespaceList->End(); ++pIt)
  1780. {
  1781.     SMIL1Namespace* pNS = (SMIL1Namespace*)(*pIt);
  1782.     IHXBuffer* pBuf = (IHXBuffer*)(*m_pActiveNamespaceMap)[pNS->m_name];
  1783.     if (pBuf)
  1784.     {
  1785. if (!m_pNSConflictList)
  1786. {
  1787.     m_pNSConflictList = new CHXSimpleList;
  1788.     if (!m_pNSConflictList)
  1789.     {
  1790. rc = HXR_OUTOFMEMORY;
  1791. break;
  1792.     }
  1793. }
  1794. SMIL1Namespace* pConflict = new SMIL1Namespace(pNS);
  1795. if (!pConflict)
  1796. {
  1797.     rc = HXR_OUTOFMEMORY;
  1798.     break;
  1799. }
  1800. m_pNSConflictList->AddHead(pConflict);
  1801. HX_RELEASE(pBuf);
  1802. (*m_pActiveNamespaceMap)[pNS->m_name] = pNS->m_pValue;
  1803. pNS->m_pValue->AddRef();
  1804.     }
  1805.     else
  1806.     {
  1807. (*m_pActiveNamespaceMap)[pNS->m_name] = pNS->m_pValue;
  1808. pNS->m_pValue->AddRef();
  1809.     }
  1810. }
  1811.     }
  1812.     return rc;
  1813. }
  1814. HX_RESULT
  1815. CSmil1Parser::removeFromNamespaceScope(SMIL1Node* pNode)
  1816. {
  1817.     HX_RESULT rc = HXR_OK;
  1818.     
  1819.     if (pNode->m_pNamespaceList)
  1820.     {
  1821. for (CHXSimpleList::Iterator pIt = pNode->m_pNamespaceList->Begin();
  1822.      pIt != pNode->m_pNamespaceList->End(); ++pIt)
  1823. {
  1824.     SMIL1Namespace* pNS = (SMIL1Namespace*)(*pIt);
  1825.     HX_ASSERT((*m_pActiveNamespaceMap)[pNS->m_name]);
  1826.     IHXBuffer* pBuf = (IHXBuffer*)(*m_pActiveNamespaceMap)[pNS->m_name];
  1827.     if (pBuf != NULL)
  1828.     {
  1829. HX_RELEASE(pBuf);
  1830. m_pActiveNamespaceMap->RemoveKey(pNS->m_name);
  1831. // check for conficts.
  1832. if (m_pNSConflictList)
  1833. {
  1834.     LISTPOSITION pos = m_pNSConflictList->GetHeadPosition();
  1835.     while (pos)
  1836.     {
  1837. SMIL1Namespace* pCon = 
  1838.     (SMIL1Namespace*)m_pNSConflictList->GetAt(pos);
  1839. if (strcmp(pCon->m_name, pNS->m_name) == 0)
  1840. {
  1841.     (*m_pActiveNamespaceMap)[pCon->m_name] = pCon->m_pValue;
  1842.     pCon->m_pValue->AddRef();
  1843.     HX_DELETE(pCon);
  1844.     m_pNSConflictList->RemoveAt(pos);
  1845.     // BREAK at the first found match.
  1846.     break;
  1847. }
  1848. m_pNSConflictList->GetNext(pos);
  1849.     }
  1850. }
  1851.     }
  1852. }
  1853.     }
  1854.     return rc;
  1855. }
  1856. HX_RESULT
  1857. CSmil1Parser::addGlobalNamespace(const char* pNamespace,
  1858.   const char* pPrefix)
  1859. {
  1860.     HX_RESULT rc = HXR_OK;
  1861.     if(m_bNoNamespaces)
  1862.     {
  1863. rc = HXR_FAIL;
  1864. CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
  1865. errHandler.ReportError(SMILErrorSMIL10Document, NULL, 0);
  1866.     }
  1867.     else if (pNamespace)
  1868.     {
  1869. if(!m_pActiveNamespaceMap)
  1870. {
  1871.     m_pActiveNamespaceMap = new CHXMapStringToOb;
  1872. }
  1873. if (!m_pRequireTagsMap)
  1874. {
  1875.     m_pRequireTagsMap = new CHXMapStringToOb;
  1876. }
  1877. if(pPrefix)
  1878. {
  1879.     // get an IHXBuffer
  1880.     //XXXJEFFA should use CF for this
  1881.     IHXBuffer* pBuffer = (IHXBuffer*) new CHXBuffer;
  1882.     pBuffer->AddRef();
  1883.     pBuffer->Set((UINT8*)pNamespace, strlen(pNamespace) + 1);
  1884.     (*m_pActiveNamespaceMap)[pPrefix] = pBuffer;
  1885.     
  1886.     // add the prefix to the require map so system 
  1887.     // required checks work
  1888.     (*m_pRequireTagsMap)[pPrefix] = 0;
  1889.     if(strcmp(pPrefix, (const char*) RN_PREFIX) == 0)
  1890.     {
  1891. m_bRNNamespace = TRUE;
  1892.     }
  1893. }
  1894. else
  1895. {
  1896.     // empty prefix, 
  1897.     // don't ignore unrecognized elements...
  1898.     m_bIgnoreUnrecognizedElements = FALSE;
  1899. }
  1900.     }
  1901.     return rc;
  1902. }
  1903. HX_RESULT
  1904. CSmil1Parser::storeError(HX_RESULT errCode, const char* pErrorString, 
  1905.  const char* pFrameString, UINT32 ulLineNumber, 
  1906.  UINT32 ulLinePosition, BOOL bXml)
  1907. {
  1908.     // XXXJHUG - this is what the SMIL error hanndler uses 1024....
  1909.     char errorString[1024]; /* Flawfinder: ignore */
  1910.     if (bXml)
  1911.     {
  1912. CSmil1XMLSyntaxErrorHandler errHandler(m_pContext);
  1913.     
  1914. errHandler.GetReportString(errCode, errorString);
  1915.     }
  1916.     else
  1917.     {
  1918. CSmil1SMILSyntaxErrorHandler errHandler(m_pContext);
  1919.     
  1920. errHandler.GetReportString((SMILErrorTag)errCode, errorString);
  1921.     }
  1922.     IHXBuffer* pBuf;
  1923.     m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pBuf);
  1924.     pBuf->SetSize(strlen(errorString) + strlen(pErrorString) + 10);
  1925.     char* buffer = (char*) pBuf->GetBuffer();
  1926.     sprintf(buffer, errorString, ulLineNumber, pErrorString); /* Flawfinder: ignore */
  1927.     m_pErrors->Add(pBuf);
  1928.     return HXR_OK;
  1929. }
  1930. HX_RESULT
  1931. CSmil1Parser::getErrors(CHXPtrArray** pErrs)
  1932. {
  1933.     *pErrs = m_pErrors;
  1934.     return HXR_OK;
  1935. }
  1936. ElementWithinTag
  1937. CSmil1Parser::GetElementWithin(const char* pID)
  1938. {
  1939.     ElementWithinTag elementWithinTag = WithinUnknown;
  1940.     SMIL1Node* pNode = NULL;
  1941.     SMIL1Node* pParentNode = NULL;
  1942.     if(!m_pIDMap->Lookup(pID, (void*&)pNode))
  1943.     {
  1944. HX_ASSERT(FALSE);
  1945. goto cleanup;
  1946.     }
  1947.     while (pNode->m_pParent)
  1948.     {
  1949. switch (pNode->m_pParent->m_tag)
  1950. {
  1951. case SMILPar:
  1952.     if (elementWithinTag == WithinSeq)
  1953.     {
  1954. elementWithinTag = WithinSeqInPar;
  1955.     }
  1956.     else
  1957.     {
  1958. elementWithinTag = WithinPar;
  1959.     }
  1960.     goto cleanup;
  1961. case SMILSeq:
  1962.     elementWithinTag = WithinSeq;
  1963.     break;
  1964. default:
  1965.     break;
  1966. }
  1967. pNode = pNode->m_pParent;
  1968.     }
  1969. cleanup:
  1970.     return elementWithinTag;
  1971. }
  1972. void
  1973. CSmil1Parser::InitPersistent(UINT32 ulPersistentComponentID, 
  1974.     ElementWithinTag elementWithinTag)
  1975. {
  1976.     m_ulPersistentComponentID = ulPersistentComponentID;
  1977.     m_elementWithinTag = elementWithinTag;
  1978. }
  1979. /*
  1980.  * CSmil1ParserResponse methods
  1981.  */
  1982. CSmil1ParserResponse::CSmil1ParserResponse(CSmil1Parser* pParser)
  1983. :   m_pParser(pParser)
  1984. ,   m_lRefCount(0)
  1985. {
  1986. }
  1987. CSmil1ParserResponse::~CSmil1ParserResponse()
  1988. {
  1989. }
  1990. STDMETHODIMP 
  1991. CSmil1ParserResponse::QueryInterface(REFIID riid, void** ppvObj)
  1992. {
  1993.     if (IsEqualIID(riid, IID_IUnknown))
  1994.     {
  1995. AddRef();
  1996. *ppvObj = this;
  1997. return HXR_OK;
  1998.     }
  1999.     else if (IsEqualIID(riid, IID_IHXXMLParserResponse))
  2000.     {
  2001. AddRef();
  2002. *ppvObj = (IHXXMLParserResponse*)this;
  2003. return HXR_OK;
  2004.     }
  2005.     *ppvObj = NULL;
  2006.     return HXR_NOINTERFACE;
  2007. }
  2008. STDMETHODIMP_(ULONG32) 
  2009. CSmil1ParserResponse::AddRef()
  2010. {
  2011.     return InterlockedIncrement(&m_lRefCount);
  2012. }
  2013. STDMETHODIMP_(ULONG32) 
  2014. CSmil1ParserResponse::Release()
  2015. {
  2016.     if (InterlockedDecrement(&m_lRefCount) > 0)
  2017.     {
  2018.         return m_lRefCount;
  2019.     }
  2020.     delete this;
  2021.     return 0;
  2022. }
  2023. STDMETHODIMP
  2024. CSmil1ParserResponse::HandleStartElement(const char* pName,
  2025.  IHXValues* pAttributes,
  2026.  UINT32 ulLineNumber,
  2027.  UINT32 ulColumnNumber)
  2028. {
  2029.     HX_RESULT rc = HXR_OK;
  2030.     SMIL1Node* pParentNode = 
  2031. (SMIL1Node*)m_pParser->m_pNodeListStack->TopOfStack();
  2032.     HX_ASSERT(pParentNode);
  2033.     SMIL1Node* pNode = new SMIL1Node;
  2034.     pNode->m_name = pName;
  2035.     pNode->m_pParent = pParentNode;
  2036.     pNode->m_pNodeList = new SMIL1NodeList;
  2037.     pNode->m_pNodeList->m_pParentNode = pNode;
  2038.     pNode->m_ulTagStartLine = ulLineNumber;
  2039.     pNode->m_ulTagStartColumn = ulColumnNumber;
  2040.     if(!pNode->m_pParent->m_bSkipContent)
  2041.     {
  2042. IHXBuffer* pBuffer = NULL;
  2043. if(HXR_OK == pAttributes->GetPropertyCString("id", pBuffer))
  2044. {
  2045.     const char* pID = (const char*)pBuffer->GetBuffer();
  2046.     // XXXMEH - 04/27/99 - change this to still throw
  2047.     // an error for isspace(), but not for isdigit()
  2048.     // - not legal SMIL, but we still allowed
  2049.     // it in previous players.
  2050. //     if (isdigit(*pID) || isspace(*pID))
  2051.     if (isspace(*pID))
  2052.     {
  2053. rc = HXR_XML_ILLEGALID;
  2054. CSmil1XMLSyntaxErrorHandler errHandler(m_pParser->m_pContext);
  2055. errHandler.ReportError(rc, pID, ulLineNumber);
  2056. goto exit;
  2057.     }
  2058.     else if (m_pParser->m_bStoreErrors && isdigit(*pID))
  2059.     {
  2060. m_pParser->storeError(HXR_XML_ILLEGALID, pID, 0, 
  2061.     ulLineNumber, ulColumnNumber);
  2062.     }
  2063.     else
  2064.     {
  2065. // append persistent ID to the end of region id
  2066. // to make it unique in nested meta
  2067. if (!strcmp(pNode->m_name, "region"))
  2068. {
  2069.     //char szPersistentComponentID[MAX_DISPLAY_NAME] = {0};
  2070.     //itoa(m_pParser->m_ulPersistentComponentID, szPersistentComponentID, 10);
  2071.     pNode->m_id = pID;
  2072.     //pNode->m_id += "_";
  2073.     //pNode->m_id += szPersistentComponentID;
  2074.     pNode->m_repeatid = pNode->m_id;
  2075. }
  2076. else
  2077. {
  2078.     pNode->m_id = pID;
  2079.     pNode->m_repeatid = pID;
  2080. }
  2081. HX_RELEASE(pBuffer);
  2082.     }
  2083. }
  2084. else
  2085. {
  2086.     //[SMIL 1.0 Compliance] Fixes PR 24034: region tag must have
  2087.     // an id attribute:
  2088.     if (m_pParser->m_bSMIL10FullCompliance  &&
  2089.     !strcmp(pNode->m_name, "region"))
  2090.     {
  2091. rc = HXR_XML_ILLEGALID;
  2092. CSmil1XMLSyntaxErrorHandler errHandler(m_pParser->m_pContext);
  2093. const char* pTmp = "region id=""";
  2094. errHandler.ReportError(rc, pTmp, ulLineNumber);
  2095. goto exit;
  2096.     }
  2097.     else
  2098.     {
  2099. pNode->m_id = m_pParser->assignID(pName);
  2100. pNode->m_repeatid = pNode->m_id;
  2101.     }
  2102.     if (m_pParser->m_bStoreErrors && !strcmp(pNode->m_name, "region"))
  2103.     {
  2104. const char* pTmp = "region id=""";
  2105. m_pParser->storeError(HXR_XML_ILLEGALID, pTmp, 0, 
  2106.     ulLineNumber, ulColumnNumber);
  2107.     }
  2108. }
  2109. if(HXR_OK != m_pParser->mapID(pNode))
  2110. {
  2111.     rc = HXR_XML_ILLEGALID;
  2112.     CSmil1XMLSyntaxErrorHandler errHandler(m_pParser->m_pContext);
  2113.     errHandler.ReportError(rc, pNode->m_id, ulLineNumber);
  2114.     goto exit;
  2115. }
  2116. if(strcmp(pName, "smil") == 0)
  2117. {
  2118.     pNode->m_tag = SMILSmil;
  2119. }
  2120. else if(strcmp(pName, "layout") == 0)
  2121. {
  2122.     pNode->m_tag = SMILBasicLayout;
  2123.     if(HXR_OK == pAttributes->GetPropertyCString("type", pBuffer))
  2124.     {
  2125. const char* pType = (const char*)pBuffer->GetBuffer();
  2126. if(strcmp(pType, "text/smil-basic-layout") != 0)
  2127. {
  2128.     pNode->m_bDelete = TRUE; // only basic layout supported
  2129. }
  2130. HX_RELEASE(pBuffer);
  2131.     }
  2132. }
  2133. else if(strcmp(pName, "meta") == 0)
  2134. {
  2135.     pNode->m_tag = SMILMeta;
  2136.     pNode->m_bSkipContent = TRUE;
  2137. }
  2138. else if(strcmp(pName, "head") == 0)
  2139. {
  2140.     pNode->m_id = "head";
  2141.     pNode->m_tag = SMILHead;
  2142. }
  2143. else if(strcmp(pName, "body") == 0)
  2144. {
  2145.     pNode->m_id = "body";
  2146.     pNode->m_tag = SMILBody;
  2147. }
  2148. else if(strcmp(pName, "region") == 0)
  2149. {
  2150.     pNode->m_tag = SMILRegion;
  2151.     pNode->m_bSkipContent = TRUE;
  2152. }
  2153. else if(strcmp(pName, "root-layout") == 0)
  2154. {
  2155.     pNode->m_tag = SMILRootLayout;
  2156.     pNode->m_bSkipContent = TRUE;
  2157. }
  2158. else if(strcmp(pName, "switch") == 0)
  2159. {
  2160.     pNode->m_tag = SMILSwitch;
  2161. }
  2162. else if(strcmp(pName, "text") == 0)
  2163. {
  2164.     pNode->m_tag = SMILText;
  2165. }
  2166. else if(strcmp(pName, "img") == 0)
  2167. {
  2168.     pNode->m_tag = SMILImg;
  2169. }
  2170. else if(strcmp(pName, "ref") == 0)
  2171. {
  2172.     pNode->m_tag = SMILRef;
  2173. }
  2174. else if(strcmp(pName, "audio") == 0)
  2175. {
  2176.     pNode->m_tag = SMILAudio;
  2177. }
  2178. else if(strcmp(pName, "video") == 0)
  2179. {
  2180.     pNode->m_tag = SMILVideo;
  2181. }
  2182. else if(strcmp(pName, "animation") == 0)
  2183. {
  2184.     pNode->m_tag = SMILAnimation;
  2185. }
  2186. else if(strcmp(pName, "textstream") == 0)
  2187. {
  2188.     pNode->m_tag = SMILTextstream;
  2189. }
  2190. else if(strcmp(pName, "a") == 0)
  2191. {
  2192.     pNode->m_tag = SMILAAnchor;
  2193. }
  2194. else if(strcmp(pName, "anchor") == 0)
  2195. {
  2196.     pNode->m_tag = SMILAnchor;
  2197.     pNode->m_bSkipContent = TRUE;
  2198. }
  2199. else if(strcmp(pName, "par") == 0)
  2200. {
  2201.     pNode->m_tag = SMILPar;
  2202. }
  2203. else if(strcmp(pName, "seq") == 0)
  2204. {
  2205.     pNode->m_tag = SMILSeq;
  2206. }
  2207. else if(m_pParser->m_bRNNamespace && 
  2208.     strcmp(pName, (const char*) RN_TAG_RENDERER_LIST) == 0)
  2209. {
  2210.     pNode->m_id = m_pParser->assignID((const char*) RN_TAG_RENDERER_LIST);
  2211.     pNode->m_tag = SMILRNRendererList;
  2212. }
  2213. else if(strcmp(pName, (const char*) RN_TAG_RENDERER) == 0)
  2214. {
  2215.     pNode->m_tag = SMILRendererPreFetch;
  2216. }
  2217. else 
  2218. {
  2219.     BOOL bValidTag = FALSE;
  2220.     char* pColon = (char *)strchr(pName, ':');
  2221.     if(pColon)
  2222.     {
  2223. //check for valid namespace tag we can
  2224. // ignore
  2225. char* pTmpNam = new_string(pName);
  2226. char* pNamespace = strtok(pTmpNam, ":");
  2227. if(pNamespace)
  2228. {
  2229.     UINT32 ulTemp = 0;
  2230.     if(m_pParser->m_pActiveNamespaceMap &&
  2231.       (m_pParser->m_pActiveNamespaceMap->Lookup(pNamespace,
  2232.       (void*&)ulTemp)))
  2233.     {
  2234. // OK, we can ignore it...
  2235. bValidTag = TRUE;
  2236.     }
  2237. }
  2238. delete[] pTmpNam;
  2239.     }
  2240.     if(!bValidTag && 
  2241. !m_pParser->m_bIgnoreUnrecognizedElements)
  2242.     {
  2243. rc = HXR_FAIL;
  2244. CSmil1SMILSyntaxErrorHandler errHandler(m_pParser->m_pContext);
  2245. errHandler.ReportError(SMILErrorUnrecognizedTag, pName, ulLineNumber);
  2246. goto exit;
  2247.     }
  2248.     else
  2249.     {
  2250. pNode->m_bDelete = TRUE; // don't ask, don't tell...
  2251.     }
  2252.     if (!bValidTag && m_pParser->m_bStoreErrors)
  2253.     {
  2254. m_pParser->storeError(SMILErrorUnrecognizedTag, pName, 0, 
  2255.     ulLineNumber, ulColumnNumber, FALSE);
  2256.     }
  2257. }
  2258. pNode->m_pValues = pAttributes;
  2259. pNode->m_pValues->AddRef();
  2260. rc = m_pParser->storeNamespaces(pNode);
  2261. if (SUCCEEDED(rc))
  2262. {
  2263.     rc = m_pParser->addToNamespaceScope(pNode);
  2264. }
  2265. const char* pName = NULL;
  2266. HX_RESULT res = pAttributes->GetFirstPropertyCString(pName, pBuffer);
  2267. while(HXR_OK == res && SUCCEEDED(rc))
  2268. {
  2269.     const char* pActualValue = (const char*)pBuffer->GetBuffer();
  2270.     if(!m_pParser->isLegalAttribute(pNode->m_tag, pName) )
  2271.     {
  2272. if (!m_pParser->m_bIgnoreUnrecognizedElements)
  2273. {
  2274.     rc = HXR_FAIL;
  2275.     m_pParser->badAttributeError(pNode->m_tag, pName,
  2276. pNode->m_ulTagStartLine, FALSE);
  2277.     break;
  2278. }
  2279. if (m_pParser->m_bStoreErrors)
  2280. {
  2281.     m_pParser->badAttributeError(pNode->m_tag, pName, 
  2282. ulLineNumber, TRUE);
  2283. }
  2284.     }
  2285.     if(strcmp(pName, "skip-content") == 0)
  2286.     {
  2287. if(strcmp(pActualValue, "true") == 0)
  2288. {
  2289.     pNode->m_bSkipContent = TRUE;
  2290. }
  2291. else
  2292. {
  2293.     pNode->m_bSkipContent = FALSE;
  2294. }
  2295.     }
  2296.     HX_RELEASE(pBuffer);
  2297.     res = pAttributes->GetNextPropertyCString(pName, pBuffer);
  2298. }
  2299. m_pParser->m_pNodeListStack->Push(pNode);
  2300.     }
  2301. exit:
  2302.     return rc;
  2303. }
  2304. STDMETHODIMP
  2305. CSmil1ParserResponse::HandleEndElement(const char* pName,
  2306.       UINT32 ulLineNumber,
  2307.       UINT32 ulColumnNumber)
  2308. {
  2309.     HX_RESULT rc = HXR_OK;
  2310.     SMIL1Node* pCurrentNode = (SMIL1Node*)m_pParser->m_pNodeListStack->Pop();
  2311.     SMIL1Node* pParentNode = (SMIL1Node*)m_pParser->m_pNodeListStack->TopOfStack();
  2312.     HX_ASSERT(pCurrentNode);
  2313.     HX_ASSERT(pParentNode);
  2314.     pParentNode->m_pNodeList->AddTail(pCurrentNode);
  2315.     SMIL1Node* pEndNode = new SMIL1Node;
  2316.     pEndNode->m_name = pName;
  2317.     pEndNode->m_id.Format("CLOSE-%s", pName);
  2318.     pEndNode->m_pParent = pParentNode;
  2319.     pEndNode->m_ulTagStartLine = ulLineNumber;
  2320.     pEndNode->m_ulTagStartColumn = ulColumnNumber;
  2321.     if(strcmp(pName, "seq") == 0)
  2322.     {
  2323. pEndNode->m_tag = SMILEndSeq;
  2324.     }
  2325.     else if(strcmp(pName, "par") == 0)
  2326.     {
  2327. pEndNode->m_tag = SMILEndPar;
  2328.     }
  2329.     else if(strcmp(pName, "a") == 0)
  2330.     {
  2331. pEndNode->m_tag = SMILEndAAnchor;
  2332.     }
  2333.     pCurrentNode->m_pNodeList->AddTail(pEndNode);
  2334.     rc = m_pParser->removeFromNamespaceScope(pCurrentNode);
  2335.     return rc;
  2336. }
  2337. STDMETHODIMP
  2338. CSmil1ParserResponse::HandleCharacterData(IHXBuffer* pBuffer,
  2339.  UINT32 ulLineNumber,
  2340.  UINT32 ulColumnNumber)
  2341. {
  2342.     HX_RESULT rc = HXR_OK;
  2343.     return rc;
  2344. }
  2345. STDMETHODIMP
  2346. CSmil1ParserResponse::HandleProcessingInstruction(const char* pTarget,
  2347.   IHXValues* pAttributes,
  2348.   UINT32 ulLineNumber,
  2349.   UINT32 ulColumnNumber)
  2350. {
  2351.     HX_RESULT rc = HXR_OK;
  2352.     if(strcmp(pTarget, "xml:namespace") == 0)
  2353.     {
  2354. IHXBuffer* pNamespaceBuffer = NULL;
  2355. IHXBuffer* pPrefixBuffer = NULL;
  2356. const char* pNamespace = NULL;
  2357. const char* pPrefix = NULL;
  2358. if(HXR_OK == pAttributes->GetPropertyCString("ns", pNamespaceBuffer))
  2359. {
  2360.     pNamespace = (const char*)pNamespaceBuffer->GetBuffer();
  2361. }
  2362. if(HXR_OK == pAttributes->GetPropertyCString("prefix", pPrefixBuffer))
  2363. {
  2364.     pPrefix = (const char*)pPrefixBuffer->GetBuffer();
  2365. }
  2366. rc = m_pParser->addGlobalNamespace(pNamespace, pPrefix);
  2367. HX_RELEASE(pNamespaceBuffer);
  2368. HX_RELEASE(pPrefixBuffer);
  2369.     }
  2370.     return rc;
  2371. }
  2372. STDMETHODIMP
  2373. CSmil1ParserResponse::HandleUnparsedEntityDecl(const char* /*IN*/  pEntityName,
  2374.       const char* /*IN*/  pSystemID,
  2375.       const char* /*IN*/  pPublicID,
  2376.       const char* /*IN*/  pNotationName,
  2377.       UINT32 ulLineNumber,
  2378.       UINT32 ulColumnNumber)
  2379. {
  2380.     HX_RESULT rc = HXR_OK;
  2381.     return rc;
  2382. }
  2383. STDMETHODIMP
  2384. CSmil1ParserResponse::HandleNotationDecl(const char* /*IN*/  pNotationName,
  2385. const char* /*IN*/  pSystemID,
  2386. const char* /*IN*/  pPublicID,
  2387. UINT32 ulLineNumber,
  2388. UINT32 ulColumnNumber)
  2389. {
  2390.     HX_RESULT rc = HXR_OK;
  2391.     return rc;
  2392. }
  2393. STDMETHODIMP
  2394. CSmil1ParserResponse::HandleUnparsedDoctypeDecl(const char*  /*IN*/ pName, 
  2395.     const char*  /*IN*/ pSystemID,
  2396.     const char*  /*IN*/ pPublicID, 
  2397.     UINT32  /*IN*/ ulLineNumber,
  2398.     UINT32  /*IN*/ ulColumNumber)
  2399. {
  2400.     HX_RESULT rc = HXR_OK;
  2401.     if(strcmp(pName, "smil") == 0 &&
  2402.        strcmp(pSystemID, "http://www.w3.org/TR/REC-smil/SMIL10.dtd") == 0 &&
  2403.        strcmp(pPublicID, "-//W3C//DTD SMIL 1.0//EN") == 0)
  2404.     {
  2405. // only be strict, still allow namespaces...
  2406. //m_pParser->m_bNoNamespaces = TRUE;
  2407. m_pParser->m_bIgnoreUnrecognizedElements = FALSE;
  2408.     }
  2409.     return rc;
  2410. }
  2411. STDMETHODIMP
  2412. CSmil1ParserResponse::HandleComment(const char* /*IN*/  pComment,
  2413.    UINT32 ulLineNumber,
  2414.    UINT32 ulColumnNumber)
  2415. {
  2416.     HX_RESULT rc = HXR_OK;
  2417.     return rc;
  2418. }
  2419. STDMETHODIMP
  2420. CSmil1ParserResponse::HandleDefault(IHXBuffer* /*IN*/ pBuffer,
  2421.    UINT32 ulLineNumber,
  2422.    UINT32 ulColumnNumber)
  2423. {
  2424.     HX_RESULT rc = HXR_OK;
  2425.     return rc;
  2426. }
  2427. HX_RESULT
  2428. CSmil1ParserResponse::ErrorInLastTag(HX_RESULT err, 
  2429.     const char* pErrorString, const char* pFrameString, 
  2430.     UINT32 ulLineNumber, UINT32 ulLinePosition)
  2431. {
  2432.     // XXXJHUG - we could add the error to the actual node...
  2433.     // SMIL1Node* pCurrentNode = (SMIL1Node*)m_pParser->m_pNodeListStack->Pop();
  2434.     // pCurrentNode->m_errs->Add
  2435.     //
  2436.     // If we were going to warn for errors I think the warnings should be
  2437.     // thrown from here.  (modify ReportError to have a warning level.)
  2438.     //
  2439.     // But for dumping the errors there is no benifit for this.
  2440.     // therefore we will just add the error to a ptr array of errors.
  2441.     // this array will also be added to when the SMIL attributes are bad.
  2442.     //
  2443.     // XXX to store in the parse tree you also have to make sure the last
  2444.     // call was a tag, and not a PI or a directive or something that was 
  2445.     // ignored.
  2446.     
  2447.     return m_pParser->storeError(err, pErrorString, pFrameString, 
  2448.     ulLineNumber, ulLinePosition);
  2449. }
  2450. /*
  2451.  * SMIL1Node methods
  2452.  */
  2453. SMIL1Node::SMIL1Node():
  2454.     m_pNodeList(0),
  2455.     m_pParent(0),
  2456.     m_pDependency(0),
  2457.     m_tag(SMILUnknown),
  2458.     m_num(0),
  2459.     m_pValues(0),
  2460.     m_curPosition(0),
  2461.     m_pElement(0),
  2462.     m_nGroup((UINT16)-1),
  2463.     m_bLastInGroup(FALSE),
  2464.     m_bDelete(FALSE),
  2465.     m_bSkipContent(FALSE),
  2466.     m_pNamespaceList(NULL),
  2467.     m_bRepeatHandled(FALSE),
  2468.     m_repeatTag(RepeatUnknown)
  2469. {
  2470. }
  2471. SMIL1Node::SMIL1Node(const SMIL1Node& rhs, BOOL bKeepId, CSmil1Parser* pParser)
  2472. {
  2473.     if (bKeepId)
  2474.     {
  2475. m_id = rhs.m_id;
  2476.     }
  2477.     else
  2478.     {
  2479. // need a unique ID, so make one...
  2480. char* pIDName = new char [256];
  2481.         if (pIDName && pParser)
  2482.         {
  2483.     sprintf(pIDName, "node_copy_%ld", pParser->GetUniqueNumber()); /* Flawfinder: ignore */
  2484.     m_id = pIDName;
  2485.         }
  2486.         HX_VECTOR_DELETE(pIDName);
  2487.     }
  2488.     m_repeatid = rhs.m_repeatid;
  2489.     m_pParent = rhs.m_pParent;
  2490.     m_pDependency = rhs.m_pDependency;
  2491.     m_tag = rhs.m_tag;
  2492.     m_num = rhs.m_num;
  2493.     m_curPosition = rhs.m_curPosition;
  2494.     m_pElement = rhs.m_pElement;
  2495.     m_nGroup = rhs.m_nGroup;
  2496.     m_bLastInGroup = rhs.m_bLastInGroup;
  2497.     m_bDelete = rhs.m_bDelete;
  2498.     m_bSkipContent = rhs.m_bSkipContent;
  2499.     m_bRepeatHandled = FALSE;
  2500.     m_repeatTag = rhs.m_repeatTag;
  2501.     if(rhs.m_pValues)
  2502.     {
  2503. m_pValues = rhs.m_pValues;
  2504. m_pValues->AddRef();
  2505.     }
  2506.     else
  2507.     {
  2508. m_pValues = NULL;
  2509.     }
  2510.     if(rhs.m_pNodeList)
  2511.     {
  2512. m_pNodeList = rhs.m_pNodeList->copy(this, bKeepId, pParser);
  2513.     }
  2514.     else
  2515.     {
  2516. m_pNodeList = NULL;
  2517.     }
  2518.     if (rhs.m_pNamespaceList)
  2519.     {
  2520.      m_pNamespaceList = new CHXSimpleList;
  2521. for (CHXSimpleList::Iterator pIt = rhs.m_pNamespaceList->Begin();
  2522.      pIt != rhs.m_pNamespaceList->End(); ++pIt)
  2523. {
  2524.     SMIL1Namespace* pNS = (SMIL1Namespace*)(*pIt);
  2525.     SMIL1Namespace* pNewNS = new SMIL1Namespace(pNS);
  2526.     m_pNamespaceList->AddHead(pNewNS);
  2527. }
  2528.     }
  2529.     else
  2530.     {
  2531. m_pNamespaceList = NULL;
  2532.     }
  2533. }
  2534. SMIL1Node::~SMIL1Node()
  2535. {
  2536.     HX_DELETE(m_pNodeList);
  2537.     HX_RELEASE(m_pValues);
  2538.     if (m_pNamespaceList) 
  2539.     {
  2540. while (!m_pNamespaceList->IsEmpty())
  2541. {
  2542.     SMIL1Namespace* pNS = (SMIL1Namespace*)m_pNamespaceList->RemoveHead();
  2543.     HX_DELETE(pNS);
  2544. }
  2545.     }
  2546.     HX_DELETE(m_pNamespaceList);
  2547. }
  2548. SMIL1Node*
  2549. SMIL1Node::getFirstChild()
  2550. {
  2551.     if(!m_pNodeList)
  2552.     {
  2553. return 0;
  2554.     }
  2555.     m_curPosition = m_pNodeList->GetHeadPosition();
  2556.     if(m_curPosition)
  2557.     {
  2558. return (SMIL1Node*)m_pNodeList->GetNext(m_curPosition);
  2559.     }
  2560.     return 0;
  2561. }
  2562. SMIL1Node*
  2563. SMIL1Node::getNextChild()
  2564. {
  2565.     if(m_curPosition)
  2566.     {
  2567. return (SMIL1Node*)m_pNodeList->GetNext(m_curPosition);
  2568.     }
  2569.     return 0;
  2570. }
  2571. SMIL1NodeList::SMIL1NodeList():
  2572.     m_pParentNode(0)
  2573. {
  2574. }
  2575. SMIL1NodeList::~SMIL1NodeList()
  2576. {
  2577.     CHXSimpleList::Iterator i;
  2578.     for(i = Begin(); i != End(); ++i)
  2579.     {
  2580. SMIL1Node* pNode = (SMIL1Node*)(*i);
  2581. HX_DELETE(pNode);
  2582.     }
  2583. }
  2584. SMIL1NodeList*
  2585. SMIL1NodeList::copy(SMIL1Node* pParent, BOOL bKeepId, CSmil1Parser* pParser)
  2586. {
  2587.     SMIL1NodeList* pNewList = new SMIL1NodeList;
  2588.     m_pParentNode = pParent;
  2589.     CHXSimpleList::Iterator i = Begin();
  2590.     for(; i != End(); ++i)
  2591.     {
  2592. SMIL1Node* pNode = (SMIL1Node*)(*i);
  2593. SMIL1Node* pNodeCopy = new SMIL1Node(*pNode, bKeepId, pParser);
  2594. pNodeCopy->m_pParent = pParent;
  2595. pNewList->AddTail(pNodeCopy);
  2596.     }
  2597.     return pNewList;
  2598. }