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

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
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "hxcom.h"
  39. #include "hxresult.h"
  40. #include "hxcomm.h"
  41. #include "ihxpckts.h"
  42. #include "hxfiles.h"
  43. // hxmisc
  44. #include "baseobj.h"
  45. // pxcomlib
  46. #include "fileread.h"
  47. // hxdebug
  48. #include "errdbg.h"
  49. #include "hxheap.h"
  50. #ifdef _DEBUG
  51. #undef HX_THIS_FILE     
  52. static char HX_THIS_FILE[] = __FILE__;
  53. #endif
  54. CHXFileReader::CHXFileReader()
  55. {
  56.     m_lRefCount           = 0;
  57.     m_pContext            = NULL;
  58.     m_pFileObject         = NULL;
  59.     m_pResponse           = NULL;
  60.     m_pCommonClassFactory = NULL;
  61.     m_ulState             = kStateConstructed;
  62.     m_ulFlags             = 0;
  63.     m_ulCurrentOffset     = 0;
  64.     m_ulReqOffset         = 0;
  65.     m_ulReqNumBytes       = 0;
  66. }
  67. CHXFileReader::~CHXFileReader()
  68. {
  69.     Deallocate();
  70. }
  71. void CHXFileReader::Deallocate()
  72. {
  73.     HX_RELEASE(m_pContext);
  74.     HX_RELEASE(m_pFileObject);
  75.     HX_RELEASE(m_pResponse);
  76.     HX_RELEASE(m_pCommonClassFactory);
  77. }
  78. STDMETHODIMP CHXFileReader::Init(IUnknown*              pContext,
  79.                                  IHXFileObject*        pFileObject,
  80.                                  BOOL                   bCanPreload,
  81.                                  BOOL                   bCanCache,
  82.                                  CHXFileReaderResponse* pResponse)
  83. {
  84.     HX_RESULT retVal = HXR_OK;
  85.     if (pContext && pFileObject && pResponse &&
  86.         !bCanPreload && !bCanCache) // XXXMEH - for now, no preload or caching
  87.     {
  88.         if (m_ulState == kStateConstructed)
  89.         {
  90.             // Save arguments into members
  91.             HX_RELEASE(m_pContext);
  92.             m_pContext = pContext;
  93.             m_pContext->AddRef();
  94.             HX_RELEASE(m_pFileObject);
  95.             m_pFileObject = pFileObject;
  96.             m_pFileObject->AddRef();
  97.             HX_RELEASE(m_pResponse);
  98.             m_pResponse = pResponse;
  99.             m_pResponse->AddRef();
  100.             // Save flags
  101.             if (bCanPreload)
  102.             {
  103.                 m_ulFlags |= kFlagCanPreload;
  104.             }
  105.             if (bCanCache)
  106.             {
  107.                 m_ulFlags |= kFlagCanCache;
  108.             }
  109.             // Get an IHXCommonClassFactory interface
  110.             HX_RELEASE(m_pCommonClassFactory);
  111.             retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
  112.                                                 (void**) &m_pCommonClassFactory);
  113.             if (SUCCEEDED(retVal))
  114.             {
  115.                 // Set the new state
  116.                 m_ulState = kStateInitPending;
  117.                 // Init the file object
  118.                 m_pFileObject->Init(HX_FILE_READ | HX_FILE_BINARY, this);
  119.             }
  120.         }
  121.         else
  122.         {
  123.             retVal = HXR_UNEXPECTED;
  124.         }
  125.     }
  126.     else
  127.     {
  128.         retVal = HXR_INVALID_PARAMETER;
  129.     }
  130.     return retVal;
  131. }
  132. STDMETHODIMP CHXFileReader::Read(UINT32 ulOffset, UINT32 ulNumBytes)
  133. {
  134.     HX_RESULT retVal = HXR_OK;
  135.     if (m_ulState == kStateReady)
  136.     {
  137.         // Save the read information
  138.         m_ulReqOffset   = ulOffset;
  139.         m_ulReqNumBytes = ulNumBytes;
  140.         // Are we already at the right place in the file?
  141.         if (ulOffset != m_ulCurrentOffset)
  142.         {
  143.             // We need to seek to the new offset
  144.             //
  145.             // Set the state
  146.             m_ulState = kStateSeekPending;
  147.             // Call IHXFileObject::Seek()
  148.             m_pFileObject->Seek(ulOffset, FALSE);
  149.         }
  150.         else
  151.         {
  152.             // We're already at the right offset, just read
  153.             //
  154.             // Set the state
  155.             m_ulState = kStateReadPending;
  156.             // Call IHXFileObject::Read()
  157.             m_pFileObject->Read(ulNumBytes);
  158.         }
  159.     }
  160.     else
  161.     {
  162.         retVal = HXR_UNEXPECTED;
  163.     }
  164.     return retVal;
  165. }
  166. STDMETHODIMP CHXFileReader::Shutdown()
  167. {
  168.     HX_RESULT retVal = HXR_OK;
  169.     if (m_pResponse)
  170.     {
  171.         if (m_ulState == kStateConstructed)
  172.         {
  173.             // We haven't Init()'d the file object yet,
  174.             // so there's no need to close it. We can just
  175.             // call back with ShutdownDone(). No need to change
  176.             // the state either
  177.             m_pResponse->ShutdownDone();
  178.         }
  179.         else if (m_ulState == kStateReady)
  180.         {
  181.             // No pending callback, but we do need to close
  182.             // the file.
  183.             //
  184.             // Set the state
  185.             m_ulState = kStateClosePending;
  186.             // Close the file
  187.             m_pFileObject->Close();
  188.         }
  189.         else if (m_ulState == kStateInitPending ||
  190.                  m_ulState == kStateSeekPending ||
  191.                  m_ulState == kStateReadPending)
  192.         {
  193.             // We are awaiting a callback when we got this 
  194.             // Shutdown(). Therefore, we will go ahead and call
  195.             // Close() on the file object, and then make sure
  196.             // we don't do anything in these callbacks.
  197.             //
  198.             // Set the state
  199.             m_ulState = kStateClosePending;
  200.             //
  201.             m_pFileObject->Close();
  202.         }
  203.         else if (m_ulState == kStateClosePending)
  204.         {
  205.             // We got a Shutdown() while after we had already called
  206.             // Close() on the file object. Nothing to do here
  207.             // since we will call ShutdownDone() already after we
  208.             // get the CloseDone().
  209.         }
  210.         else
  211.         {
  212.             // Unknown state
  213.             retVal = HXR_UNEXPECTED;
  214.         }
  215.     }
  216.     else
  217.     {
  218.         retVal = HXR_UNEXPECTED;
  219.     }
  220.     return retVal;
  221. }
  222. STDMETHODIMP CHXFileReader::QueryInterface(REFIID riid, void** ppvObj)
  223. {
  224.     HX_RESULT retVal = HXR_OK;
  225.     if (IsEqualIID(riid, IID_IUnknown))
  226.     {
  227.         AddRef();
  228.         *ppvObj = this;
  229.     }
  230.     else if (IsEqualIID(riid, IID_IHXFileResponse))
  231.     {
  232.         AddRef();
  233.         *ppvObj = (IHXFileResponse*) this;
  234.     }
  235.     else
  236.     {
  237.         *ppvObj = NULL;
  238.         retVal  = HXR_NOINTERFACE;
  239.     }
  240.     return retVal;
  241. }
  242. STDMETHODIMP_(UINT32) CHXFileReader::AddRef()
  243. {
  244.     return InterlockedIncrement(&m_lRefCount);
  245. }
  246. STDMETHODIMP_(UINT32) CHXFileReader::Release()
  247. {
  248.     
  249.     if (InterlockedDecrement(&m_lRefCount) > 0)
  250.     {
  251.         return m_lRefCount;
  252.     }
  253.     delete this;
  254.     return 0;
  255. }
  256. STDMETHODIMP CHXFileReader::InitDone(HX_RESULT status)
  257. {
  258.     HX_RESULT retVal = HXR_OK;
  259.     if (m_ulState == kStateInitPending)
  260.     {
  261.         // Set the state
  262.         m_ulState  = (SUCCEEDED(status) ? kStateReady : kStateConstructed);
  263.         // Tell the response interface we've initialized
  264.         m_pResponse->InitDone(status);
  265.     }
  266.     else if (m_ulState == kStateClosePending)
  267.     {
  268.         // We got a Shutdown() while we were waiting
  269.         // for the InitDone() callback. Therefore, do 
  270.         // nothing here.
  271.     }
  272.     else
  273.     {
  274.         retVal = HXR_UNEXPECTED;
  275.     }
  276.     return retVal;
  277. }
  278. STDMETHODIMP CHXFileReader::CloseDone(HX_RESULT status)
  279. {
  280.     HX_RESULT retVal = HXR_OK;
  281.     if (m_ulState == kStateClosePending)
  282.     {
  283.         // Set the state
  284.         m_ulState = kStateReady;
  285.         // Tell the response interface that we've shutdown
  286.         m_pResponse->ShutdownDone();
  287.     }
  288.     else
  289.     {
  290.         retVal = HXR_UNEXPECTED;
  291.     }
  292.     return retVal;
  293. }
  294. STDMETHODIMP CHXFileReader::ReadDone(HX_RESULT status, IHXBuffer* pBuffer)
  295. {
  296.     HX_RESULT retVal = HXR_OK;
  297.     if (m_ulState == kStateReadPending)
  298.     {
  299.         // Set the state
  300.         m_ulState = kStateReady;
  301.         // Did we succeed in reading?
  302.         if (SUCCEEDED(status) && pBuffer)
  303.         {
  304.             // We successfully read the number of bytes
  305.             //
  306.             // Update the current offset
  307.             m_ulCurrentOffset += pBuffer->GetSize();
  308.             // Tell the response interface
  309.             m_pResponse->ReadDone(status, pBuffer);
  310.         }
  311.         else
  312.         {
  313.             // We failed to read
  314.             //
  315.             // Tell the response interface
  316.             m_pResponse->ReadDone(status, NULL);
  317.         }
  318.     }
  319.     else if (m_ulState == kStateClosePending)
  320.     {
  321.         // We got a Shutdown() while we were waiting to
  322.         // get this ReadDone() callback. Therefore we do
  323.         // nothing here.
  324.     }
  325.     else
  326.     {
  327.         retVal = HXR_UNEXPECTED;
  328.     }
  329.     return retVal;
  330. }
  331. STDMETHODIMP CHXFileReader::WriteDone(HX_RESULT status)
  332. {
  333.     HX_RESULT retVal = HXR_NOTIMPL;
  334.     return retVal;
  335. }
  336. STDMETHODIMP CHXFileReader::SeekDone(HX_RESULT status)
  337. {
  338.     HX_RESULT retVal = HXR_OK;
  339.     if (m_ulState == kStateSeekPending)
  340.     {
  341.         if (SUCCEEDED(status))
  342.         {
  343.             // We successfully seeked - update the current offset
  344.             m_ulCurrentOffset = m_ulReqOffset;
  345.             // Set the state
  346.             m_ulState = kStateReadPending;
  347.             // Now read the saved number of bytes
  348.             m_pFileObject->Read(m_ulReqNumBytes);
  349.         }
  350.         else
  351.         {
  352.             // We failed to seek
  353.             //
  354.             // Set the state
  355.             m_ulState = kStateReady;
  356.             // Tell the response interface
  357.             m_pResponse->ReadDone(status, NULL);
  358.         }
  359.     }
  360.     else if (m_ulState == kStateClosePending)
  361.     {
  362.         // We got a Shutdown() while we were waiting on
  363.         // this SeekDone() callback. Therefore, do nothing
  364.         // here.
  365.     }
  366.     else
  367.     {
  368.         retVal = HXR_UNEXPECTED;
  369.     }
  370.     return retVal;
  371. }