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

Symbian

开发平台:

Visual C++

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