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

📄 macasyncfile.cpp

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

#if defined(_DEBUG) && defined (_LOG_DATA)
    char str[255]; /* Flawfinder: ignore */
   ::sprintf(str, "ReadAsyncData: %d;g", (int) ASYNC); /* Flawfinder: ignore */
    DEBUGSTR(c2pstr(str));
#endif
 
    // mOutStandingCallbacks: if there are any, then we bail right
    // now 'cause we don't want scads of pending callbacks... the math
    // will work out in the end because subsequent calls will have us
    // read more bytes.
    
    if(!mRefNum || m_bFileDone || mOutStandingCallbacks > 0)
    {
        m_pMutex->Unlock();
	return;
    }

    ULONG32 emptysize = mReadQueue->GetAvailableElements();

    if(emptysize < kNeedToReadThreshhold)
    {
        m_pMutex->Unlock();
        DEBUGSTR("\p ReadAsyncData: emptysize < kNeedToReadThreshhold ;g");
 	return;
    }
    
    if (m_bCheckFromPQ)
    {
        BOOL bFilled = FillBufferFromPQ(m_ulReadPositionInFile);
        if (bFilled)
        {
            emptysize = mReadQueue->GetAvailableElements();
            if(emptysize < kNeedToReadThreshhold)
            {
                m_pMutex->Unlock();
                return;
            }
        }
    }
    
    if (emptysize > kMacMaxChunkToRead)
    {
	emptysize = kMacMaxChunkToRead;
    }
    
    if (m_bInternalSeekNeeded)
    {
        m_bInternalSeekNeeded = FALSE;
        PerformInternalSeek(ASYNC);
        // more stuff will be done once we get async callback for internal seek
        if (ASYNC)
        {
            m_pMutex->Unlock();
            return;
        }
    }

    HXParamBlockRec *pb = new HXParamBlockRec;

    memset(pb, 0, sizeof(HXParamBlockRec));

    pb->param = this;
    pb->io.ioParam.ioCompletion = zmIOCallbackUPP;
    pb->io.ioParam.ioRefNum = mRefNum;

    pb->entry = new HXAsyncQueueBuffer;
    memset(pb->entry, 0, sizeof(HXAsyncQueueBuffer));
    pb->entry->size = emptysize;
    pb->entry->current_size = emptysize;
    
    pb->entry->position_in_file = m_ulReadPositionInFile;

    char* tempbuffer = new char[emptysize];

    pb->entry->buffer 		= tempbuffer;
    pb->entry->current_buf_ptr  = tempbuffer;
    pb->entry->state = AB_STATE_EMPTY;

    pb->io.ioParam.ioBuffer = tempbuffer;
    pb->io.ioParam.ioReqCount = emptysize;

    HX_ASSERT(mSeekFromWhere == 0);

    e = ReadData(pb, ASYNC);


    if (!ASYNC)
    {
         if (e == noErr)
         {
	     pb->entry->state = AB_STATE_FULL;
	     pb->entry->size = pb->io.ioParam.ioActCount;
	     pb->entry->current_size = pb->io.ioParam.ioActCount;
	     m_ulReadPositionInFile += pb->entry->size;
	     mAsyncQueue->AddTail(pb->entry);
	 }
	 else
	 {
	     HX_DELETE(pb->entry);
	 }
	     	 
	 HX_DELETE(pb);
    }
    else
    {
        if (e != noErr)
        {
	    HX_DELETE(pb->entry);
	    HX_DELETE(pb);
        }
    }    

    DEBUGSTR("\p ReadAsyncData EXIT; g");

    m_pMutex->Unlock();

    return;
}

ULONG32 CMacAsyncFile::WriteAsyncData(IHXBuffer* pBuffer, BOOL ASYNC)
{
    ULONG32 outWrittenSize = 0;
    OSErr e = noErr;

#if defined(_DEBUG) && defined (_LOG_DATA)
    char str[255]; /* Flawfinder: ignore */
   ::sprintf(str, "WriteAsyncData: %d;g", (int) ASYNC); /* Flawfinder: ignore */
    DEBUGSTR(c2pstr(str));
#endif
 
    if(!mRefNum)
    {
	return outWrittenSize;
    }

    pBuffer->AddRef();

    HXParamBlockRec *pb = new HXParamBlockRec;

    memset(pb, 0, sizeof(HXParamBlockRec));

    pb->param = this;
    pb->io.ioParam.ioCompletion = zmIOCallbackUPP;
    pb->io.ioParam.ioRefNum = mRefNum;

    pb->entry = new HXAsyncQueueBuffer;
    memset(pb->entry, 0, sizeof(HXAsyncQueueBuffer));
    
    outWrittenSize = pBuffer->GetSize();
    pb->entry->size = outWrittenSize;
    pb->entry->current_size = outWrittenSize;
    pb->entry->state = AB_STATE_WRITE;

    char* tempbuffer = NULL;
    if (ASYNC)
    {
    	tempbuffer = new char[outWrittenSize];
    	BlockMoveData(pBuffer->GetBuffer(), tempbuffer, outWrittenSize);
    	pb->entry->buffer = tempbuffer;
    	pb->entry->current_buf_ptr = tempbuffer;
	pb->io.ioParam.ioBuffer = tempbuffer;
    }
    else
    {
	pb->io.ioParam.ioBuffer = ( char* ) pBuffer->GetBuffer();
    }

    pb->io.ioParam.ioReqCount = outWrittenSize;

    HX_ASSERT(mSeekFromWhere == 0);

    e = WriteData(pb, ASYNC);


    if (!ASYNC)
    {
	 HX_DELETE(pb->entry);
	 HX_DELETE(pb);
    }
    else
    {
        if (e != noErr)
        {
	    HX_DELETE(pb->entry);
	    HX_DELETE(pb);
        }
    }    

    DEBUGSTR("\p WriteAsyncData EXIT; g");
    pBuffer->Release();
    return outWrittenSize;
}

void CMacAsyncFile::UpdateFilePos(BOOL bASync, BOOL bInternal)
{
    AddRef();
    m_pMutex->Lock();
     DEBUGSTR("\p UpdateFilePos;g");
   OSErr e = noErr;

    if(!mRefNum)
    {
	m_pMutex->Unlock();
	Release();
	return;
    }

    HXParamBlockRec *pb = new HXParamBlockRec;

    memset(pb, 0, sizeof(HXParamBlockRec));

    pb->param = this;
    pb->io.ioParam.ioRefNum = mRefNum;
    pb->io.ioParam.ioReqCount = 0;
    pb->io.ioParam.ioCompletion = zmIOCallbackUPP;

    pb->entry = new HXAsyncQueueBuffer;
    memset(pb->entry, 0, sizeof(HXAsyncQueueBuffer));

    HX_ASSERT(mSeekFromWhere > 0);

    if(mSeekFromWhere)
    {
	pb->io.ioParam.ioPosMode = mSeekFromWhere;
	pb->io.ioParam.ioPosOffset = mSeekPos;

	mSeekFromWhere = 0;
	mSeekPos = 0;
	if (bInternal)
	{
            pb->entry->state = AB_STATE_ASYNC_INTERNAL_SEEK;
        }
        else
        {
            pb->entry->state = AB_STATE_ASYNC_SEEK;
        }
    }

    e = SeekData(pb, bASync);

    if (!bASync)
    {
         if (e == noErr)
         {
	     m_ulReadPositionInFile = pb->io.ioParam.ioPosOffset;
             if (!bInternal)
             {
	         mFilePos = pb->io.ioParam.ioPosOffset;
	     }
	 }
	     
	 HX_DELETE(pb->entry);
	 HX_DELETE(pb);
    }
    else
    {
        if (e != noErr)
        {
	    HX_DELETE(pb->entry);
	    HX_DELETE(pb);
        }
    }    

    if (!bASync && !bInternal)
    {
	PendingAsyncSeekDone();
    }

    m_pMutex->Unlock();
    Release();
    return;

}

OSErr
CMacAsyncFile::ReadData(HXParamBlockRec* pb, BOOL ASYNC)
{
    m_pMutex->Lock();

    OSErr e = noErr;

    if(ASYNC)
    {
	mAsyncQueue->AddTail(pb->entry);
	mOutStandingCallbacks++;
    }
    
    // xxxbobclark large PBRead's on SMB-mounted volumes are failing here.
    // That's why we reduced the constants in the .h file for carbon builds.

    e = PBRead((ParmBlkPtr) pb, ASYNC);

    if (e == eofErr)
    {
	    m_bFileDone = TRUE;
	    
        DEBUGSTR("\pFIle Done in ReadData;g");
	    /* Mask this error if this is the last read */
	    /* If either we are in aysnc mode OR we actually read some data */
	    if (ASYNC ||  pb->io.ioParam.ioActCount > 0)
	    {
	    	e = noErr;
	    }
    }

    if(e != noErr && ASYNC && mOutStandingCallbacks > 0)
    {
        mAsyncQueue->RemoveTail();
        mOutStandingCallbacks--;
    }

    m_pMutex->Unlock();

    return e;
}

OSErr
CMacAsyncFile::WriteData(HXParamBlockRec* pb, BOOL ASYNC)
{
    m_pMutex->Lock();

    OSErr e = noErr;

    if(ASYNC)
    {
	mAsyncQueue->AddTail(pb->entry);
	mOutStandingCallbacks++;
    }

    e = PBWrite((ParmBlkPtr) pb, ASYNC);

    if(e != noErr && ASYNC && mOutStandingCallbacks > 0)
    {
        mAsyncQueue->RemoveTail();
        mOutStandingCallbacks--;
    }

    m_pMutex->Unlock();

    return e;
}

OSErr
CMacAsyncFile::SeekData(HXParamBlockRec* pb, BOOL ASYNC)
{
    m_pMutex->Lock();

    OSErr e = noErr;

    if(ASYNC)
    {
	    mAsyncQueue->AddTail(pb->entry);
	    mOutStandingCallbacks++;
    }

    e = PBSetFPos((ParmBlkPtr) pb, ASYNC);

    if (e == eofErr)
    {
	DEBUGSTR("\p File done in SeekData");
	m_bFileDone = TRUE;
	e = noErr;
    }

    if(e != noErr && ASYNC && mOutStandingCallbacks > 0)
    {
        mAsyncQueue->RemoveTail();
	mOutStandingCallbacks--;
    }

    m_pMutex->Unlock();

    return e;
}

void
CMacAsyncFile::PendingAsyncSeekDone()
{
    AddRef();
    m_pMutex->Lock();
    HX_ASSERT(m_bSeekPending == TRUE);

    m_bSeekPending = FALSE;
     DEBUGSTR("\p PendingAsyncSeekDone;g");
   // ? should check status
    m_pResponse->AsyncSeekDone(HXR_OK);
    m_pMutex->Unlock();
    Release();
}

void
CMacAsyncFile::AllPendingCallbacksDone()
{   
    DEBUGSTR("\p AllPendingCallbacksDone;g");

    m_pMutex->Lock();
    
    HX_ASSERT(m_pPendingCallbackList->GetCount() == 0);
     	      
    if(m_bReadPending)
    {
        EnqueueAsyncBuffers();
	ProcessPendingRead();
    }

    /* If there is still a pending read and no outstanding reads
     * issue one more read
     */
    if(m_bReadPending && mOutStandingCallbacks == 0)
    {
        DEBUGSTR("\pm_bReadPending && mOutStandingCallbacks == 0;g");
	ReadAsyncData(TRUE);
    }
    m_pMutex->Unlock();
}

void
CMacAsyncFile::ProcessPendingRead()
{
    AddRef();
    m_pMutex->Lock();
    
    ULONG32 totalinqueue = mReadQueue->GetQueuedItemCount();
    ULONG32 numberInPendingCallbackList = m_pPendingCallbackList->GetCount();
    if(m_bReadPending &&
       ((m_bFileDone && numberInPendingCallbackList == 0) ||
       (totalinqueue >= m_ulPendingReadCount)))
    {
	m_bReadPending = FALSE;

	if (totalinqueue == 0)
	{
       DEBUGSTR("\p AsyncReadDone FAIL;g");
 	    m_pResponse->AsyncReadDone(HXR_FAIL, NULL);
	}
	else
	{
   	    UINT32 count = m_ulPendingReadCount;
	
	    if (count > totalinqueue)
	    {
		count = totalinqueue;
	    }

	    IHXBuffer *pBuffer = new CHXBuffer;
	    pBuffer->AddRef();
	    pBuffer->SetSize(count);
	    char *buf = (char*) pBuffer->GetBuffer();

		    mFilePos += mReadQueue->DeQueue(buf, count);
		    
#if defined(_DEBUG) && defined (_LOG_DATA)
       char str[255]; /* Flawfinder: ignore */
       ::sprintf(str, "AsyncReadDone: HXR_OK: %d;g", (int) count); /* Flawfinder: ignore */
        DEBUGSTR(c2pstr(str));
#endif	    
	    m_pResponse->AsyncReadDone(HXR_OK, pBuffer);
	    pBuffer->Release();
	}
    }
    m_pMutex->Unlock();
    Release();
}

HX_RESULT
CMacAsyncFile::SetAsyncResponse(CMacAsyncFileResponse * pResponse)
{
    if(!pResponse)
    {
	return HXR_UNEXPECTED;
    }

    m_pMutex->Lock();
    m_pResponse = pResponse;
    m_pMutex->Unlock();
    return HXR_OK;
}

⌨️ 快捷键说明

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