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

📄 macasyncfile.cpp

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

    if(result == HXR_OK)
    {
	    ReadAsyncData(bAtInterrupt);
    }

    //
    //   Set it to null.
    //
    mFilePos = 0;
    
    m_pMutex->Unlock();
    return result;
}
 
HX_RESULT CMacAsyncFile::Close(void)
{
    m_pMutex->Lock();
    HX_RESULT result = CMacFile::Close();

    EmptyAsyncQueue();

    mReadQueue->FlushQueue();

    m_pMutex->Unlock();
    return result;

}

HX_RESULT CMacAsyncFile::Seek(ULONG32 offset, UINT16 fromWhere)
{
    return HXR_NOTIMPL;
}

void
CMacAsyncFile::PerformInternalSeek(BOOL ASYNC)
{
    m_pMutex->Lock();
    mSeekFromWhere = fsFromStart;
    mSeekPos = m_ulReadPositionInFile;
    UpdateFilePos(ASYNC, TRUE);
    m_pMutex->Unlock();
}

HX_RESULT
CMacAsyncFile::SafeSeek(ULONG32 offset, UINT16 fromWhere, BOOL bAtInterrupt)
{
#if defined(_DEBUG) && defined (_LOG_DATA)
    char str[255]; /* Flawfinder: ignore */
   ::sprintf(str, "SafeSeek: %lu %u %d;g", offset, fromWhere, (int) bAtInterrupt); /* Flawfinder: ignore */
    DEBUGSTR(c2pstr(str));
#endif
	
    if (m_pMutex) m_pMutex->Lock();
    //dfprintf("mem","SafeSeek: %lu, %u, %d\n", offset, fromWhere, (int) bAtInterrupt);
    m_bFileDone 	= FALSE;
    m_bReadPending	= FALSE;
     
    LISTPOSITION pos = NULL;

    /* If we get a read deferred callback while setting the state for buffers in
     * async queue, ignore it
     */
    m_bSettingSeekState = TRUE;

    pos = mAsyncQueue->GetHeadPosition();

    while(pos)
    {
	HXAsyncQueueBuffer *x =(HXAsyncQueueBuffer *) mAsyncQueue->GetAt(pos);
	if(x->state == AB_STATE_FULL)
	{
	    DeleteAsyncQueueBuffer(x, pos);
	    pos = mAsyncQueue->GetHeadPosition();
	    continue;
	    //x->state = AB_STATE_IGNORED;
	}
	/* All other states are pending states and result in AB_STATE_OUTOFCONTEXT */
	else if(x->state != AB_STATE_IGNORED)
	{
	    x->state = AB_STATE_OUTOFCONTEXT;
	}

	mAsyncQueue->GetNext(pos);
    }

    m_bSettingSeekState = FALSE;

    mReadQueue->FlushQueue();

    m_bSeekPending = TRUE;
    if(BufferedWrite())
    {
	CMacFile::Seek(offset, fromWhere);
	PendingAsyncSeekDone();
    }
    else
    {
        UINT32 ulSeekPosition = 0;
        BOOL bSeekNeeded = FALSE;
        
	switch(fromWhere)
	{
	case SEEK_SET:
	    fromWhere = fsFromStart;
	    mSeekFromWhere = fromWhere;
	    mSeekPos = offset;
	    ulSeekPosition = m_ulReadPositionInFile = offset;
	    break;

	case SEEK_CUR:
	    fromWhere = fsFromMark;
	    mSeekFromWhere = fromWhere;
	    mSeekPos = offset;
	    ulSeekPosition = m_ulReadPositionInFile = mFilePos+offset;
	    break;

	case SEEK_END:
	    //HX_ASSERT(!"Need to add support for seek from end -- XXXRA");
	    fromWhere = fsFromLEOF;
	    mSeekFromWhere = fromWhere;
	    mSeekPos = offset;
	    bSeekNeeded = TRUE;
	    break;

	}
	
        if (!bSeekNeeded)
        {
            bSeekNeeded = !(FillBufferFromPQ(ulSeekPosition));	
        }
        
        if (bSeekNeeded)
        {
	    UpdateFilePos(bAtInterrupt);
	}
	else
	{
	    mFilePos 	   = ulSeekPosition;
	    mSeekFromWhere = 0;
            m_bInternalSeekNeeded = TRUE;
	    PendingAsyncSeekDone();
	}
    }
    DEBUGSTR("\p EXIT SafeSeek;g");
    
    if (m_pMutex) m_pMutex->Unlock();
    return HXR_OK;
}


HX_RESULT
CMacAsyncFile::SafeRead(ULONG32 count, BOOL bAtInterrupt)
{
    AddRef();
    m_pMutex->Lock();
    HX_ASSERT(m_bReadPending == FALSE);

    if(!mReadQueue || m_bReadPending)
    {
        DEBUGSTR("\p SafeRead UNEXPECTED;g");
        //dfprintf("mem", "SafeRead UNEXPECTED\n");
        m_pMutex->Unlock();
        Release();
	return HXR_UNEXPECTED;
    }

#if defined(_DEBUG) && defined (_LOG_DATA)
    char str[255]; /* Flawfinder: ignore */
   ::sprintf(str, "SafeRead: %lu %d;g", count, (int) bAtInterrupt); /* Flawfinder: ignore */
    DEBUGSTR(c2pstr(str));
#endif
    
    //dfprintf("mem","SafeRead: %lu, %d\n", count, (int) bAtInterrupt);
    m_bReadPending	 = TRUE;
    m_ulPendingReadCount = count;

    EnqueueAsyncBuffers();

    ReadAsyncData(bAtInterrupt);

    EnqueueAsyncBuffers();
    
    ProcessPendingRead();
    
   DEBUGSTR("\p EXIT SafeRead;g");
   
   m_pMutex->Unlock();
   Release();
   return HXR_OK;
}

ULONG32
CMacAsyncFile::SafeWrite(IHXBuffer* pBuffer, BOOL bAtInterrupt)
{
    m_pMutex->Lock();
    HX_ASSERT(m_bReadPending == FALSE);

    ULONG32 outWrittenSize = 0;
    if(m_bReadPending)
    {
        DEBUGSTR("\p SafeWrite UNEXPECTED;g");
        m_pMutex->Unlock();
	return outWrittenSize;
    }

#if defined(_DEBUG) && defined (_LOG_DATA)
    char str[255]; /* Flawfinder: ignore */
   ::sprintf(str, "SafeWrite: %d;g", (int) bAtInterrupt); /* Flawfinder: ignore */
    DEBUGSTR(c2pstr(str));
#endif
    
    outWrittenSize = WriteAsyncData(pBuffer, bAtInterrupt);

    DEBUGSTR("\p EXIT SafeWrite;g");
    m_pMutex->Unlock();
    return outWrittenSize;
}

ULONG32 CMacAsyncFile::Read(char *buf, ULONG32 count)
{
    return HXR_NOTIMPL;
}

//
//      Static Initializers
//

#ifdef _CARBON
IOCompletionUPP CMacAsyncFile::zmIOCallbackUPP = NewIOCompletionUPP((IOCompletionProcPtr)CMacAsyncFile::zmIOCallback);
#else
IOCompletionUPP CMacAsyncFile::zmIOCallbackUPP = NewIOCompletionProc(CMacAsyncFile::zmIOCallback);
#endif

//
//      Tell
//

ULONG32 CMacAsyncFile::Tell(void)
{
    return mFilePos;
}

//
//       This is the zmIOCompletion callback.
//       When this is done, the data is then pumped into the buffer for this file.
//
pascal void CMacAsyncFile::zmIOCallback(HXParamBlockRec * pb)
{

    HXMM_INTERRUPTON();

    /*
     *	Setup and then install a deferred task 
     */
    if (pb != NULL &&  pb->param != NULL)
    {
    
	CMacAsyncFile* fileobj = (CMacAsyncFile*) pb->param;
	fileobj->m_pMutex->Lock();
	if (fileobj->m_DeferredTaskStruct.dtAddr != NULL)
	{
#if defined(_DEBUG) && defined (_LOG_DATA)
	     char tmpStr1[255]; /* Flawfinder: ignore */
	     ::sprintf(tmpStr1, "ENTER INterrupt Callback %p ;g", fileobj); /* Flawfinder: ignore */
	     DEBUGSTR(c2pstr(tmpStr1));
#endif

	    fileobj->AddToThePendingList((void*) pb);
	    
	    fileobj->m_uNumDeferredTask++;
#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	    /*
	    if (fileobj->m_uNumDeferredTask > 1)
	    {
	        char tmpStr[255];
	        ::sprintf(tmpStr, "More than one pending DeferredTask: %u;g", fileobj->m_uNumDeferredTask);
	        DebugStr(c2pstr(tmpStr));
	    }
	    */
#endif
	    
	    if (!fileobj->m_bDeferredTaskPending)
	    {
	        if ( !fileobj->m_bIsQuitting )
	        {
		    fileobj->m_bDeferredTaskPending = TRUE;
#ifdef _CARBON
		    DeferredTaskProc(fileobj->m_DeferredTaskStruct.dtParam);
#else
		    DTInstall(&fileobj->m_DeferredTaskStruct);
#endif
	        }
	    }
	}
	fileobj->m_pMutex->Unlock();
    }
    
    HXMM_INTERRUPTOFF();
}

pascal void CMacAsyncFile::DeferredTaskProc(long inParam)
{
    HXMM_INTERRUPTON();

    DEBUGSTR("\pENTER CMacAsyncFile::DeferredTaskProc;g");
    CMacAsyncFile*   fileobj = (CMacAsyncFile*) inParam;;
    if(fileobj)
    {
#if defined(_DEBUG) && defined (_LOG_DATA)
        char tmpStr[255]; /* Flawfinder: ignore */
        sprintf(tmpStr, " This pointer: %p;g", fileobj); /* Flawfinder: ignore */
        DEBUGSTR(c2pstr(tmpStr));
#endif
#if defined(_DEBUG) && defined(LOG_MULTIPLE_DEFERRED_TASKS)
	    /*
	    if (fileobj->m_uNumDeferredTask != 1)
	    {
	        char tmpStr[255];
	        ::sprintf(tmpStr, "(In DeferredTaskProc) m_uNumDeferredTask != 1: %u;g", fileobj->m_uNumDeferredTask);
	        DebugStr(c2pstr(tmpStr));
	    }
	    */
	    if ( !fileobj->m_bDeferredTaskPending )
	    {
	    	DebugStr( "\p(In DeferredTaskProc) m_bDeferredTaskPending is false!;g" );
	    }
#endif
	if ( !fileobj->m_bIsQuitting )
	{
	    fileobj->ProcessPendingCallbacks();
	}
        fileobj->m_bDeferredTaskPending = FALSE;
    }
    
    DEBUGSTR("\pLEAVE CMacAsyncFile::DeferredTaskProc;g");
    HXMM_INTERRUPTOFF();
}

void CMacAsyncFile::ProcessPendingCallbacks()
{
    m_pMutex->Lock();

    if (m_bInProcessPendingCallbacks)
    {
        m_pMutex->Unlock();
        return;
    }
 
 start:   
    m_bInProcessPendingCallbacks = TRUE;
    
    while (m_pPendingCallbackList && m_pPendingCallbackList->GetCount() > 0)
    {
        m_uNumDeferredTask--;
        HXParamBlockRec* pb = (HXParamBlockRec*) m_pPendingCallbackList->RemoveHead();
        if (pb && pb->param)
        {
            ProcessBlock(pb);
        }
        HX_DELETE(pb);
    }
    
    EnqueueAsyncBuffers();

    if (m_bPendingAsyncSeekCompleted)
    {
        m_bPendingAsyncSeekCompleted = FALSE;
	PendingAsyncSeekDone();
    }
    
    if (mOutStandingCallbacks == 0 && m_bAllCallbacksCompleted)
    {
        m_bAllCallbacksCompleted = FALSE;
        AllPendingCallbacksDone();
    }    
    
    m_bInProcessPendingCallbacks = FALSE;
    
    /* Do we still have more pending callbacks to process? */
    if (m_pPendingCallbackList && m_pPendingCallbackList->GetCount() > 0)
    {
        goto start;
    }

    m_pMutex->Unlock();
}        

void CMacAsyncFile::ProcessBlock(HXParamBlockRec* pb)
{
	m_pMutex->Lock();
	if (mOutStandingCallbacks > 0)
	{
	    mOutStandingCallbacks--;
	}

	if(pb->entry->state == AB_STATE_OUTOFCONTEXT ||
	   m_bSettingSeekState)
	{
	    //
	    //      Don't need to do anything with this data
	    //      just ignore it. 
	    //              
	    pb->entry->state = AB_STATE_IGNORED;
	}
	else if (pb->entry->state == AB_STATE_ASYNC_INTERNAL_SEEK)
	{
	    m_ulReadPositionInFile = pb->io.ioParam.ioPosOffset;
	    pb->entry->state = AB_STATE_IGNORED;
	}
	else if (pb->entry->state == AB_STATE_ASYNC_SEEK)
	{
	    mFilePos = pb->io.ioParam.ioPosOffset;
	    m_ulReadPositionInFile = mFilePos;
	    pb->entry->state = AB_STATE_IGNORED;
	    m_bPendingAsyncSeekCompleted = TRUE;	    
	}
	else if (pb->entry->state == AB_STATE_WRITE)
	{
	    HX_VECTOR_DELETE(pb->entry->buffer);
	    pb->entry->state = AB_STATE_IGNORED;
	}
	else
	{
	    /* Are we at the end of the file? */
	    if (pb->io.ioParam.ioActCount < pb->entry->size)
	    {
	        m_bFileDone = TRUE;

#if defined(_DEBUG) && defined (_LOG_DATA)
	        char tmpStr[255]; /* Flawfinder: ignore */
	        sprintf(tmpStr, "ProcessBlock %d %d;g", pb->io.ioParam.ioActCount, pb->entry->size); /* Flawfinder: ignore */
	        DEBUGSTR(c2pstr(tmpStr));
#endif
	    }

	    pb->entry->size = pb->io.ioParam.ioActCount;
	    pb->entry->current_size = pb->io.ioParam.ioActCount;
	    if(pb->io.ioParam.ioBuffer && pb->entry->size > 0)
	    {
	        pb->entry->state = AB_STATE_FULL;
	        m_ulReadPositionInFile	+= pb->entry->size;
	    }
	    else
	    {
	        pb->entry->state = AB_STATE_IGNORED;
	    }
	}

	if (mOutStandingCallbacks == 0)
	{
            m_bAllCallbacksCompleted = TRUE;
	}
	m_pMutex->Unlock();
}

void CMacAsyncFile::AddToThePendingList(void* pNode)
{
    m_pMutex->Lock();

    /* Atleast one of the list MUST be free to operate on */
    HX_ASSERT(m_pPendingCallbackList != NULL);
		
    if (m_pPendingCallbackList)
    {
        m_pPendingCallbackList->AddTail(pNode);
    }

    m_pMutex->Unlock();
}		

//
//
//      Start the Async file IO call which physically reads the data into the buffer.
//
//
void CMacAsyncFile::ReadAsyncData(BOOL ASYNC)
{
    m_pMutex->Lock();

⌨️ 快捷键说明

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