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

📄 memfsys.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	 */	if (m_ulFlags == ulFlags || ulFlags == 0)	{	    m_ulPos = 0;	    m_pFileResponse->InitDone(HXR_OK);	    return HXR_OK;	}	_CloseFile();    }        UpdateFileNameMember();    m_bAsynchInit = FALSE;    m_ulFlags = ulFlags;    BOOL bExists = FALSE;    IHXMemoryFileSystem* pMemFS = GetMemoryFileSystem();    IHXMemoryFileSystem2* pMemFS2 = NULL;    if (pMemFS)    {	bExists = pMemFS->Exists(m_pFilename);	if (!bExists)	{	    // XXXNH: we have to flag this *before* we request the file, or	    // else initialization will fail with a synchronous file system	    m_bAsynchInit = TRUE;	    bChoseAsynchInit = TRUE;	    pMemFS2 = GetMemoryFileSystem2();	    if (pMemFS2)	    {		// try to request the file		lReturnVal = pMemFS2->RequestURL(m_pFilename, this);	    }	    else	    {		//XXXNH: No IHXMemoryFileSystem2? this should never happen!		HX_ASSERT(FALSE);		lReturnVal = HXR_FAIL;	    }	    // request failed, so respond with a failure	    if (lReturnVal != HXR_OK)	    {		m_pFileResponse->InitDone(HXR_DOC_MISSING);		lReturnVal = HXR_DOC_MISSING;		// XXXNH: we're already initialized: we are missing!		m_bAsynchInit = FALSE;		bChoseAsynchInit = FALSE;		goto exit;	    }    	}    }    else    {	// XXXNH: No IHXMemoryFileSystem? this should never happen!  	HX_ASSERT(FALSE);	m_pFileResponse->InitDone(HXR_FAIL);	return HXR_FAIL;    }    // XXXNH: it is entirely possible that if we're initializing    // asynchronously that we may have been closed as a result of making the    // URL request!    if (!m_bClosed && !bChoseAsynchInit)    {	if (!m_pCommonClassFactory)	{	    HX_ASSERT(m_pContext);	    m_pContext->QueryInterface(IID_IHXCommonClassFactory,				       (void **)&m_pCommonClassFactory);	}	if (m_pRequest &&	    SUCCEEDED(m_pRequest->QueryInterface(				    IID_IHXRequestContext,				    (void**)&pIHXRequestContextCurrent)))	{	    pIHXRequestContextCurrent->GetUserContext(pIUnknownUserContext);	    HX_RELEASE(pIHXRequestContextCurrent);	}	if (!bChoseAsynchInit)	{	    lReturnVal = _OpenFile(ulFlags);	    HX_RESULT status = m_pChunkyRes ? HXR_OK : HXR_DOC_MISSING;	    resultInitDone = m_pFileResponse->InitDone(status);			}    }exit:    HX_RELEASE(pIUnknownUserContext);    HX_RELEASE(pMemFS);    HX_RELEASE(pMemFS2);    return (HXR_OK==lReturnVal? resultInitDone:lReturnVal);}/************************************************************************ *  Method: *      IHXFileObject::GetFilename *  Purpose: *      Returns the filename (without any path information) associated *      with a file object. */STDMETHODIMP CMemoryFileObject::GetFilename(    REF(const char*) /*OUT*/ pFilename){    UpdateFileNameMember();    // Find the separator character before the file name    pFilename = ::strrchr(m_pFilename, '/');    if (pFilename != NULL) // Found    {	// File name starts after the separator charactor	pFilename++;    }    else // Not found    {	pFilename = m_pFilename;    }    return HXR_OK;}/************************************************************************ *  Method: *	IHXFileObject::Close *  Purpose: *	Closes the file resource and releases all resources associated *	with the object. */STDMETHODIMP CMemoryFileObject::Close(){    m_bClosed = TRUE;    if (m_bAsynchInit)    {	m_bAsynchInit = FALSE;	IHXMemoryFileSystem2* pFS = GetMemoryFileSystem2();	if (pFS)	{	    pFS->CancelRequest(m_pFilename, HXR_FAIL);	}    }    // If there is a pending callback, be sure to remove it!    if (m_pCallback && m_pCallback->m_ulPendingCallbackID && m_pScheduler)     {	m_pScheduler->Remove(m_pCallback->m_ulPendingCallbackID);    }    HX_RELEASE(m_pCallback);    HX_RELEASE(m_pScheduler);    if (m_pContext)     {	m_pContext->Release();	m_pContext = NULL;    }    if (m_pCommonClassFactory)     {	m_pCommonClassFactory->Release();	m_pCommonClassFactory = NULL;    }    if (m_pFileSystem)    {	m_pFileSystem->Release();	m_pFileSystem = NULL;    }    if (m_pRequest)    {	m_pRequest->Release();	m_pRequest = NULL;    }    if (m_pChunkyRes)     {	_CloseFile();    }    if(m_pFilename)    {	delete[] m_pFilename;	m_pFilename = NULL;    }        // It is vitally important that the CloseDone be the last step in    // this method, as the last reference to this object may be    // released inside CloseDone!  Do not place code after this if block!    //    // XXXGH...can't release the m_pFileResponse because it's needed here,    //         so I've moved the m_pFileResponse->Release() to after the    //         CloseDone() call and added an AddRef()/Release() pair    if (!m_bLocalClose)    {	AddRef();	if(m_pFileResponse)	{	    m_pFileResponse->CloseDone(HXR_OK);	    m_pFileResponse->Release();	    m_pFileResponse = NULL;        }	Release();    }    else if (m_pFileResponse)     {	m_pFileResponse->Release();	m_pFileResponse = NULL;    }    return HXR_OK;}/************************************************************************ *  Method: *	IHXFileObject::Read *  Purpose: *	Reads a buffer of data of the specified length from the file *	and asynchronously returns it to the caller via the  *	IHXFileResponse interface passed in to Init. */STDMETHODIMP CMemoryFileObject::Read(ULONG32 ulCount){    HX_ASSERT(m_pFileResponse);    // XXXBHG, For now, you cant read more than 1MB at a time!    if (ulCount > 0x000FFFFF)    {        HX_ASSERT(!"CMemoryFileObject::Read() - ulCount > 0xFFFFF");	//Force the system to recognize a failed Read so infinite	// buffering does not occur with the core waiting for EOF:	m_pFileResponse->ReadDone(HXR_FAIL, NULL);	return HXR_INVALID_PARAMETER;    }    if (m_bSeekPending)    {	m_pFileResponse->ReadDone(HXR_SEEK_PENDING, NULL);	return HXR_UNEXPECTED;    }    if(!m_pChunkyRes && m_bCanBeReOpened)    {	_OpenFile(m_ulFlags);	m_bCanBeReOpened = FALSE;    }    if (m_pChunkyRes)    {	if(!(m_ulFlags & HX_FILE_READ))	    return HXR_UNEXPECTED;	// Do we have enough data?	ULONG32 ulCurLen = m_pStatus->GetSize();	if (ulCount + m_ulPos > ulCurLen)	{	    // If we're done filling the memory file, read the remainder	    if (m_pStatus->GetDone())	    {		/* Read the last few bytes */		if (m_ulPos < ulCurLen)		{		    ulCount = ulCurLen - m_ulPos;		}		else		{		    m_bInReadDone = TRUE;		    // Let the file response sink know about the buffer...		    HX_RESULT result = HXR_FAIL;		    m_pFileResponse->ReadDone(result, NULL);			    		    m_bInReadDone = FALSE;		    return result;		}	    }	    else	    {		// Request that the context read some more data for us.		IHXMemoryFileContext* pCtxt = m_pStatus->GetContext();		if (pCtxt)		{		    pCtxt->RequestRead(m_pStatus->GetID(), ulCount);		    pCtxt->Release();		}		// Schedule a callback		if (m_pScheduler)		{		    if (!m_pCallback->m_bCallbackPending)		    {			m_pCallback->m_bCallbackPending	= TRUE;			m_pCallback->m_ulPendingCallbackID  = 				    m_pScheduler->RelativeEnter(m_pCallback, 0);		    }		    //set the count so that the callback will know how much to read.		    HX_ASSERT(!m_ulPendingReadCount); // XXXSEH: I suspect ulCount should be added to m_ulPendingReadCount.		    m_ulPendingReadCount = ulCount;		    return HXR_OK;		}		// No scheduler!		return HXR_FAIL;	    }	}	if (m_bInReadDone)	{	    m_uRecursionCount++;	}	if (m_uRecursionCount > CMemoryFileSystem::z_uMaxRecursionLevel)	{	    //if there already is a callback registered	    if(m_pCallback->m_bCallbackPending)	    {		//see if seek canceled him.  If he did,		//the file sys called Seek while a Read was		//pending, so all is good with the callback.		if(m_bReadCancelled)		{		    //seek canceled him, so we will make him valid		    //and use him.		    m_pCallback->m_bIgnoreCallback = FALSE;		    m_bReadCancelled = FALSE;			//" so IgnoreCallback = FALSE\n");		}		else		{		    //the fileformat has called us twice and is bad.		    return HXR_UNEXPECTED;		}	    }	    else	    { 		if (m_pScheduler)		{		    if (!m_pCallback->m_bCallbackPending)		    {			//there was no callback on the schedule, so make a new one.			m_pCallback->m_bIgnoreCallback = FALSE;			m_bReadCancelled = FALSE;			m_pCallback->m_bCallbackPending	= TRUE;			m_pCallback->m_ulPendingCallbackID  = 					m_pScheduler->RelativeEnter(m_pCallback, 0);		    }		}		else		{		    // no scheduler!		    return HXR_FAIL;		}	    }	    //set the count so that the callback will know how much to read.            HX_ASSERT(!m_ulPendingReadCount); // XXXSEH: I suspect ulCount should be added to m_ulPendingReadCount.	    m_ulPendingReadCount = ulCount;	    return HXR_OK;	}	// Create buffer object here, notice that we call the	// CreateInstance method of the controller, but we could	// have implemented our own object that exposed the IHXBuffer	// interface.	IHXBuffer* pBuffer;	HX_RESULT result;	if (!m_pCommonClassFactory)	{	    result = m_pContext->QueryInterface(IID_IHXCommonClassFactory,	                                        (void **)&m_pCommonClassFactory);	    if (HXR_OK != result)	    {		return result;	    }	}	result = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,	                                               (void**)&pBuffer);	if (HXR_OK != result)	{	    return result;	}	// Ask the buffer to create a space to read into...	result = pBuffer->SetSize(ulCount);	if (HXR_OK != result)	{	    return result;	}	HX_ASSERT(m_pChunkyRes);	ULONG32 actual = 0;	m_pChunkyRes->GetData(m_ulPos, (char*)pBuffer->GetBuffer(), ulCount, &actual);	HX_ASSERT((actual > 0) && (actual <= ulCount));	// Tell the buffer about it's real meaningful size	pBuffer->SetSize(actual);	m_ulPos += actual;	m_bInReadDone = TRUE;	// Let the file response sink know about the buffer...	result = m_pFileResponse->ReadDone(actual > 0 ? HXR_OK : HXR_FAILED,	                                   pBuffer);			m_bInReadDone = FALSE;	if (m_uRecursionCount > 0)	{	    m_uRecursionCount--;	}	// Release our reference on the buffer!	pBuffer->Release();	return result;    }    return HXR_UNEXPECTED;}/************************************************************************ *  Method: *	IHXFileObject::Write *  Purpose: *	Not allowed to write to a memory file with this interface */STDMETHODIMP CMemoryFileObject::Write(IHXBuffer* pBuffer){    return HXR_UNEXPECTED;}/************************************************************************ *  Method: *	IHXFileObject::Seek *  Purpose: *	Seeks to an offset in the file and asynchronously notifies *	the caller via the IHXFileResponse interface passed in to Init, *	of the completeness of the operation. */STDMETHODIMP CMemoryFileObject::Seek(ULONG32 ulOffset, BOOL bRelative){    if (m_bSeekPending)    {	m_bSeekPending = FALSE;	m_pFileResponse->SeekDone(HXR_CANCELLED);    }    if(!m_pChunkyRes && m_bCanBeReOpened)    {	_OpenFile(m_ulFlags);    }    if (m_pChunkyRes)    {	/*	 *  Seek cancels pending Reads.	 */	if(m_pCallback && m_pCallback->m_bCallbackPending && !m_bReadCancelled)	{	    m_pCallback->m_bIgnoreCallback = TRUE;	    m_bReadCancelled = TRUE;	    m_pFileResponse->ReadDone(HXR_CANCELLED, NULL);	}	if(bRelative)	{	    m_ulPos += ulOffset;	}	else	{	    m_ulPos = ulOffset;	}	if (m_ulPos < m_pStatus->GetSize())	{	    return m_pFileResponse->SeekDone(HXR_OK);	}	else	{	    // XXXNH: until we have pending seek support, respond with an error	    return m_pFileResponse->SeekDone(HXR_WOULD_BLOCK);	}    }    return HXR_UNEXPECTED;}/************************************************************************ * Method: *	IHXFileObject::Stat * Purpose: *	Collects information about the file that is returned to the *	caller in an IHXStat object */STDMETHODIMP CMemoryFileObject::Stat(IHXFileStatResponse* pFileStatResponse){    HX_ASSERT(m_pStatus);    HX_ASSERT(pFileStatResponse);    if (m_pStatus)    {	pFileStatResponse->StatDone(HXR_OK,				    m_pStatus->GetContentSize(),				    0,				    0,				    0,				    0);    }    else    {	pFileStatResponse->StatDone(HXR_UNEXPECTED, 0, 0, 0, 0, 0);    }    return HXR_OK;}/************************************************************************ *  Method: *	IHXFileObject::Advise *  Purpose: *	To pass information to the File Object */STDMETHODIMP CMemoryFileObject::Advise(ULONG32 ulInfo){    HX_RESULT pnr = HXR_OK;    // If we're done, then we're cached and can allow random access, but    // otherwise we need to behave like a linear file system    if ( ( !m_pStatus || !m_pStatus->GetDone() ) && ( ulInfo == HX_FILEADVISE_RANDOMACCESS ) )    {        pnr = HXR_ADVISE_PREFER_LINEAR;    }    return pnr;}/************************************************************************ *	Method: *	    IHXFileObject::GetFileObjectFromPool *	Purpose: *      To get another FileObject from the same pool.  */STDMETHODIMP CMemoryFileObject::GetFileObjectFromPool (    IHXGetFileFromSamePoolResponse* response){    HX_RESULT lReturnVal = HXR_FAILED;    CMemoryFileObject* pFileObject = 0;    CHXString new_path;    CHXString strFileName;    CHXString strURL;    IUnknown* pUnknown = 0;    char* pNewPath    = 0;    char* pSeparator  = 0;    UpdateFileNameMember();    if(!m_pFilename)    {	pNewPath = new char[strlen(m_base_path) + 1];	strcpy(pNewPath, m_base_path); /* Flawfinder: ignore */    }    else    {	strURL = m_pFilename;		// Make a nice local file name from the URL!	strFileName = strURL;	pNewPath = new char[strlen(strFileName) + 1];	strcpy(pNewPath, (const char*)strFileName); /* Flawfinder: ignore */	pSeparator = ::strrchr(pNewPath, '/');	if(pSeparator)	{	    /* Separator will be added in seturl */	    *pSeparator = 0;	}	else	{	    // started w/filename. no separator implies no path	    pNewPath[0] = NULL;	}    }    new_path = pNewPath;    if (pNewPath)    {

⌨️ 快捷键说明

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