fswtchr.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,243 行 · 第 1/2 页

CPP
1,243
字号
	m_bRelative = bRelative;
	m_pResponse = pResponse;
	m_pResponse->AddRef();

	m_State = FSWCHR_ProcSeek;

	retVal = GetFileHandle(pFileName);
    }

    return retVal;
}

/****************************************************************************
 *  Advise
 */
STDMETHODIMP CFileSwitcher::Advise(ULONG32 ulInfo,
				   const char* pFileName)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if ((m_State == FSWCHR_Ready) && (!m_bClosing))
    {
	HX_ASSERT(!m_pResponse);

	m_ulSize = ulInfo;

	m_State = FSWCHR_ProcAdvise;

	retVal = GetFileHandle(pFileName);
    }

    return retVal;
}

/****************************************************************************
 *  Close
 */
STDMETHODIMP CFileSwitcher::Close(IHXFileResponse *pResponse,
				  const char* pFileName)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if ((m_State != FSWCHR_Offline) && (!m_bClosing))
    {
	if (pFileName)
	{
	    // File Specific Closing - must be synchronous
	    if (m_State == FSWCHR_Ready)
	    {
		FileHandle *pFileHandle;
	
		HX_ASSERT(!m_pResponse);
		m_pResponse = pResponse;
		pResponse->AddRef();

		retVal = HXR_OK;
		m_State = FSWCHR_ProcClose;
		
		pFileHandle = FindFileHandle(pFileName);
		
		if (pFileHandle)
		{
		    if (pFileHandle->m_pFileName)
		    {
			pFileHandle->SetName(NULL);

			HX_ASSERT(m_uCurrentChildCount > 0);

			m_uCurrentChildCount--;
		    }
		    
		    retVal = CloseFileHandleObject(pFileHandle);
		}
		else
		{
		    CloseDone(HXR_OK);
		}
	    }
	}
	else
	{
	    // This is a general closure (shutdown)
	    // which need not be synchronous
	    UINT16 i;
	    FileHandle* pFileHandle;
	    
	    HX_ASSERT(m_pHandleTable);
	    
	    retVal = HXR_OK;

	    m_bClosing = TRUE;
	    m_CloseStatus = HXR_OK;

	    HX_RELEASE(m_pResponse);
	    m_pResponse = pResponse;
	    pResponse->AddRef();
	    
	    if (m_State == FSWCHR_ProcClose)
	    {
		// there is an additional outstanding Close to complete 
		// for a child
		m_uCurrentChildCount++;
	    }
	    
	    // Close Children
	    HX_ASSERT(m_uCurrentChildCount <= m_uMaxChildCount);
	    
	    for (i = m_uCurrentChildCount, pFileHandle = m_pHandleTable + 1;
		 i > 0;
		 i--, pFileHandle++)
	    {
		if (pFileHandle->m_pFileName)
		{
		    pFileHandle->SetName(NULL);
		    
		    if (FAILED(CloseFileHandleObject(pFileHandle)))
		    {
			// Recover by forcing the closing on this level
			CloseDone(HXR_OK);
		    }
		}
	    }

	    // Close the root file
	    if (FAILED(CloseFileHandleObject(m_pHandleTable)))
	    {
		// Recover by forcing the closing on this level
		CloseDone(HXR_OK);
	    }
	}
    }

    return retVal;
}


/****************************************************************************
 *  IHXFileResponse methods
 */
/****************************************************************************
 *  InitDone
 */
STDMETHODIMP CFileSwitcher::InitDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_OK;

    if (m_State != FSWCHR_Offline)
    {
	if (m_State != FSWCHR_ProcInit)
	{
	    HX_ASSERT(m_pCurrentHandle);
	    HX_ASSERT(m_pCurrentHandle->m_pFileObject);

	    // This must be initialization completion
	    // as part of obtaining file handle during
	    // Read, Write or Seek
	    if (SUCCEEDED(status))
	    {
		status = FileHandleReady();
	    }

	    if (FAILED(status))
	    {
		m_pCurrentHandle->Clear();

		// Must report Failure to the requestor
		retVal = HandleFailureAsync(status);
	    }
	}
	else
	{
	    // Initialization complete
	    IHXFileResponse* pResponse = m_pResponse;

	    HX_ASSERT(pResponse);

	    m_pResponse = NULL;
	    if (SUCCEEDED(status))
	    {
		m_State = FSWCHR_Ready;
	    }

	    retVal = pResponse->InitDone(status);

	    pResponse->Release();
	}
    }
    else
    {
	retVal = HXR_UNEXPECTED;
    }

    return retVal;
}

/****************************************************************************
 *  CloseDone
 */
STDMETHODIMP CFileSwitcher::CloseDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_State != FSWCHR_Offline)
    {
	if (((m_State == FSWCHR_ProcRead) ||
	     (m_State == FSWCHR_ProcWrite) ||
	     (m_State == FSWCHR_ProcSeek) ||
	     (m_State == FSWCHR_ProcAdvise)) &&
	    (!m_bClosing))
	{
	    // It must be a close due to freeing of a stale
	    // file handle so we can create a new one
	    retVal = HXR_OK;

	    if (SUCCEEDED(status))
	    {
		IHXGetFileFromSamePool* pFilePool;
		
		// Handle was made but needs set-up
		HX_ASSERT(m_pHandleTable->m_pFileObject);
		
		status = m_pHandleTable->m_pFileObject->QueryInterface(
			    IID_IHXGetFileFromSamePool,
			    (void**) &pFilePool);
		
		if (SUCCEEDED(status))
		{
		    // Set-up is made by duplicating the root file object
		    status = pFilePool->GetFileObjectFromPool(
				(IHXGetFileFromSamePoolResponse*) this);
		    pFilePool->Release();
		}
	    }
	    
	    if (FAILED(status))
	    {
		retVal = HandleFailureAsync(status);
	    }
	}
	else if ((m_State == FSWCHR_ProcClose) ||
	         (m_bClosing))
	{
	    retVal = HXR_OK;

	    if (!m_bClosing || (m_uCurrentChildCount == 0))
	    {
		// Close completion
		IHXFileResponse *pResponse = m_pResponse;
				
		m_pResponse = NULL;

		if (m_bClosing)
		{
		    Reset();

		    m_State = FSWCHR_Offline;

		    if (FAILED(m_CloseStatus))
		    {
			status = m_CloseStatus;
		    }
		}
		else
		{
		    m_State = FSWCHR_Ready;
		}
		
		if (pResponse)
		{
		    retVal = pResponse->CloseDone(status);
		    pResponse->Release();
		}
	    }
	    else
	    {
		// Still Closing files
		m_uCurrentChildCount--;

		if (SUCCEEDED(m_CloseStatus))
		{
		    m_CloseStatus = status;
		}
	    }
	}
    }

    return retVal;
}

/****************************************************************************
 *  ReadDone
 */
STDMETHODIMP CFileSwitcher::ReadDone(HX_RESULT status,
				     IHXBuffer* pBuffer)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_State == FSWCHR_ProcRead)
    {
	HX_ASSERT(m_pResponse);
		
	if (m_ulChunkSize == m_ulSize)
	{
	    IHXFileResponse *pResponse = m_pResponse;
	    m_pResponse = NULL;
	    m_State = FSWCHR_Ready;
	    retVal = pResponse->ReadDone(status, pBuffer);
	    pResponse->Release();
	}
	else
	{
	    // The read of a fragment is completed
	    // Initialize fragment buffer if just starting
	    if (SUCCEEDED(status))
	    {
		if (m_ulProcessedSize == 0)
		{
		    // Starting the fragmented read - 
		    HX_ASSERT(m_pBuffer == NULL);
		    HX_ASSERT(m_ulSize != 0);
		    
		    m_ulFragmentCount = 0;

		    HX_RELEASE(m_pBuffer);
		    
		    status = m_pClassFactory->CreateInstance(
			IID_IHXBuffer, 
			(void **) &m_pBuffer);
		    
		    if (SUCCEEDED(status))
		    {
			status = m_pBuffer->SetSize(m_ulSize);

			if (FAILED(status))
			{
			    HX_RELEASE(m_pBuffer);
			}
		    }
		}
	    }

	    if (SUCCEEDED(status))
	    {
		ULONG32 ulSize = pBuffer->GetSize();

		memcpy(m_pBuffer->GetBuffer() + m_ulProcessedSize, /* Flawfinder: ignore */
		       pBuffer->GetBuffer(),
		       ulSize);
		m_ulProcessedSize += ulSize;
	    }

	    if ((m_ulProcessedSize >= m_ulSize) || FAILED(status))
	    {
		HX_ASSERT(m_ulProcessedSize <= m_ulSize);

		if (FAILED(status) && m_pBuffer)
		{
		    if (m_ulProcessedSize != 0)
		    {
			// Trim the buffer to what was read successfully
			m_pBuffer->SetSize(m_ulProcessedSize);
			status = HXR_OK;
		    }
		    else
		    {
			HX_RELEASE(m_pBuffer);
		    }
		}

		IHXBuffer* pBuffer = m_pBuffer;
		IHXFileResponse *pResponse = m_pResponse;
		m_pResponse = NULL;
		m_pBuffer = NULL;
		m_State = FSWCHR_Ready;
		retVal = pResponse->ReadDone(status, pBuffer);
		HX_RELEASE(pBuffer);
		pResponse->Release();
	    }
	    else
	    {
		m_ulFragmentCount++;
		retVal = ReadNextFragment();
	    }
	}
    }

    return retVal;
}

/****************************************************************************
 *  WriteDone
 */
STDMETHODIMP CFileSwitcher::WriteDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_State == FSWCHR_ProcWrite)
    {
	IHXFileResponse *pResponse = m_pResponse;
	
	HX_ASSERT(m_pResponse);
	
	m_pResponse = NULL;
	m_State = FSWCHR_Ready;
	
	retVal = pResponse->WriteDone(status);
	
	pResponse->Release();
    }

    return retVal;
}

/****************************************************************************
 *  SeekDone
 */
STDMETHODIMP CFileSwitcher::SeekDone(HX_RESULT status)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_State == FSWCHR_ProcSeek)
    {
	IHXFileResponse *pResponse = m_pResponse;
	
	HX_ASSERT(m_pResponse);
	
	m_pResponse = NULL;
	m_State = FSWCHR_Ready;
	
	retVal = pResponse->SeekDone(status);
	
	pResponse->Release();
    }

    return retVal;
}

/****************************************************************************
 *  IHXCallback methods
 */
/****************************************************************************
 *  Func
 */
STDMETHODIMP CFileSwitcher::Func(void)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_State == FSWCHR_ProcRead)
    {
	retVal = ReadNextFragment();
    }

    return retVal;
}

/****************************************************************************
 *  IHXThreadSafeMethods method
 */
/****************************************************************************
 *  IsThreadSafe
 */
STDMETHODIMP_(UINT32)
CFileSwitcher::IsThreadSafe()
{
    return HX_THREADSAFE_METHOD_FSR_READDONE;
}


/****************************************************************************
 *  IHXGetFileFromSamePoolResponse method
 */
/****************************************************************************
 *  FileObjectReady
 */
STDMETHODIMP CFileSwitcher::FileObjectReady(HX_RESULT status,
					    IUnknown* pFileObject)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (m_State != FSWCHR_Offline)
    {
	HX_ASSERT(m_pCurrentHandle);
	HX_ASSERT(m_pCurrentHandle->m_pFileName);
	HX_ASSERT(!m_pCurrentHandle->m_pFileObject);
	
	if (SUCCEEDED(status))
	{
	    IHXRequestHandler* pRequestHandler = NULL;
	    IHXRequest* pRequest = NULL;

	    if (!m_bClosing)
	    {
		status = pFileObject->QueryInterface(
			    IID_IHXFileObject, 
			    (void **) &(m_pCurrentHandle->m_pFileObject));
	    }
	    else
	    {
		status = HXR_ABORT;
	    }

	    if (status == HXR_OK)
	    {
		status = m_pClassFactory->CreateInstance(
			    IID_IHXRequest, 
			    (void **) &pRequest);
	    }
	    
	    if (status == HXR_OK)
	    {
		status = pRequest->SetURL(m_pCurrentHandle->m_pFileName);
	    }

	    if (status == HXR_OK)
	    {
		status = pFileObject->QueryInterface(
			    IID_IHXRequestHandler, 
			    (void**) &pRequestHandler);
	    }
	    
	    if (status == HXR_OK)
	    {
		status = pRequestHandler->SetRequest(pRequest);
	    }
		
	    HX_RELEASE(pRequest);
	    HX_RELEASE(pRequestHandler);
	    
	    if (status == HXR_OK)
	    {
		status = m_pCurrentHandle->m_pFileObject->Init
			    (m_ulFlags, 
			    (IHXFileResponse*) this);
	    }
	}
	
	if (status != HXR_OK)
	{
	    retVal = HandleFailureAsync(status);
	}
    }

    return retVal;
}


/****************************************************************************
 *  IUnknown methods
 */
/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::QueryInterface
//
STDMETHODIMP CFileSwitcher::QueryInterface(REFIID riid, void** ppvObj)
{
    if (IsEqualIID(riid, IID_IHXFileSwitcher))
    {
	AddRef();
	*ppvObj = (IHXFileSwitcher*) this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXCallback))
    {
        AddRef();
        *ppvObj = (IHXCallback*)this;
        return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXGetFileFromSamePoolResponse))
    {
	AddRef();
	*ppvObj = (IHXGetFileFromSamePoolResponse*) this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXFileResponse))
    {
	AddRef();
	*ppvObj = (IHXFileResponse*) this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IUnknown))
    {
	AddRef();
	*ppvObj = this;
	return HXR_OK;
    }
    else if (IsEqualIID(riid, IID_IHXThreadSafeMethods))
    {
	AddRef();
	*ppvObj = (IHXThreadSafeMethods*) this;
	return HXR_OK;
    }

    *ppvObj = NULL;

    return HXR_NOINTERFACE;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::AddRef
//
STDMETHODIMP_(ULONG32) CFileSwitcher::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IUnknown::Release
//
STDMETHODIMP_(ULONG32) CFileSwitcher::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
        return m_lRefCount;
    }

    delete this;
    return 0;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?