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

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hlxclib/stdlib.h"
  36. #include "hlxclib/stdio.h"
  37. #include "hlxclib/ctype.h"
  38. #include "hxtypes.h"
  39. #include "hxresult.h"
  40. #include "hxassert.h"
  41. #include "hxcom.h"
  42. #include "debug.h"
  43. #include "hxstrutl.h"
  44. #include "hxstring.h"
  45. #include "hxmap.h"
  46. #include "hxslist.h"
  47. #include "chxpckts.h"
  48. #include "cbbqueue.h"
  49. #include "hxstack.h"
  50. #include "smlpkt.h"
  51. #ifdef _WINCE
  52. #include <charfs.h>
  53. #endif
  54. #include "hxheap.h"
  55. #ifdef _DEBUG
  56. #undef HX_THIS_FILE             
  57. static char HX_THIS_FILE[] = __FILE__;
  58. #endif
  59. static const int MAX_ARGS = 32;
  60. static const int MAX_STRING_LEN = 10000;
  61. CSmilAddGroupPacket::CSmilAddGroupPacket():
  62.     CSmilPacket(SMILAddGroup),
  63.     m_nGroup(0),
  64.     m_nTotalTracks(0),
  65.     m_nInitTracks(0),
  66.     m_ulDuration((UINT32)-1)
  67. {
  68. }
  69. void
  70. CSmilAddGroupPacket::assign(const char* pName, const char** pValues,
  71.                             INT32 nValues)
  72. {
  73.     if(strcmp(pName, "ver") == 0 && nValues >= 1)
  74.     {
  75.         m_version = pValues[0];
  76.     }
  77.     else if(strcmp(pName, "id") == 0 && nValues >= 1)
  78.     {
  79.         m_id = pValues[0];
  80.     }
  81.     else if(strcmp(pName, "group") == 0 && nValues >= 1)
  82.     {
  83.         m_nGroup = (int)atol(pValues[0]);
  84.     }
  85.     else if(strcmp(pName, "total-tracks") == 0 && nValues >= 1)
  86.     {
  87.         m_nTotalTracks = (int)atol(pValues[0]);
  88.     }
  89.     else if(strcmp(pName, "init-tracks") == 0 && nValues >= 1)
  90.     {
  91.         m_nInitTracks = (int)atol(pValues[0]);
  92.     }
  93.     else if(strcmp(pName, "title") == 0 && nValues >= 1)
  94.     {
  95.         m_title = pValues[0];
  96.     }
  97.     else if(strcmp(pName, "dur") == 0 && nValues >= 1)
  98.     {
  99.         m_ulDuration = atol(pValues[0]);
  100.     }
  101. }
  102. CSmilPlayGroupPacket::CSmilPlayGroupPacket():
  103.     CSmilPacket(SMILPlayGroup),
  104.     m_nGroup(0),
  105.     m_ulDelay(0),
  106.     m_ulDuration(0)
  107. {
  108. }
  109. void
  110. CSmilPlayGroupPacket::assign(const char* pName, const char** pValues,
  111.                              INT32 nValues)
  112. {
  113.     if(strcmp(pName, "ver") == 0 && nValues >= 1)
  114.     {
  115.         m_version = pValues[0];
  116.     }
  117.     else if(strcmp(pName, "id") == 0 && nValues >= 1)
  118.     {
  119.         m_id = pValues[0];
  120.     }
  121.     else if(strcmp(pName, "group") == 0 && nValues >= 1)
  122.     {
  123.         m_nGroup = (int)atol(pValues[0]);
  124.     }
  125.     else if(strcmp(pName, "delay") == 0 && nValues >= 1)
  126.     {
  127.         m_ulDelay = atol(pValues[0]);
  128.     }
  129.     else if(strcmp(pName, "dur") == 0 && nValues >= 1)
  130.     {
  131.         m_ulDuration = atol(pValues[0]);
  132.     }
  133. }
  134. CSmilMetaValuesPacket::CSmilMetaValuesPacket():
  135.     CSmilPacket(SMILMetaValues)
  136. {
  137.     m_pValues = new CHXHeader;
  138.     m_pValues->AddRef();
  139. }
  140. CSmilMetaValuesPacket::~CSmilMetaValuesPacket()
  141. {
  142.     HX_RELEASE(m_pValues);
  143. }
  144. void
  145. CSmilMetaValuesPacket::assign(const char* pName, const char** pValues,
  146.                               INT32 nValues)
  147. {
  148.     if(nValues >= 1)
  149.     {
  150.         CHXBuffer* pBuffer = new CHXBuffer;
  151.         pBuffer->AddRef();
  152.         pBuffer->Set((BYTE*)pValues[0], strlen(pValues[0])+1);
  153.         m_pValues->SetPropertyCString(pName, pBuffer);
  154.         pBuffer->Release();
  155.     }
  156. }
  157. CSmilAddChannelPacket::CSmilAddChannelPacket():
  158.     CSmilPacket(SMILAddChannel),
  159.     m_ulLeft(0),
  160.     m_ulTop(0),
  161.     m_ulHeight(0),
  162.     m_ulWidth(0),
  163.     m_ulZIndex(0),
  164.     m_ulBgColor(0)
  165. {
  166. }
  167. void
  168. CSmilAddChannelPacket::assign(const char* pName, const char** pValues,
  169.                               INT32 nValues)
  170. {
  171.     if(strcmp(pName, "ver") == 0 && nValues >= 1)
  172.     {
  173.         m_version = pValues[0];
  174.     }
  175.     else if(strcmp(pName, "id") == 0 && nValues >= 1)
  176.     {
  177.         m_id = pValues[0];
  178.     }
  179.     else if(strcmp(pName, "left") == 0 && nValues >= 1)
  180.     {
  181.         m_ulLeft = atol(pValues[0]);
  182.     }
  183.     else if(strcmp(pName, "top") == 0 && nValues >= 1)
  184.     {
  185.         m_ulTop = atol(pValues[0]);
  186.     }
  187.     else if(strcmp(pName, "height") == 0 && nValues >= 1)
  188.     {
  189.         m_ulHeight = atol(pValues[0]);
  190.     }
  191.     else if(strcmp(pName, "width") == 0 && nValues >= 1)
  192.     {
  193.         m_ulWidth = atol(pValues[0]);
  194.     }
  195.     else if(strcmp(pName, "z-index") == 0 && nValues >= 1)
  196.     {
  197.         m_ulZIndex = atol(pValues[0]);
  198.     }
  199.     else if(strcmp(pName, "bgcolor") == 0 && nValues >= 1)
  200.     {
  201.         m_ulBgColor = atol(pValues[0]);
  202.     }
  203. }
  204. CSmilEndLayoutPacket::CSmilEndLayoutPacket():
  205.     CSmilPacket(SMILEndLayout)
  206. {
  207. }
  208. CSmilEndLayoutPacket::~CSmilEndLayoutPacket()
  209. {
  210. }
  211. void
  212. CSmilEndLayoutPacket::assign(const char* pName, const char** pValues,
  213.                              INT32 nValues)
  214. {
  215. }
  216. CSmilDocumentPacket::CSmilDocumentPacket():
  217.     CSmilPacket(SMILDocument),
  218.     m_ulPacketNumber(0),
  219.     m_ulTotalPackets(0)
  220. {
  221. }
  222. CSmilDocumentPacket::~CSmilDocumentPacket()
  223. {
  224. }
  225. void
  226. CSmilDocumentPacket::assign(const char* pName, const char** pValues,
  227.                             INT32 nValues)
  228. {
  229.     if(strcmp(pName, "ver") == 0 && nValues >= 1)
  230.     {
  231.         m_version = pValues[0];
  232.     }
  233.     else if(strcmp(pName, "id") == 0 && nValues >= 1)
  234.     {
  235.         m_id = pValues[0];
  236.     }
  237.     else if(strcmp(pName, "doc") == 0 && nValues >= 1)
  238.     {
  239.         m_document = pValues[0];
  240.     }
  241.     else if(strcmp(pName, "npkt") == 0 && nValues >= 1)
  242.     {
  243.         m_ulPacketNumber = atol(pValues[0]);
  244.     }
  245.     else if(strcmp(pName, "ttlpkt") == 0 && nValues >= 1)
  246.     {
  247.         m_ulTotalPackets = atol(pValues[0]);
  248.     }
  249. }
  250. CSmilAddSourcePacket::CSmilAddSourcePacket():
  251.     CSmilPacket(SMILAddSource),
  252.     m_ulDelay((UINT32)-1),
  253.     m_ulDuration((UINT32)-1),
  254.     m_ulClipStart((UINT32)-1),
  255.     m_ulClipEnd((UINT32)-1)
  256. {
  257. }
  258. void
  259. CSmilAddSourcePacket::assign(const char* pName, const char** pValues,
  260.                              INT32 nValues)
  261. {
  262.     if(strcmp(pName, "ver") == 0 && nValues >= 1)
  263.     {
  264.         m_version = pValues[0];
  265.     }
  266.     else if(strcmp(pName, "id") == 0 && nValues >= 1)
  267.     {
  268.         m_id = pValues[0];
  269.     }
  270.     else if(strcmp(pName, "src") == 0 && nValues >= 1)
  271.     {
  272.         m_src = pValues[0];
  273.     }
  274.     else if(strcmp(pName, "channel") == 0 && nValues >= 1)
  275.     {
  276.         m_channel = pValues[0];
  277.     }
  278.     else if(strcmp(pName, "group") == 0 && nValues >= 1)
  279.     {
  280.         m_nGroup = atol(pValues[0]);
  281.     }
  282.     else if(strcmp(pName, "delay") == 0 && nValues >= 1)
  283.     {
  284.         m_ulDelay = atol(pValues[0]);
  285.     }
  286.     else if(strcmp(pName, "dur") == 0 && nValues >= 1)
  287.     {
  288.         m_ulDuration = atol(pValues[0]);
  289.     }
  290.     else if(strcmp(pName, "start") == 0 && nValues >= 1)
  291.     {
  292.         m_ulClipStart = atol(pValues[0]);
  293.     }
  294.     else if(strcmp(pName, "end") == 0 && nValues >= 1)
  295.     {
  296.         m_ulClipEnd = atol(pValues[0]);
  297.     }
  298.     else if(strcmp(pName, "fill") == 0 && nValues >= 1)
  299.     {
  300.         m_fill = pValues[0];
  301.     }
  302. }
  303. CSmilSourceAddedPacket::CSmilSourceAddedPacket():
  304.     CSmilPacket(SMILSourceAdded),
  305.     m_duration(0)
  306. {
  307. }
  308. void
  309. CSmilSourceAddedPacket::assign(const char* pName, const char** pValues,
  310.                                INT32 nValues)
  311. {
  312.     if(strcmp(pName, "dur") == 0 && nValues >= 1)
  313.     {
  314.         m_duration = atol(pValues[0]);
  315.     }
  316. }
  317. CSmilPacketParser::CSmilPacketParser():
  318.     m_pRootNode(0)
  319. {
  320. }
  321. CSmilPacketParser::~CSmilPacketParser()
  322. {
  323.     deleteNode(m_pRootNode);
  324. }
  325. CSmilPacketParser::SMILPacketParseResult
  326. CSmilPacketParser::getAtom(const char*& pBuf, UINT32 len, 
  327.                            CSmilPacketTag*& pTag)
  328. {
  329.     CSmilPacketParser::SMILPacketParseResult retCode = SMILUnknown;
  330.     const char* pEnd;
  331.     const char* pCur;
  332.     pTag = 0;
  333.     pEnd = pBuf + len;
  334.     pCur = pBuf;
  335.     if(*pCur == '(')
  336.     {
  337.         pCur++;
  338.         pBuf = pCur;
  339.         retCode = SMILOpenList;
  340.     }
  341.     else if(*pCur == ')')
  342.     {
  343.         pCur++;
  344.         pBuf = pCur;
  345.         retCode = SMILCloseList;
  346.     }
  347.     else
  348.     {
  349.         // skip whitespace
  350.         while(isspace(*pCur) && (pCur < pEnd))
  351.         {
  352.             pCur++;
  353.         }
  354.         if(pCur >= pEnd)
  355.         {
  356.             pBuf = pCur;
  357.             retCode = SMILNoValue;
  358.         }
  359.         else if(*pCur == ')')
  360.         {
  361.             pCur++;
  362.             pBuf = pCur;
  363.             retCode = SMILCloseList;
  364.         }
  365.         else if(*pCur == '(')
  366.         {
  367.             pCur++;
  368.             pBuf = pCur;
  369.             retCode = SMILOpenList;
  370.         }
  371.         else
  372.         {
  373.             char* tmpBuf = new char [MAX_STRING_LEN + 2]; /* Flawfinder: ignore */ // one for null, one for luck
  374.             char* pTmpBuf = tmpBuf;
  375.             if(*pCur == '"')
  376.             {
  377.                 pCur++;
  378.                 int iLen = 0;  
  379.                 while((*pCur != '"') && (pCur < pEnd) && (++iLen < MAX_STRING_LEN))
  380.                 {
  381.                     if(*pCur == '\')
  382.                     {
  383.                         pCur++;
  384.                         *pTmpBuf++ = *pCur++;
  385.                     }
  386.                     else
  387.                     {
  388.                         *pTmpBuf++ = *pCur++;
  389.                     }
  390.                 }
  391.                 if(*pCur != '"')
  392.                 {
  393.                     pBuf = pCur;
  394.                     retCode = SMILMissingQuote;
  395.                 }
  396.                 else
  397.                 {
  398.                     *pTmpBuf = 0;
  399.                     pCur++;
  400.                 }
  401.             }
  402.             else
  403.             {
  404.                 while((pCur<pEnd) && !isspace(*pCur) && (*pCur != ')') && 
  405.                       (*pCur != '(') )
  406.                 {
  407.                     if(*pCur == '\')
  408.                     {
  409.                         pCur++;
  410.                         *pTmpBuf++ = *pCur++;
  411.                     }
  412.                     else
  413.                     {
  414.                         *pTmpBuf++ = *pCur++;
  415.                     }
  416.                 }
  417.                 *pTmpBuf = 0;
  418.             }
  419.             if( retCode != SMILMissingQuote )
  420.             {
  421.                 pTag = new CSmilPacketTag;
  422.                 pTag->m_name = tmpBuf;
  423.                 pBuf = pCur;
  424.                 retCode = SMILString;
  425.             }
  426.             HX_VECTOR_DELETE(tmpBuf);
  427.         }
  428.     }
  429.     return retCode;
  430. }
  431. CSmilPacket*
  432. CSmilPacketParser::parse(IHXBuffer* pBuffer,
  433.                          REF(CSmilPacketParser::SMILPacketParseResult) pktPrsRslt)
  434. {
  435.     BOOL bErrorOccurred = FALSE;
  436.     CSmilPacketTag* pTag = 0;
  437.     HX_RESULT pnr = HXR_OK;
  438.     if(m_pRootNode)
  439.     {
  440.         deleteNode(m_pRootNode);
  441.     }
  442.     m_pRootNode = new Node;
  443.     Node* pCurNode = m_pRootNode;
  444.     Node* pCurList = m_pRootNode;
  445.     CHXStack* pStack = new CHXStack;
  446.     CBigByteQueue* pQueue = new CBigByteQueue(pBuffer->GetSize());
  447.     pQueue->EnQueue((void*)pBuffer->GetBuffer(), pBuffer->GetSize());
  448.     BOOL bFirst = TRUE;
  449.     for(;;)
  450.     {
  451.         UINT32 bytesUsed;
  452.         UINT32 bytesAvail = pQueue->GetQueuedItemCount();
  453.         if(bytesAvail <= 0)
  454.         {
  455.             break;
  456.         }
  457.         BYTE* pBuf = new BYTE[bytesAvail];
  458.         BYTE* p = pBuf;
  459.         pQueue->DeQueue(pBuf, bytesAvail);
  460.         bytesUsed = bytesAvail;
  461.         if(pTag)
  462.         {
  463.             delete pTag;
  464.             pTag = 0;
  465.         }
  466.         SMILPacketParseResult rc = getAtom((const char*&)p, bytesAvail, pTag);
  467.         // /Fixes PR 32297 (release-build-only crash):
  468.         // In case rc is SMILMissingQuote, quit and return an error,
  469.         // otherwise a 0-sized buffer gets created later on that is the
  470.         // subject of an access violation:
  471.         INT32 lSizeToEnqueue = bytesAvail - (p - pBuf);
  472.         HX_ASSERT(lSizeToEnqueue >= 0); // /If < 0, something is messed up.
  473.         if (0 == lSizeToEnqueue  &&  SMILMissingQuote == rc)
  474.         {
  475.             pktPrsRslt = rc;
  476.             bErrorOccurred = TRUE;
  477.             goto cleanup;
  478.         }
  479.         pQueue->EnQueue(p, (UINT32)(bytesAvail - (p - pBuf)));
  480.         switch(rc)
  481.         {
  482.            case SMILOpenList:
  483.            {
  484.                Node* pNode = new Node;
  485.                if(pCurNode == m_pRootNode)
  486.                {
  487.                    pCurNode->car = pNode;
  488.                }
  489.                else
  490.                {
  491.                    pCurNode->cdr = pNode;
  492.                }
  493.                pStack->Push(pNode);
  494.                pCurNode = pNode;
  495.            }
  496.            break;
  497.            case SMILString:
  498.            {
  499.                if(bFirst)
  500.                {
  501.                    bFirst = FALSE;
  502.                }
  503.                else
  504.                {
  505.                    Node* pNode = new Node;
  506.                    if(!pCurNode->m_bIsSymbol)
  507.                    {
  508.                        if(!pCurNode->car)
  509.                            pCurNode->car = pNode;
  510.                        else
  511.                            pCurNode->cdr = pNode;
  512.                    }
  513.                    else
  514.                    {
  515.                        pCurNode->cdr = pNode;
  516.                    }
  517.                    pCurNode = pNode;
  518.                }
  519.                pCurNode->m_name = pTag->m_name;
  520.                pCurNode->m_bIsSymbol = TRUE;
  521.            }
  522.            break;
  523.            case SMILCloseList:
  524.            {
  525.                pCurNode = (Node*)pStack->Pop();
  526.            }
  527.            break;
  528.            default:
  529.                break;
  530.         }
  531.         HX_VECTOR_DELETE(pBuf);
  532.     }
  533.   cleanup:
  534.     if(pTag)
  535.     {
  536.         delete pTag;
  537.     }
  538.     delete pQueue;
  539.     delete pStack;
  540.     if (bErrorOccurred)
  541.     {
  542.         return NULL;
  543.     }
  544.     return evalNode(getRoot());
  545. }
  546. void
  547. CSmilPacketParser::deleteNode(Node* pNode)
  548. {
  549.     if(!pNode)
  550.     {
  551.         return;
  552.     }
  553.     deleteNode(pNode->car);
  554.     deleteNode(pNode->cdr);
  555.     delete pNode;
  556. }
  557. void
  558. CSmilPacketParser::eval(Node* pNode, CSmilPacket* pPacket)
  559. {
  560.     if(!pNode)
  561.         return;
  562.     BOOL bFirst = TRUE;
  563.     const char* pName = 0;
  564.     const char* pValue[MAX_ARGS] = {0};
  565.     int i = 0;
  566.     while(pNode && i < MAX_ARGS)
  567.     {
  568.         if(pNode->m_bIsSymbol)
  569.         {
  570.             if(bFirst)
  571.             {
  572.                 pName = (const char*)pNode->m_name;
  573.                 bFirst = FALSE;
  574.                 i = 0;
  575.             }
  576.             else
  577.             {
  578.                 pValue[i] = (const char*)pNode->m_name;
  579.                 i++;
  580.             }
  581.         }
  582.         else
  583.         {
  584.             eval(pNode->car, pPacket);
  585.         }
  586.         pNode = pNode->cdr;
  587.     }
  588.     if(pName)
  589.     {
  590.         pPacket->assign(pName, pValue, i);
  591.     }
  592. }
  593. CSmilPacket*
  594. CSmilPacketParser::evalNode(Node* pNode)
  595. {
  596.     if(!pNode || !pNode->m_bIsSymbol)
  597.     {
  598.         return 0;
  599.     }
  600.     CSmilPacket* pPacket = 0;
  601.     // const char* pID = 0;
  602.     const char* pName = 0;
  603.     pName = (const char*)pNode->m_name;
  604.     pNode = pNode->cdr;
  605.     if(pNode)
  606.     {
  607. //      if(pNode->m_bIsSymbol)
  608. //      {
  609. //          pID = (const char*)pNode->m_name;
  610. //          pNode = pNode->cdr;
  611. //      }
  612. //      else
  613. //      {
  614. //          pID = "<anonymous>";
  615. //      }
  616.         if(strcmp(pName, "smil-document") == 0)
  617.         {
  618.             pPacket = new CSmilDocumentPacket;
  619.         }
  620.         else if(strcmp(pName, "add-channel") == 0)
  621.         {
  622.             pPacket = new CSmilAddChannelPacket;
  623.         }
  624.         else if(strcmp(pName, "add-group") == 0)
  625.         {
  626.             pPacket = new CSmilAddGroupPacket;
  627.         }
  628.         else if(strcmp(pName, "play-group") == 0)
  629.         {
  630.             pPacket = new CSmilPlayGroupPacket;
  631.         }
  632.         else if(strcmp(pName, "add-source") == 0)
  633.         {
  634.             pPacket = new CSmilAddSourcePacket;
  635.         }
  636.         else if(strcmp(pName, "source-added") == 0)
  637.         {
  638.             pPacket = new CSmilSourceAddedPacket;
  639.         }
  640.         else if(strcmp(pName, "end-layout") == 0)
  641.         {
  642.             pPacket = new CSmilEndLayoutPacket;
  643.         }
  644.         else if(strcmp(pName, "meta") == 0)
  645.         {
  646.             pPacket = new CSmilMetaValuesPacket;
  647.         }
  648.         if(pPacket)
  649.         {
  650.             eval(pNode, pPacket);
  651.         }
  652.         return pPacket;
  653.     }
  654.     return 0;
  655. }