smlparse.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:137k
源码类别:

Symbian

开发平台:

Visual C++

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