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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: brushff.cpp,v 1.3.2.1 2004/07/09 01:57:45 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. // system
  50. #include <stdio.h>
  51. // include
  52. #include "hxcom.h"
  53. #include "hxtypes.h"
  54. #include "hxcomm.h"
  55. #include "ihxpckts.h"
  56. #include "hxfiles.h"
  57. #include "hxformt.h"
  58. #include "hxplugn.h"
  59. #include "hxver.h"
  60. // pnmisc
  61. #include "baseobj.h"
  62. // pxcomlib
  63. #include "buffutil.h"
  64. // brushff
  65. #include "brushff.h"
  66. #include "brushff.ver"
  67. // pndebug
  68. #include "errdbg.h"
  69. #include "hxheap.h"
  70. #ifdef _DEBUG
  71. #undef HX_THIS_FILE             
  72. static const char HX_THIS_FILE[] = __FILE__;
  73. #endif
  74. const char* const CBrushFileFormat::m_pszDescription       = "RealNetworks Brush File Format Plugin";
  75. const char* const CBrushFileFormat::m_pszCopyright         = HXVER_COPYRIGHT;
  76. const char* const CBrushFileFormat::m_pszMoreInfoURL       = HXVER_MOREINFO;
  77. const char* const CBrushFileFormat::m_ppszFileMimeTypes[]  = {"text/brush", NULL};
  78. const char* const CBrushFileFormat::m_ppszFileExtensions[] = {"bsh", NULL};
  79. const char* const CBrushFileFormat::m_ppszFileOpenNames[]  = {"Brush Files (*.bsh)", NULL};
  80. const char* const CBrushFileFormat::m_pszStreamMimeType    = "application/vnd.rn-brushstream";
  81. const UINT32      CBrushFileFormat::m_ulContentVersion     = HX_ENCODE_PROD_VERSION(0, 0, 0, 0);
  82. const UINT32      CBrushFileFormat::m_ulStreamVersion      = HX_ENCODE_PROD_VERSION(0, 0, 0, 0);
  83. CBrushFileFormat::CBrushFileFormat()
  84. {
  85.     m_lRefCount = 0;
  86.     Reset();
  87. };
  88. CBrushFileFormat::~CBrushFileFormat()
  89. {
  90.     Deallocate();
  91. };
  92. STDMETHODIMP CBrushFileFormat::QueryInterface(REFIID riid, void** ppvObj)
  93. {
  94.     HX_RESULT retVal = HXR_OK;
  95.     if (IsEqualIID(riid, IID_IUnknown))
  96.     {
  97.         AddRef();
  98.         *ppvObj = (IUnknown*) (IHXPlugin*) this;
  99.     }
  100.     else if (IsEqualIID(riid, IID_IHXPlugin))
  101.     {
  102.         AddRef();
  103.         *ppvObj = (IHXPlugin*) this;
  104.     }
  105.     else if (IsEqualIID(riid, IID_IHXFileFormatObject))
  106.     {
  107.         AddRef();
  108.         *ppvObj = (IHXFileFormatObject*) this;
  109.     }
  110.     else if (IsEqualIID(riid, IID_IHXFileResponse))
  111.     {
  112.         AddRef();
  113.         *ppvObj = (IHXFileResponse*) this;
  114.     }
  115.     else
  116.     {
  117.         *ppvObj = NULL;
  118.         retVal  = HXR_NOINTERFACE;
  119.     }
  120.     return retVal;
  121. }
  122. STDMETHODIMP_(UINT32) CBrushFileFormat::AddRef()
  123. {
  124.     return InterlockedIncrement(&m_lRefCount);
  125. }
  126. STDMETHODIMP_(UINT32) CBrushFileFormat::Release()
  127. {
  128.     if (InterlockedDecrement(&m_lRefCount) > 0)
  129.     {
  130.         return m_lRefCount;
  131.     }
  132.     delete this;
  133.     return 0;
  134. }
  135. STDMETHODIMP CBrushFileFormat::GetPluginInfo(REF(BOOL)        rbLoadMultiple,
  136.                                              REF(const char*) rpszDescription,
  137.                                              REF(const char*) rpszCopyright,
  138.                                              REF(const char*) rpszMoreInfoURL,
  139.                                              REF(UINT32)      rulVersionNumber)
  140. {
  141.     rbLoadMultiple   = TRUE;
  142.     rpszDescription  = (const char*) m_pszDescription;
  143.     rpszCopyright    = (const char*) m_pszCopyright;
  144.     rpszMoreInfoURL  = (const char*) m_pszMoreInfoURL;
  145.     rulVersionNumber = TARVER_ULONG32_VERSION;
  146.     return HXR_OK;
  147. }
  148. STDMETHODIMP CBrushFileFormat::InitPlugin(IUnknown* pContext)
  149. {
  150.     HX_RESULT retVal = HXR_FAIL;
  151.     if (pContext)
  152.     {
  153.         // Clear out everything
  154.         Deallocate();
  155.         // Save a copy of the calling context
  156.         m_pContext = pContext;
  157.         m_pContext->AddRef();
  158.         // Get an interface to the common class factory
  159.         retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  160.                                             (void**) &m_pCommonClassFactory);
  161.         if (SUCCEEDED(retVal))
  162.         {
  163.             // Set the state
  164.             m_ulState = kStatePluginInitialized;
  165.         }
  166.     }
  167.     return retVal;
  168. }
  169. STDMETHODIMP CBrushFileFormat::GetFileFormatInfo(REF(const char**) rppszFileMimeTypes,
  170.                                                  REF(const char**) rppszFileExtensions,  
  171.                                                  REF(const char**) rppszFileOpenNames)
  172. {
  173.     rppszFileMimeTypes  = (const char**) m_ppszFileMimeTypes;
  174.     rppszFileExtensions = (const char**) m_ppszFileExtensions;
  175.     rppszFileOpenNames  = (const char**) m_ppszFileOpenNames;
  176.     return HXR_OK;
  177. }
  178. STDMETHODIMP CBrushFileFormat::InitFileFormat(IHXRequest*        pRequest, 
  179.                                               IHXFormatResponse* pFormatResponse,
  180.                                               IHXFileObject*     pFileObject)
  181. {
  182.     HX_RESULT retVal = HXR_OK;
  183.     if (pRequest && pFormatResponse && pFileObject)
  184.     {
  185.         if (m_ulState == kStatePluginInitialized)
  186.         {
  187.             // Find out from the 822 headers if this
  188.             // is a NULL brush
  189.             m_bNullBrush = IsNullBrush(pRequest);
  190.             // Save members
  191.             HX_RELEASE(m_pFormatResponse);
  192.             m_pFormatResponse = pFormatResponse;
  193.             m_pFormatResponse->AddRef();
  194.             HX_RELEASE(m_pFileObject);
  195.             m_pFileObject = pFileObject;
  196.             m_pFileObject->AddRef();
  197.             // Set the state
  198.             m_ulState = kStateFileInitPending;
  199.             // Init the file object
  200.             m_pFileObject->Init(HX_FILE_READ | HX_FILE_BINARY, this);
  201.         }
  202.         else
  203.         {
  204.             retVal = HXR_UNEXPECTED;
  205.         }
  206.     }
  207.     else
  208.     {
  209.         retVal = HXR_FAIL;
  210.     }
  211.     if (FAILED(retVal) && pFormatResponse)
  212.     {
  213.         pFormatResponse->InitDone(retVal);
  214.     }
  215.     return retVal;
  216. }
  217. STDMETHODIMP CBrushFileFormat::GetFileHeader()
  218. {
  219.     HX_RESULT retVal = HXR_OK;
  220.     if (m_ulState == kStateFileFormatInitialized)
  221.     {
  222.         // Get an IHXValues object
  223.         IHXValues* pFileHeader = NULL;
  224.         retVal                  = m_pCommonClassFactory->CreateInstance(CLSID_IHXValues,
  225.                                                                         (void**) &pFileHeader);
  226.         if (SUCCEEDED(retVal))
  227.         {
  228.             // Set the stream count
  229.             pFileHeader->SetPropertyULONG32("StreamCount",    1);
  230.             pFileHeader->SetPropertyULONG32("IsRealDataType", 1);
  231.             // Set the new state
  232.             m_ulState = kStateFileHeaderSent;
  233.             // Call the response interface
  234.             m_pFormatResponse->FileHeaderReady(HXR_OK, pFileHeader);
  235.         }
  236.         HX_RELEASE(pFileHeader);
  237.         if (FAILED(retVal))
  238.         {
  239.             m_pFormatResponse->FileHeaderReady(retVal, NULL);
  240.         }
  241.     }
  242.     else
  243.     {
  244.         retVal = HXR_UNEXPECTED;
  245.     }
  246.     return retVal;
  247. }
  248. STDMETHODIMP CBrushFileFormat::GetStreamHeader(UINT16 usStreamNum)
  249. {
  250.     HX_RESULT retVal = HXR_OK;
  251.     if (m_ulState == kStateFileHeaderSent)
  252.     {
  253.         // Create an IHXValues object
  254.         IHXValues* pStreamHeader = NULL;
  255.         retVal                    = m_pCommonClassFactory->CreateInstance(CLSID_IHXValues,
  256.                                                                           (void**) &pStreamHeader);
  257.         if (SUCCEEDED(retVal))
  258.         {
  259.             // Create mime type IHXBuffer string
  260.             IHXBuffer* pMimeStr = NULL;
  261.             retVal = PXUtilities::CreateStringBuffer((const char*) m_pszStreamMimeType,
  262.                                                      m_pContext,
  263.                                                      pMimeStr);
  264.             if (SUCCEEDED(retVal))
  265.             {
  266.                 // Create intrinsic duration type string buffer
  267.                 IHXBuffer* pIntrin = NULL;
  268.                 retVal = PXUtilities::CreateStringBuffer("intrinsicDurationDiscrete",
  269.                                                          m_pContext,
  270.                                                          pIntrin);
  271.                 if (SUCCEEDED(retVal))
  272.                 {
  273.                     // Create ASM rulebook string buffer
  274.                     char szASM[64]; /* Flawfinder: ignore */
  275.                     sprintf(szASM, "AverageBandwidth=%lu,Priority=5;", kDefaultBitrate); /* Flawfinder: ignore */
  276.                     IHXBuffer* pASM = NULL;
  277.                     retVal = PXUtilities::CreateStringBuffer((const char*) szASM,
  278.                                                              m_pContext, pASM);
  279.                     if (SUCCEEDED(retVal))
  280.                     {
  281.                         // Set the properties
  282.                         pStreamHeader->SetPropertyULONG32("StreamNumber",          0);
  283.                         pStreamHeader->SetPropertyULONG32("MaxBitRate",            kDefaultBitrate);
  284.                         pStreamHeader->SetPropertyULONG32("AvgBitRate",            kDefaultBitrate);
  285.                         pStreamHeader->SetPropertyULONG32("MaxPacketSize",         kDefaultPacketSize);
  286.                         pStreamHeader->SetPropertyULONG32("AvgPacketSize",         kDefaultPacketSize);
  287.                         pStreamHeader->SetPropertyULONG32("Preroll",               kDefaultPreroll);
  288.                         pStreamHeader->SetPropertyULONG32("Duration",              kDefaultDuration);
  289.                         pStreamHeader->SetPropertyCString("MimeType",              pMimeStr);
  290.                         pStreamHeader->SetPropertyULONG32("ContentVersion",        m_ulContentVersion);
  291.                         pStreamHeader->SetPropertyULONG32("StreamVersion",         m_ulStreamVersion);
  292.                         pStreamHeader->SetPropertyCString("ASMRuleBook",           pASM);
  293.                         pStreamHeader->SetPropertyCString("intrinsicDurationType", pIntrin);
  294.                         if (m_pFileBuffer)
  295.                         {
  296.                             pStreamHeader->SetPropertyBuffer("OpaqueData", m_pFileBuffer);
  297.                         }
  298.                         if (m_bNullBrush)
  299.                         {
  300.                             pStreamHeader->SetPropertyULONG32("NullBrush", 1);
  301.                         }
  302.                         // Set the new state
  303.                         m_ulState = kStateReadyForGetPacket;
  304.                         // Pass the stream header back to the server
  305.                         m_pFormatResponse->StreamHeaderReady(HXR_OK, pStreamHeader);
  306.                     }
  307.                     HX_RELEASE(pASM);
  308.                 }
  309.                 HX_RELEASE(pIntrin);
  310.             }
  311.             HX_RELEASE(pMimeStr);
  312.         }
  313.         HX_RELEASE(pStreamHeader);
  314.         // Now we can release the file buffer
  315.         HX_RELEASE(m_pFileBuffer);
  316.     }
  317.     else
  318.     {
  319.         retVal = HXR_UNEXPECTED;
  320.     }
  321.     if (FAILED(retVal))
  322.     {
  323.         m_pFormatResponse->StreamHeaderReady(retVal, NULL);
  324.     }
  325.     return retVal;
  326. }
  327. STDMETHODIMP CBrushFileFormat::GetPacket(UINT16 usStreamNum)
  328. {
  329.     HX_RESULT retVal = HXR_OK;
  330.     if (m_ulState == kStateReadyForGetPacket)
  331.     {
  332.         if (usStreamNum == 0)
  333.         {
  334.             // Set the state
  335.             m_ulState = kStateStreamDoneSent;
  336.             // Read from the file
  337.             m_pFormatResponse->StreamDone(0);
  338.         }
  339.         else
  340.         {
  341.             retVal = HXR_INVALID_PARAMETER;
  342.         }
  343.     }
  344.     else
  345.     {
  346.         retVal = HXR_UNEXPECTED;
  347.     }
  348.     return retVal;
  349. }
  350. STDMETHODIMP CBrushFileFormat::Seek(UINT32 ulOffset)
  351. {
  352.     HX_RESULT retVal = HXR_OK;
  353.     if (m_pFormatResponse)
  354.     {
  355.         // Set the state
  356.         m_ulState = kStateReadyForGetPacket;
  357.         // Tell the format response the seek is done
  358.         m_pFormatResponse->SeekDone(HXR_OK);
  359.     }
  360.     else
  361.     {
  362.         retVal = HXR_UNEXPECTED;
  363.     }
  364.     return retVal;
  365. }
  366. STDMETHODIMP CBrushFileFormat::Close()
  367. {
  368.     HX_RESULT retVal = HXR_OK;
  369.     Deallocate();
  370.     return retVal;
  371. }
  372. STDMETHODIMP CBrushFileFormat::InitDone(HX_RESULT status)
  373. {
  374.     HX_RESULT retVal = HXR_OK;
  375.     if (m_ulState == kStateFileInitPending)
  376.     {
  377.         if (SUCCEEDED(status))
  378.         {
  379.             // Set the new state
  380.             m_ulState = kStateFileReadPending;
  381.             // Read the first kDefaultPacketSize bytes of the file
  382.             m_pFileObject->Read(kDefaultPacketSize);
  383.         }
  384.         else
  385.         {
  386.             // Set the state
  387.             m_ulState = kStateError;
  388.             // Inform the response interface of the error
  389.             m_pFormatResponse->InitDone(status);
  390.         }
  391.     }
  392.     else
  393.     {
  394.         retVal = HXR_UNEXPECTED;
  395.     }
  396.     return retVal;
  397. }
  398. STDMETHODIMP CBrushFileFormat::SeekDone(HX_RESULT status)
  399. {
  400.     return HXR_UNEXPECTED;
  401. }
  402. STDMETHODIMP CBrushFileFormat::ReadDone(HX_RESULT status, IHXBuffer* pBuffer)
  403. {
  404.     HX_RESULT retVal = HXR_OK;
  405.     if (m_ulState == kStateFileReadPending)
  406.     {
  407.         if (SUCCEEDED(status))
  408.         {
  409.             // If we already have a buffer, then we'll need to
  410.             // copy this buffer into the bigger one. In practical
  411.             // use, this should never happen, since the SMIL-generated
  412.             // "brush file" should only be a few bytes, well within
  413.             // kDefaultPacketSize bytes.
  414.             if (m_pFileBuffer)
  415.             {
  416.                 IHXBuffer* pTmp = NULL;
  417.                 m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pTmp);
  418.                 if (pTmp)
  419.                 {
  420.                     // Set the size
  421.                     pTmp->SetSize(m_pFileBuffer->GetSize() + pBuffer->GetSize());
  422.                     // Copy in the old buffer
  423.                     memcpy(pTmp->GetBuffer(), m_pFileBuffer->GetBuffer(), m_pFileBuffer->GetSize()); /* Flawfinder: ignore */
  424.                     // Copy in the new buffer
  425.                     memcpy(pTmp->GetBuffer() + m_pFileBuffer->GetSize(), /* Flawfinder: ignore */
  426.                            pBuffer->GetBuffer(), pBuffer->GetSize());
  427.                     // Now get rid of the old buffer
  428.                     HX_RELEASE(m_pFileBuffer);
  429.                     m_pFileBuffer = pTmp;
  430.                     m_pFileBuffer->AddRef();
  431.                 }
  432.                 HX_RELEASE(pTmp);
  433.             }
  434.             else
  435.             {
  436.                 m_pFileBuffer = pBuffer;
  437.                 m_pFileBuffer->AddRef();
  438.             }
  439.             // Set the new state
  440.             m_ulState = kStateFileReadPending;
  441.             // Read the first kDefaultPacketSize bytes of the file
  442.             m_pFileObject->Read(kDefaultPacketSize);
  443.         }
  444.         else
  445.         {
  446.             // Set the state
  447.             m_ulState = kStateFileClosePending;
  448.             // Close the file
  449.             m_pFileObject->Close();
  450.         }
  451.     }
  452.     else
  453.     {
  454.         retVal = HXR_UNEXPECTED;
  455.     }
  456.     return retVal;
  457. }
  458. STDMETHODIMP CBrushFileFormat::WriteDone(HX_RESULT status)
  459. {
  460.     // We don't ever write, so we don't expect to get this...
  461.     return HXR_UNEXPECTED;
  462. }
  463. STDMETHODIMP CBrushFileFormat::CloseDone(HX_RESULT status)
  464. {
  465.     HX_RESULT retVal = HXR_OK;
  466.     if (m_ulState == kStateFileClosePending)
  467.     {
  468.         // We can't be initialized successfully if we
  469.         // don't have a file buffer
  470.         if (!m_pFileBuffer)
  471.         {
  472.             status = HXR_FAIL;
  473.         }
  474.         // Set the state
  475.         m_ulState = (SUCCEEDED(status) ? kStateFileFormatInitialized : kStateError);
  476.         // Send a stream done
  477.         m_pFormatResponse->InitDone(status);
  478.     }
  479.     else
  480.     {
  481.         retVal = HXR_UNEXPECTED;
  482.     }
  483.     return retVal;
  484. }
  485. HX_RESULT STDAPICALLTYPE CBrushFileFormat::HXCreateInstance(IUnknown** ppIUnknown)
  486. {
  487.     HX_RESULT retVal = HXR_FAIL;
  488.     if (ppIUnknown)
  489.     {
  490.         // Create the object
  491.         CBrushFileFormat* pObj = new CBrushFileFormat();
  492.         if (pObj)
  493.         {
  494.             // QI for IUnknown
  495.             retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
  496.         }
  497.     }
  498.     return retVal;
  499. }
  500. HX_RESULT STDAPICALLTYPE CBrushFileFormat::CanUnload2()
  501. {
  502.     return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK );
  503. }
  504. void CBrushFileFormat::Deallocate()
  505. {
  506.     HX_RELEASE(m_pContext);
  507.     HX_RELEASE(m_pFileObject);
  508.     HX_RELEASE(m_pFormatResponse);
  509.     HX_RELEASE(m_pCommonClassFactory);
  510.     HX_RELEASE(m_pFileBuffer);
  511.     Reset();
  512. }
  513. void CBrushFileFormat::Reset()
  514. {
  515.     m_pContext            = NULL;
  516.     m_pFileObject         = NULL;
  517.     m_pFormatResponse     = NULL;
  518.     m_pCommonClassFactory = NULL;
  519.     m_pFileBuffer         = NULL;
  520.     m_ulState             = kStateConstructed;
  521.     m_bNullBrush          = FALSE;
  522. }
  523. BOOL CBrushFileFormat::IsNullBrush(IHXRequest* pRequest)
  524. {
  525.     BOOL bRet = FALSE;
  526.     if (pRequest)
  527.     {
  528.         // Get the request headers
  529.         IHXValues* pReqHdrs = NULL;
  530.         pRequest->GetRequestHeaders(pReqHdrs);
  531.         if (pReqHdrs)
  532.         {
  533.             // See if there was a "NullBrush" flag
  534.             IHXBuffer* pTmp = NULL;
  535.             pReqHdrs->GetPropertyCString("NullBrush", pTmp);
  536.             if (pTmp)
  537.             {
  538.                 // Yes, there WAS a "NullBrush" flag
  539.                 bRet = TRUE;
  540.             }
  541.             HX_RELEASE(pTmp);
  542.         }
  543.         HX_RELEASE(pReqHdrs);
  544.     }
  545.     return bRet;
  546. }