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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: dtrvtcon.cpp,v 1.4.20.1 2004/07/09 02:05:57 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 "hxcom.h"
  50. #include "ihxpckts.h"
  51. #include "hxdtcvt.h"
  52. #include "plghand2.h"
  53. #include "dtrvtcon.h"
  54. #include "hxmarsh.h"
  55. #include "hxstrutl.h"
  56. #include "rtsputil.h"
  57. #include "hxbuffer.h"
  58. #define HX_CONVERT_MIME_TYPE "application/vnd.rn.dataconvert."
  59. DataRevertController::DataRevertController(IUnknown* pContext)
  60. : m_pPlugin2Handler(0)
  61. , m_pContext(0)
  62. , m_pControlResp(0)
  63. , m_lRefCount(0)
  64. , m_pDataRevert(0)
  65. , m_pStreamHeaders(0)
  66. , m_pRevertedStreamHeaders(0)
  67. , m_pFileHeaders(0)
  68. , m_pResponseHeaders(0)
  69. , m_pCurrentStreamHeader(0)
  70. , m_pDataResp(0)
  71. , m_pPacketList(0)
  72. , m_pControlBufferList(0)
  73. , m_bInited(FALSE)
  74. {
  75.     m_pContext = pContext;
  76.     m_pContext->AddRef();
  77.     m_pContext->QueryInterface(IID_IHXPlugin2Handler,
  78.     (void**)&m_pPlugin2Handler);
  79. }
  80. DataRevertController::~DataRevertController()
  81. {
  82.     HX_RELEASE(m_pContext);
  83.     HX_RELEASE(m_pPlugin2Handler);
  84.     HX_RELEASE(m_pDataRevert);
  85.     HX_RELEASE(m_pCurrentStreamHeader);
  86.     CleanStreamHeaders();
  87.     CleanControlBuffers();
  88.     HX_RELEASE(m_pFileHeaders);
  89.     HX_RELEASE(m_pResponseHeaders);
  90.     delete m_pPacketList;
  91. }
  92. void
  93. DataRevertController::CleanControlBuffers()
  94. {
  95.     IHXBuffer* pBuffer;
  96.     if (m_pControlBufferList)
  97.     {
  98. while (!m_pControlBufferList->IsEmpty())
  99. {
  100.     pBuffer = (IHXBuffer*)m_pControlBufferList->RemoveHead();
  101.     pBuffer->Release();
  102. }
  103. delete m_pControlBufferList;
  104.     }
  105. }
  106. void
  107. DataRevertController::CleanStreamHeaders()
  108. {
  109.     IHXValues* pHeader;
  110.     if (m_pStreamHeaders)
  111.     {
  112. while (!m_pStreamHeaders->IsEmpty())
  113. {
  114.     pHeader = (IHXValues*)m_pStreamHeaders->RemoveHead();
  115.     pHeader->Release();
  116. }
  117. delete m_pStreamHeaders;
  118.     }
  119.     if (m_pRevertedStreamHeaders)
  120.     {
  121. while (!m_pRevertedStreamHeaders->IsEmpty())
  122. {
  123.     pHeader = (IHXValues*)m_pRevertedStreamHeaders->RemoveHead();
  124.     pHeader->Release();
  125. }
  126. delete m_pRevertedStreamHeaders;
  127.     }
  128. }
  129. void
  130. DataRevertController::SetControlResponse(DataRevertControllerResponse* pResp)
  131. {
  132.     m_pControlResp = pResp;
  133. }
  134. void
  135. DataRevertController::RevertHeaders(IHXValues* pFileHeader,
  136.     CHXSimpleList* pStreamHeaders,
  137.     IHXValues* pResponseHeaders)
  138. {
  139.     IHXBuffer* pMimeType = 0;
  140.     IHXValues* pHeader;
  141.     CHXSimpleList::Iterator i;
  142.     char* pConversionType = NULL;
  143.     IUnknown* pUnkReverter = NULL;
  144.     HX_RELEASE(m_pDataRevert);
  145.     
  146.     i = pStreamHeaders->Begin();
  147.     if (i != pStreamHeaders->End())
  148.     {
  149. pHeader = (IHXValues*)(*i);
  150. pHeader->GetPropertyCString("MimeType", pMimeType);
  151. if (!pMimeType)
  152. {
  153.     HX_ASSERT(0);
  154.     goto exit;
  155. }
  156. if (strncasecmp((const char*)pMimeType->GetBuffer(),
  157.     HX_CONVERT_MIME_TYPE, (int)strlen(HX_CONVERT_MIME_TYPE)))
  158. {
  159.     goto exit;
  160. }
  161. pConversionType = (char*)pMimeType->GetBuffer() +
  162.     strlen(HX_CONVERT_MIME_TYPE);
  163. if (m_pPlugin2Handler &&
  164.     HXR_OK == m_pPlugin2Handler->FindPluginUsingStrings(
  165. PLUGIN_CLASS, PLUGIN_REVERTER_TYPE,
  166. PLUGIN_REVERTER_MIME, pConversionType,
  167. NULL, NULL, pUnkReverter))
  168. {
  169.     pUnkReverter->QueryInterface(IID_IHXDataRevert,
  170.     (void**)&m_pDataRevert);
  171.     pUnkReverter->Release();
  172. }
  173. if (!m_pDataRevert)
  174. {
  175.     goto exit;
  176. }
  177. IHXPlugin* pPlugin;
  178. m_pDataRevert->QueryInterface(IID_IHXPlugin, (void**)&pPlugin);
  179. pPlugin->InitPlugin(m_pContext);
  180. pPlugin->Release();
  181. HX_RELEASE(pMimeType);
  182. m_pStreamHeaders = new CHXSimpleList;
  183. m_pRevertedStreamHeaders = new CHXSimpleList;
  184. IHXBuffer* pConvertHeader = 0;
  185. for (i = pStreamHeaders->Begin(); i != pStreamHeaders->End(); ++i)
  186. {
  187.     pHeader = (IHXValues*)(*i);
  188.     /*
  189.      * If this stream header was converted and flattened then
  190.      * the one we want to give to the plugin is the result
  191.      * of re-inflating that.  If not, then just give the plugin
  192.      * the one we already got.
  193.      */
  194.     if (HXR_OK == pHeader->GetPropertyBuffer("DataConvertStreamHeader",
  195.     pConvertHeader))
  196.     {
  197. pHeader = InflateConvertHeader(pConvertHeader);
  198. pConvertHeader->Release();
  199.     }
  200.     else
  201.     {
  202. IHXBuffer* pPreConvertMimeType;
  203. if (HXR_OK == pHeader->GetPropertyCString("PreConvertMimeType",
  204. pPreConvertMimeType))
  205. {
  206.     pHeader->SetPropertyCString("MimeType",
  207. pPreConvertMimeType);
  208.     pPreConvertMimeType->Release();
  209. }
  210. pHeader->AddRef();
  211.     }
  212.     m_pStreamHeaders->AddTail((void*)pHeader);
  213. }
  214. m_pResponseHeaders = pResponseHeaders;
  215. m_pResponseHeaders->AddRef();
  216. /*
  217.  * If playing through an old proxy which does not support
  218.  * initiate-session then the DataConvertBuffer will come in here.
  219.  * This is not an ideal situation because only one can come in
  220.  * at this point, but it's better then nothing. 
  221.  */
  222. IHXBuffer* pConvertBuffer = 0;
  223. if (HXR_OK == pFileHeader->GetPropertyBuffer("DataConvertBuffer",
  224.     pConvertBuffer))
  225. {
  226.     const char* pContent = (const char*)pConvertBuffer->GetBuffer();
  227.     IHXBuffer* pNewBuffer = new CHXBuffer();
  228.     int contentLen = pConvertBuffer->GetSize();
  229.     pNewBuffer->SetSize(contentLen);
  230.     int offset = BinFrom64(pContent, contentLen,
  231.     (unsigned char*)pNewBuffer->GetBuffer());
  232.     pNewBuffer->SetSize(offset);
  233.     pNewBuffer->AddRef();
  234.     ControlBufferReady(pNewBuffer);
  235.     pNewBuffer->Release();
  236.     pConvertBuffer->Release();
  237. }
  238. /*
  239.  * Again for file header, if the header was converted and
  240.  * flattened then give to plugin the inflated version of that.
  241.  * If not, then give the straight old header that we already
  242.  * have.
  243.  */
  244. if (HXR_OK == pFileHeader->GetPropertyBuffer("DataConvertFileHeader",
  245.     pConvertHeader))
  246. {
  247.     m_pFileHeaders = InflateConvertHeader(pConvertHeader);
  248.     pConvertHeader->Release();
  249. }
  250. else
  251. {
  252.     m_pFileHeaders = pFileHeader;
  253.     m_pFileHeaders->AddRef();
  254. }
  255. m_pDataRevert->DataRevertInit(this);
  256. return;
  257.     }
  258. exit:;
  259.     HX_RELEASE(pMimeType);
  260.     m_pControlResp->RevertHeadersDone(pFileHeader, 
  261.       pStreamHeaders,
  262.       pResponseHeaders,
  263.       FALSE);
  264. }
  265. void
  266. DataRevertController::ControlBufferReady(IHXBuffer* pBuffer)
  267. {
  268.     if (!m_bInited)
  269.     {
  270. if (!m_pControlBufferList)
  271. {
  272.     m_pControlBufferList = new CHXSimpleList;
  273. }
  274. m_pControlBufferList->AddTail((void*)pBuffer);
  275. pBuffer->AddRef();
  276.     }
  277.     else
  278.     {
  279. m_pDataRevert->ControlBufferReady(pBuffer);
  280.     }
  281. }
  282. /*
  283.  *  IUnknown methods
  284.  */
  285. STDMETHODIMP
  286. DataRevertController::QueryInterface(REFIID riid, void** ppvObj)
  287. {
  288.     QInterfaceList qiList[] =
  289.         {
  290.             { GET_IIDHANDLE(IID_IHXDataRevertResponse), (IHXDataRevertResponse*)this },
  291.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXDataRevertResponse*)this },
  292.         };
  293.     
  294.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  295. }
  296. STDMETHODIMP_(ULONG32)
  297. DataRevertController::AddRef()
  298. {
  299.     return InterlockedIncrement(&m_lRefCount);
  300. }
  301. STDMETHODIMP_(ULONG32)
  302. DataRevertController::Release()
  303. {
  304.     if (InterlockedDecrement(&m_lRefCount) > 0)
  305.     {
  306. return m_lRefCount;
  307.     }
  308.     delete this;
  309.     return 0;
  310. }
  311. /************************************************************************
  312.  *  IHXDataRevertResponse
  313.  */
  314. STDMETHODIMP
  315. DataRevertController::DataRevertInitDone(HX_RESULT status)
  316. {
  317.     m_bInited = TRUE;
  318.     if (m_pControlBufferList)
  319.     {
  320. IHXBuffer* pBuffer;
  321. while (!m_pControlBufferList->IsEmpty())
  322. {
  323.     pBuffer = (IHXBuffer*)m_pControlBufferList->RemoveHead();
  324.     m_pDataRevert->ControlBufferReady(pBuffer);
  325.     pBuffer->Release();
  326. }
  327.     }
  328.     m_pDataRevert->RevertFileHeader(m_pFileHeaders);
  329.     return HXR_OK;
  330. }
  331. STDMETHODIMP
  332. DataRevertController::RevertedFileHeaderReady(HX_RESULT status,
  333. IHXValues* pHeader)
  334. {
  335.     if (pHeader)
  336.     {
  337. HX_RELEASE(m_pFileHeaders);
  338. m_pFileHeaders = pHeader;
  339. pHeader->AddRef();
  340.     }
  341.     pHeader = (IHXValues*)m_pStreamHeaders->RemoveHead(); 
  342.     if (!pHeader)
  343.     {
  344. m_pControlResp->RevertHeadersDone(m_pFileHeaders,
  345.   m_pRevertedStreamHeaders, 
  346.   m_pResponseHeaders,
  347.   TRUE);
  348. return HXR_OK;
  349.     }
  350.     
  351.     HX_RELEASE(m_pCurrentStreamHeader);
  352.     m_pCurrentStreamHeader = pHeader;
  353.     m_pDataRevert->RevertStreamHeader(pHeader);
  354.     return HXR_OK;
  355. }
  356. STDMETHODIMP
  357. DataRevertController::RevertedStreamHeaderReady(HX_RESULT status,
  358. IHXValues* pHeader)
  359. {
  360.     if (!pHeader)
  361.     {
  362. pHeader = m_pCurrentStreamHeader;
  363.     }
  364.     else
  365.     {
  366. pHeader->AddRef();
  367.     }
  368.     m_pRevertedStreamHeaders->AddTail((void*)pHeader);
  369.     if (!m_pStreamHeaders->IsEmpty())
  370.     {
  371. HX_RELEASE(m_pCurrentStreamHeader);
  372. m_pCurrentStreamHeader = (IHXValues*)m_pStreamHeaders->RemoveHead();
  373. m_pDataRevert->RevertStreamHeader(m_pCurrentStreamHeader);
  374.     }
  375.     else
  376.     {
  377. m_pControlResp->RevertHeadersDone(m_pFileHeaders,
  378.   m_pRevertedStreamHeaders, 
  379.   m_pResponseHeaders,
  380.   TRUE);
  381.     }
  382.     return HXR_OK;
  383. }
  384. STDMETHODIMP
  385. DataRevertController::RevertedDataReady(HX_RESULT status, IHXPacket* pPacket)
  386. {
  387.     IHXPacket* pThisPacket;
  388.     pThisPacket = (IHXPacket*)m_pPacketList->RemoveTail();
  389.     if (pPacket)
  390.     {
  391. HX_RELEASE(pThisPacket);
  392. pThisPacket = pPacket;
  393. pThisPacket->AddRef();
  394.     }
  395.     m_pDataResp->FilterPacket(pThisPacket);
  396.     pThisPacket->Release();
  397.     return HXR_OK;
  398. }
  399. STDMETHODIMP
  400. DataRevertController::SendControlBuffer(IHXBuffer* pBuffer)
  401. {
  402.     m_pControlResp->SendControlBuffer(pBuffer);
  403.     return HXR_OK;
  404. }
  405. void
  406. DataRevertController::FilterPacket(IHXPacket* pPacket)
  407. {
  408.     if (m_pDataRevert)
  409.     {
  410. pPacket->AddRef();
  411. if (!m_pPacketList)
  412. {
  413.     m_pPacketList = new CHXSimpleList;
  414. }
  415. m_pPacketList->AddHead((void*)pPacket);
  416. m_pDataRevert->RevertData(pPacket);
  417.     }
  418.     else
  419.     {
  420. m_pDataResp->FilterPacket(pPacket);
  421.     }
  422. }
  423. void
  424. DataRevertController::SetFilterResponse(RawPacketFilter* pFilt)
  425. {
  426.     m_pDataResp = pFilt;
  427. }
  428. IHXValues*
  429. DataRevertController::InflateConvertHeader(IHXBuffer* pInflate)
  430. {
  431.     IHXValues* pNewHeader = NULL;
  432.     IHXCommonClassFactory* pCCF;
  433.     
  434.     m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  435.     (void**)&pCCF);
  436.     
  437.     pCCF->CreateInstance(CLSID_IHXValues, (void**)&pNewHeader);
  438.     ULONG32 ul;
  439.     IHXBuffer* pBuffer;
  440.     const char* p;
  441.     IHXBuffer* pTemp;
  442.     ULONG32 ulTemp;
  443.     pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pTemp);
  444.     UINT32 limit = pInflate->GetSize();
  445.     UINT32 i = 0;
  446.     p = (const char*)pInflate->GetBuffer();
  447.     while (i < pInflate->GetSize() - 5)
  448.     {
  449. if (p[i] == 'u')
  450. {
  451.     i++;
  452.     ulTemp = getlong((UINT8*) &(p[i]));
  453.     i += 4;
  454.     if (i + ulTemp > limit)
  455.     {
  456. goto error;
  457.     }
  458.     pTemp->SetSize(ulTemp + 1);
  459.     memcpy((char *)pTemp->GetBuffer(), &(p[i]), ulTemp); /* Flawfinder: ignore */
  460.     ((char*)pTemp->GetBuffer())[ulTemp] = 0;
  461.     i += ulTemp;
  462.     if (i + 4 > limit)
  463.     {
  464. goto error;
  465.     }
  466.     ul = getlong((UINT8*) &(p[i]));
  467.     i += 4;
  468.     pNewHeader->SetPropertyULONG32((char*)pTemp->GetBuffer(), ul);
  469. }
  470. else if (p[i] == 's' || p[i] == 'b')
  471. {
  472.     int at = i;
  473.     i++;
  474.     ulTemp = getlong((UINT8*) &(p[i]));
  475.     i += 4;
  476.     if (i + ulTemp > limit)
  477.     {
  478. goto error;
  479.     }
  480.     pTemp->SetSize(ulTemp + 1);
  481.     memcpy((char*)pTemp->GetBuffer(), &(p[i]), ulTemp); /* Flawfinder: ignore */
  482.     ((char*)pTemp->GetBuffer())[ulTemp] = 0;
  483.     i += ulTemp;
  484.     if (i + 4 > limit)
  485.     {
  486. goto error;
  487.     }
  488.     ulTemp = getlong((UINT8*) &(p[i]));
  489.     i += 4;
  490.     if (i + ulTemp > limit)
  491.     {
  492. goto error;
  493.     }
  494.     pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pBuffer);
  495.     pBuffer->SetSize(ulTemp);
  496.     memcpy((char*)pBuffer->GetBuffer(), &(p[i]), ulTemp); /* Flawfinder: ignore */
  497.     if (p[at] == 's')
  498.     {
  499. pNewHeader->SetPropertyCString((const char*)pTemp->GetBuffer(),
  500. pBuffer);
  501.     }
  502.     else
  503.     {
  504. pNewHeader->SetPropertyBuffer((const char*)pTemp->GetBuffer(),
  505. pBuffer);
  506.     }
  507.     pBuffer->Release();
  508.     i+= ulTemp;
  509. }
  510. else
  511. {
  512.     goto error;
  513. }
  514.     }
  515.     if (i != pInflate->GetSize())
  516.     {
  517. goto error;
  518.     }
  519.     
  520.     goto exit;
  521.     
  522. error:;
  523.     
  524. exit:;
  525.     HX_RELEASE(pTemp);
  526.     HX_RELEASE(pCCF);
  527.     
  528.     return pNewHeader;
  529. }
  530. void
  531. DataRevertController::Done(void)
  532. {
  533.     HX_RELEASE(m_pDataRevert);
  534. }