⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxfsmgr.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    m_pRequest = pRequest;
    if (m_pRequest)
    {
	m_pRequest->AddRef();
    }

    m_State = e_GetFileObjectPending;

#ifdef _MACINTOSH
    if (!IsMacInCooperativeThread())
    {
	if (!m_pScheduler)
	{
	    HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK);
	}
	
	if (!m_pCallback)
	{
	    m_pCallback = new RMAFSManagerCallback(this);
	    m_pCallback->AddRef();
	}

	HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE);

	if (!m_pCallback->m_bIsCallbackPending)
	{
	    m_pCallback->m_bIsCallbackPending = TRUE;
	    m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0);
	}
			
        return HXR_OK;
    }
#endif

    return (ProcessGetFileObjectPending());
}

HX_RESULT
HXFileSystemManager::ProcessGetFileObjectPending()
{
    HX_LOG_BLOCK( "HXFileSystemManager::ProcessGetFileObjectPending" );

    HX_RESULT theErr = HXR_OK;

    IUnknown*		    pUnknownFS		= NULL;
    IUnknown*		    pUnknownFileObject	= NULL;
    IHXFileSystemObject*   pFileSystem		= NULL;
    IHXRequestHandler*	    pRequestHandler	= NULL;
    IHXPlugin2Handler*	    pPlugin2Handler	= NULL; 

    if (!m_pContext)
    {
	return HXR_FAILED;
    }

    /* 
     * We might get released (and deleted) in the response object. so 
     * Addref here and Release after the response function is called
     */
    AddRef();
    
    // get the plugin handler 
    if (HXR_OK != m_pContext->QueryInterface(IID_IHXPlugin2Handler, (void**)&pPlugin2Handler))
    {
        theErr = HXR_FAILED;
	goto exit;
    }

    const char* pURL;

    HX_ASSERT( NULL != m_pRequest );
    if ( ( NULL == m_pRequest ) || ( m_pRequest->GetURL(pURL) != HXR_OK ) )
    {
        theErr = HXR_FAILED;
	goto exit;
    }

    const char* pProtocolEnd;
    pProtocolEnd = HXFindChar(pURL,':');

    if (!pProtocolEnd)
    {
        theErr = HXR_FAILED;
    }

    if (!theErr)
    {
	int nLength = pProtocolEnd - pURL;
	CHXString strProtocol(pURL,nLength);

	if (HXR_OK != (theErr = pPlugin2Handler->FindPluginUsingStrings(PLUGIN_CLASS, PLUGIN_FILESYSTEM_TYPE, 
	    PLUGIN_FILESYSTEMPROTOCOL, (char*)(const char*)strProtocol, NULL, NULL, pUnknownFS)))
	{
	    goto exit;
	}

	IHXPlugin* pPluginInterface = NULL;

	if(!theErr)
	{
	    theErr = pUnknownFS->QueryInterface(IID_IHXPlugin,
						(void**)&pPluginInterface);
	}

	if(!theErr)
	{
	    theErr = pPluginInterface->InitPlugin(m_pContext);
	    pPluginInterface->Release();
	}
	
	if(!theErr)
	{
	    theErr = pUnknownFS->QueryInterface(IID_IHXFileSystemObject,
						(void**)&pFileSystem);
	}
	
	// At this point we should initalize the file system.to do this we must find the 
	// IHXValues for this mount path in the Options Cache.

	IHXValues* pOptions = NULL;

	pOptions = GetOptionsGivenURL(pURL);

	pFileSystem->InitFileSystem(pOptions);

	HX_RELEASE(pOptions);

	if(!theErr)
	{
	    theErr = pFileSystem->CreateFile(&pUnknownFileObject);
	}
	
	if(!theErr)
	{
	    if(HXR_OK == pUnknownFileObject->QueryInterface(
		IID_IHXRequestHandler,
		(void**)&pRequestHandler))
	    {
		pRequestHandler->SetRequest(m_pRequest);
	    }
	    else
	    {
		theErr = HXR_FAILED;
	    }
	}
    }
    else
    {
	theErr = HXR_FAILED;
    }

    if (!theErr && pUnknownFileObject)
    {
	m_pFSManagerResponse->FileObjectReady(HXR_OK, pUnknownFileObject);
    }
    else
    {
	m_pFSManagerResponse->FileObjectReady(HXR_FAILED, NULL);
    }

exit:
    HX_RELEASE(pUnknownFS);
    HX_RELEASE(pUnknownFileObject);
    HX_RELEASE(pRequestHandler);
    HX_RELEASE(pFileSystem);
    HX_RELEASE(pPlugin2Handler);

#ifndef _MACINTOSH
    // Note: This change is necessary for the Macintosh build due to the fact
    // that this platform uses a different approach in GetFileObject.  The problem
    // is that file object processing had generally been done recursively, with
    // GetFileObject calling ProcessGetFileObjectPending, which in turn indirectly
    // invoked GetFileObject in a pattern of mutual recursion.  The recursion had
    // always ended with a call to ProcessGetFileObjectPending.  With the change
    // in GetFileObject:
    //     #ifdef _MACINTOSH
    //      if (!IsMacInCooperativeThread())
    // the recursion would terminate in a GetFileObject call.  This call would
    // unwind to the scheduler, which would then process the queued file object
    // by calling ProcessGetFileObjectPending.  However, since the request object
    // was freed during the unwinding of the recursion, this object was no longer
    // available and hence the process failed.
    //
    // The best short term fix appears to be to remove this release.  The best long
    // term fix is to eliminate the recursion (which would also simplify maintenance). 
    //     -cconover 	XXX
    
    HX_RELEASE(m_pRequest);
#endif

    /* 
     * Release for extra Addref
     */
    Release();

    return theErr;
}

/*
 * In this implementation of FSManager, GetNewFileObject is wholly
 * equivalent to GetFileObject.  GetNewFileObject exists for the
 * server's FSManager since it would otherwise be impossible to get
 * a brand new file object for writing, as the DoesExist checks
 * would fail for every file system checked.  This implementation has
 * ambiguities between URL's and file systems, so there is no
 * different functionality needed.
 */
STDMETHODIMP
HXFileSystemManager::GetNewFileObject(IHXRequest* pRequest,
				       IHXAuthenticator* pAuthenticator)
{
    return GetFileObject(pRequest, pAuthenticator);
}

STDMETHODIMP
HXFileSystemManager::GetRelativeFileObject(IUnknown* pOriginalObject,
				 const char* pRelativePath)
{
    HX_RESULT		    theErr = HXR_OK;

    if(!pRelativePath)
    {
	return HXR_FAIL;
    }

    HX_RELEASE(m_pOriginalObject);

    m_pOriginalObject = pOriginalObject;
    if (m_pOriginalObject)
    {
	m_pOriginalObject->AddRef();
    }

    HX_VECTOR_DELETE(m_pRelativePath);
    m_pRelativePath = new_string(pRelativePath);

    m_State = e_GetRelativeFileObjectPending;

#ifdef _MACINTOSH
    if (!IsMacInCooperativeThread())
    {
	if (!m_pScheduler)
	{
	    HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK);
	}
	
	if (!m_pCallback)
	{
	    m_pCallback = new RMAFSManagerCallback(this);
	    m_pCallback->AddRef();
	}

	HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE);

	if (!m_pCallback->m_bIsCallbackPending)
	{
	    m_pCallback->m_bIsCallbackPending = TRUE;
	    m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0);
	}
			
        return HXR_OK;
    }
#endif

    return (ProcessGetRelativeFileObjectPending());

}

HX_RESULT
HXFileSystemManager::ProcessGetRelativeFileObjectPending()
{
    HX_RESULT theErr = HXR_OK;
    IHXRequestHandler* pRequestHandlerOrigional = NULL;
    IHXRequest* pRequestOld = NULL;

    AddRef();
    
    if (!m_pOriginalObject)
    	goto exit;

    if(HXR_OK != m_pOriginalObject->QueryInterface(IID_IHXGetFileFromSamePool,
					       (void**)&m_pSamePool))
    {
	theErr = HXR_FAIL;
	goto exit;
    }

    if 
    (
	HXR_OK != m_pOriginalObject->QueryInterface
	(
	    IID_IHXRequestHandler,
	    (void**)&pRequestHandlerOrigional
	)
	||
	!pRequestHandlerOrigional
	||
	HXR_OK != pRequestHandlerOrigional->GetRequest(pRequestOld)
	||
	!pRequestOld
    )
    {
	HX_RELEASE(pRequestHandlerOrigional);
	HX_RELEASE(pRequestOld);

	theErr = HXR_FAIL;
	goto exit;
    }

    HX_RELEASE(pRequestHandlerOrigional);

    /*
     * Create an IHXRequest object for the new file
     */

    HX_RELEASE(m_pRequest);

    CHXRequest::CreateFrom(pRequestOld, &m_pRequest);
    HX_RELEASE(pRequestOld);

    m_pRequest->SetURL(m_pRelativePath);

    if(HXR_OK != m_pSamePool->GetFileObjectFromPool(this))
    {
	theErr = HXR_FAIL;
	goto exit;
    }

exit:
    HX_RELEASE(m_pSamePool);
    HX_RELEASE(m_pOriginalObject);
    HX_VECTOR_DELETE(m_pRelativePath);

    Release();

    return theErr;
}

STDMETHODIMP
HXFileSystemManager::FileObjectReady(HX_RESULT status, IUnknown* pUnknown)
{
    IHXRequestHandler* pRequestHandler = NULL;

    if(HXR_OK == status)
    {
	if(HXR_OK == pUnknown->QueryInterface(IID_IHXRequestHandler,
					    (void**)&pRequestHandler))
	{
	    pRequestHandler->SetRequest(m_pRequest);
	}
	else
	{
	    pUnknown = 0;
	    status = HXR_FAILED;
	}

	pRequestHandler->Release();
    }

    HX_RELEASE(m_pRequest);

    /* 
     * We might get released (and deleted) in the response object. so 
     * Addref here and Release after the response function is called
     */
    AddRef();
    
    if (m_pFSManagerResponse)
    {
	m_pFSManagerResponse->FileObjectReady(status, pUnknown);
    }

    /* 
     * Release for extra Addref
     */
    Release();

    return HXR_OK;
}



STDMETHODIMP 
HXFileSystemManager::GetDirObjectFromURL(const char* pURL)
{
    return HXR_NOTIMPL;
}

void
HXFileSystemManager::ProcessPendingRequest()
{

    switch(m_State)
    {
	case e_GetFileObjectPending:
	    ProcessGetFileObjectPending();
	    break;
	case e_GetRelativeFileObjectPending:
	    ProcessGetRelativeFileObjectPending();
	    break;
	default:
	    HX_ASSERT(FALSE);
	    break;
    }    
}

// HXFileSystemManager::RMAFSManagerCallback

HXFileSystemManager::RMAFSManagerCallback::RMAFSManagerCallback(HXFileSystemManager*	pFSManager) :
     m_lRefCount (0)
    ,m_pFSManager (pFSManager)
    ,m_Handle (0)
    ,m_bIsCallbackPending(FALSE)
{
}

HXFileSystemManager::RMAFSManagerCallback::~RMAFSManagerCallback()
{
}

/*
 * IUnknown methods
 */

/////////////////////////////////////////////////////////////////////////
//	Method:
//		IUnknown::QueryInterface
//	Purpose:
//		Implement this to export the interfaces supported by your 
//		object.
//
STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::QueryInterface(REFIID riid, void** ppvObj)
{
    QInterfaceList qiList[] =
        {
            { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this },
            { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXCallback*)this },
        };
    
    return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}

/////////////////////////////////////////////////////////////////////////
//	Method:
//		IUnknown::AddRef
//	Purpose:
//		Everyone usually implements this the same... feel free to use
//		this implementation.
//
STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::AddRef()
{
    return InterlockedIncrement(&m_lRefCount);
}

/////////////////////////////////////////////////////////////////////////
//	Method:
//		IUnknown::Release
//	Purpose:
//		Everyone usually implements this the same... feel free to use
//		this implementation.
//
STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::Release()
{
    if (InterlockedDecrement(&m_lRefCount) > 0)
    {
	return m_lRefCount;
    }

    delete this;
    return 0;
}


/*
 *	UDPSchedulerCallback methods
 */
STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::Func(void)
{
    m_Handle = 0;
    m_bIsCallbackPending = FALSE;
    if (m_pFSManager)
    {
	m_pFSManager->ProcessPendingRequest();
    }

    return HXR_OK;
}

⌨️ 快捷键说明

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