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

📄 httpfsys.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if (m_uRecursionCount > 0)    {        m_uRecursionCount--;    }}/************************************************************************ *  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 CHTTPFileObject::Read(ULONG32 ulCount){    HX_RESULT           lResult      = HXR_OK;    static UINT32       ulReadCount  = 0;          LOGX((szDbgTemp, "Read #%03lu, Size is %4lu, Recurs is %2u, FileObj is '%s'",          ++ulReadCount, ulCount, m_uRecursionCount + 1, NULLOK(m_pFilename)));    #ifdef CREATE_LOG_DUMP    FILE *fp = fopen(LOG_DUMP_FILE, "a+");    if (fp)    {        fprintf(fp, "Read %lx from %ld %ld\n", m_pChunkyRes, m_ulCurrentReadPosition, ulCount);        fclose(fp);    }    #endif    if (m_LastError)    {        return m_LastError;    }    /* It is illegal to call read if a seek is pending */    if (m_bSeekPending)    {        #ifdef CREATE_LOG_DUMP        FILE *fp = fopen(LOG_DUMP_FILE, "a+");        if (fp)        {            fprintf(fp, "Cancel Read: Seek Pending %lx %ld\n", m_pChunkyRes, ulCount);            fclose(fp);        }        #endif        CallReadDone(HXR_SEEK_PENDING ,NULL);        return HXR_UNEXPECTED;    }    /* mark it as a pending read request..     * We do this since a call to readdone may result in a call to read     * which may mess up the sequence in which we read data and pass it to     * the caller (specially when some reads are pendiing     */    m_PendingReadList.AddTail((void*) ulCount);    if (m_bInReadDone)    {        m_uRecursionCount++;    }    if (m_uRecursionCount > m_uMaxRecursionLevel)    {        if (m_pCallback && !m_pCallback->m_bCallbackPending)        {            m_pCallback->m_bCallbackPending     = TRUE;            m_pCallback->m_ulPendingCallbackID  = m_pScheduler->RelativeEnter(m_pCallback, 0);        }        return HXR_OK;    }    // This adds greatly to the stack depth when Read()s are recursed --fnh#ifdef _MACINTOSH    /*      * We do not call ProcessPending reads at interrupt time on Mac     * This is because we use ChunkyRes which writes/reads data to     * disk. We do not want it to happen at interrupt time since     * chunkyres has synchronous interface and it makes synchronous     * file io calls. We should someday change chunkyres interface to     * be async and also modify it to use aysnc file io to read/write     */    if (m_pInterruptState && m_pInterruptState->AtInterruptTime())    {        if (m_pCallback && !m_pCallback->m_bCallbackPending)        {            m_pCallback->m_bCallbackPending     = TRUE;            m_pCallback->m_ulPendingCallbackID  =                        m_pScheduler->RelativeEnter(m_pCallback, 0);        }        return HXR_OK;      }    else    {        lResult = ProcessPendingReads();    }#else    lResult = ProcessPendingReads();#endif      return lResult;}/************************************************************************ *  Method: *      IHXFileObject::Write *  Purpose: *      Writes a buffer of data to the file and asynchronously notifies *      the caller via the IHXFileResponse interface passed in to Init, *      of the completeness of the operation. */STDMETHODIMP CHTTPFileObject::Write(IHXBuffer* pBuffer){    HX_RESULT nRetVal = HXR_FAILED;    if (m_pSocket && m_nPostDataSize && pBuffer)    {	nRetVal = m_pSocket->Write(pBuffer);	if(nRetVal == HXR_OK)	{	    if(m_nPostDataSize >= pBuffer->GetSize())		m_nPostDataSize -= pBuffer->GetSize();	    else		m_nPostDataSize = 0;	}    }    return nRetVal;}/************************************************************************ *  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 CHTTPFileObject::Seek(ULONG32 ulOffset, BOOL bRelative){    #ifdef CREATE_LOG_DUMP    FILE *fp = fopen(LOG_DUMP_FILE, "a+");    if (fp)    {        fprintf(fp, "Seek %lx %ld\n", m_pChunkyRes, ulOffset);        fclose(fp);    }    #endif        if (m_LastError)    {        return m_LastError;    }    #ifdef CREATE_LOG_DUMP    if (m_PendingReadList.GetCount())    {        FILE *fp = fopen(LOG_DUMP_FILE, "a+");        if (fp)        {            fprintf(fp, "_Reopen %lx pending reads %ld\n", m_pChunkyRes, m_PendingReadList.GetCount());            fclose(fp);        }    }    #endif    while (m_PendingReadList.GetCount())    {        m_PendingReadList.RemoveHead();        m_pFileResponse->ReadDone(HXR_CANCELLED, NULL);    }        if (bRelative)    {        m_ulCurrentReadPosition += ulOffset;    }    else    {        m_ulCurrentReadPosition = ulOffset;    }    /* check if there were any pending reads */    if (m_bSeekPending || m_bReadPending)     {        #ifdef CREATE_LOG_DUMP        FILE *fp = fopen(LOG_DUMP_FILE, "a+");        if (fp)        {            fprintf(fp, "Cancel Seek: Seek Pending %lx %ld\n", m_pChunkyRes, ulOffset);            fclose(fp);        }        #endif                m_bSeekPending  = FALSE;        m_pFileResponse->SeekDone(HXR_CANCELLED);    }    if (m_pChunkyRes->HasPartialData(1, m_ulCurrentReadPosition))    {        // Don't call SeekDone until we are actaully done with the seek        if (m_bSupportsByteRanges)	{	    _EnsureThatWeAreReadingWisely();                        // m_bByteRangeSeekPending means we reconnecting the socket             // a new location.            if (m_bByteRangeSeekPending)                m_bSeekPending = TRUE;            else            {                #ifdef CREATE_LOG_DUMP                FILE *fp = fopen(LOG_DUMP_FILE, "a+");                if (fp)                {                    fprintf(fp, "SeekDone no reconnect %lx %ld\n", m_pChunkyRes, m_ulCurrentReadPosition);                    fclose(fp);                }                #endif                                m_pFileResponse->SeekDone(HXR_OK);            }	}        else        {            #ifdef CREATE_LOG_DUMP            FILE *fp = fopen(LOG_DUMP_FILE, "a+");            if (fp)            {                fprintf(fp, "SeekDone %lx %ld\n", m_pChunkyRes, m_ulCurrentReadPosition);                fclose(fp);            }            #endif                        m_pFileResponse->SeekDone(HXR_OK);        }    }    else    {        if (m_bSupportsByteRanges)        {	    // signal the caller about the end of content	    if (m_ulCurrentReadPosition == m_nContentRead)	    {                #ifdef CREATE_LOG_DUMP                FILE *fp = fopen(LOG_DUMP_FILE, "a+");                if (fp)                {                    fprintf(fp, "SeekDone Gaps read=write %lx %ld\n", m_pChunkyRes, m_ulCurrentReadPosition);                    fclose(fp);                }                #endif	                        m_pFileResponse->SeekDone(HXR_OK);	    }	    else if (m_bKnowContentSize && m_ulCurrentReadPosition == m_nContentSize)            {                #ifdef CREATE_LOG_DUMP                FILE *fp = fopen(LOG_DUMP_FILE, "a+");                if (fp)                {                    fprintf(fp, "SeekDone gaps read=end %lx %ld\n", m_pChunkyRes, m_ulCurrentReadPosition);                    fclose(fp);                }                #endif		                m_pFileResponse->SeekDone(HXR_OK);            }            else	    {                // We need to reconnect if:                // 1. The read pointer is behind the write pointer and there are gaps OR                // 2. The write pointer is behind the read pointer with too many bytes to simply wait for                if (!m_bByteRangeSeekPending)                {                    if (m_ulCurrentReadPosition < m_nContentRead ||                        m_ulCurrentReadPosition - m_nContentRead > BYTE_RANGE_SEEK_THRESHHOLD)                    {                        _HandleByteRangeSeek(m_ulCurrentReadPosition);                    }                }                    		m_bSeekPending = TRUE;	    }        }        else        {            /* is it a valid value to seek to?*/	    if (m_bReadContentsDone)	    {	        // signal the caller about the end of content	        if (m_ulCurrentReadPosition == m_nContentRead)	        {		    m_pFileResponse->SeekDone(HXR_OK);	        }	        else	        {		    HX_ASSERT(m_ulCurrentReadPosition > m_nContentRead);		    m_pFileResponse->SeekDone(HXR_FAILED);	        }            }            else /* add it to the seek pending queue...*/            {	        m_bSeekPending = TRUE;            }        }    }    return (HXR_OK);}/************************************************************************ * Method: *      IHXFileObject::Stat * Purpose: *      Collects information about the file that is returned to the *      caller in an IHXStat object */STDMETHODIMP CHTTPFileObject::Stat(IHXFileStatResponse* pFileStatResponse){    LOGX ((szDbgTemp, "Stat(%s)", m_pFilename));    /*     * XXXGH...Need to get real statistics     */    if(!m_bReadHeaderDone)    {        m_bStatPending = TRUE;        m_pFileStatResponse = pFileStatResponse;        m_pFileStatResponse->AddRef();    }    else    {        pFileStatResponse->StatDone(HXR_OK, m_nContentSize, 0, 0, 0, 0);    }    return HXR_OK;}/************************************************************************ *  Method: *      IHXFileObject::Advise *  Purpose: *      To pass information to the File Object */STDMETHODIMP CHTTPFileObject::Advise(ULONG32 ulInfo){    HX_RESULT pnr = HXR_OK;    // XXXJEFFA it's possible that for cached HTTP we want to    // return HXR_OK from this instead of prefer linear since    // the file is local in the cache but that's an optimization    // we can make later JEFFA 11/8/98    // disable the HTTP1.1 support if the file format    // doesn't support async seek(i.e. AVI)    if (ulInfo == HXR_ADVISE_NOASYNC_SEEK)    {        m_bDisableByteRanges = TRUE;        m_bSupportsByteRanges = FALSE;    }    else if (ulInfo == HX_FILEADVISE_RANDOMACCESS)    {        if (m_bSupportsByteRanges && !IsLiveStream(m_strMimeType))            pnr = HXR_OK;        else            pnr = HXR_ADVISE_PREFER_LINEAR;    }    else if (HX_FILEADVISE_RANDOMACCESSONLY == ulInfo)    {        m_bConvertFailedSeeksToLinear = FALSE;    }    else if (HX_FILEADVISE_ANYACCESS == ulInfo)    {        m_bConvertFailedSeeksToLinear = TRUE;    }    return pnr;}/************************************************************************ *      Method: *          IHXFileObject::GetFileObjectFromPool *      Purpose: *      To get another FileObject from the same pool. */STDMETHODIMP CHTTPFileObject::GetFileObjectFromPool(    IHXGetFileFromSamePoolResponse* response){    LOGX ((szDbgTemp, "GetFileObjectFromPool(%s)", m_pFilename));    HX_RESULT           lReturnVal = HXR_FAIL;    CHTTPFileObject*    pFileObject = NULL;    IUnknown*           pUnknown = NULL;    CHXString           sBaseURL;    INT32               nBeforeFile;    sBaseURL = m_pFilename;    nBeforeFile = max    (        sBaseURL.ReverseFind('\\'),        sBaseURL.ReverseFind('/')    );    if(nBeforeFile > -1)    {        sBaseURL = sBaseURL.Left(nBeforeFile);        pFileObject = CHTTPFileObject::CreateObject();        if (pFileObject)        {            pFileObject->InitObject            (                sBaseURL.GetBuffer(1),                 m_pFileSystem,                 m_pContext,		m_pOptions            );            lReturnVal = pFileObject->QueryInterface            (                IID_IUnknown,                 (void**)&pUnknown            );        }	else	{            response->FileObjectReady(HXR_OUTOFMEMORY, NULL);            return HXR_OUTOFMEMORY;	}    }    response->FileObjectReady    (        lReturnVal == HXR_OK ? HXR_OK : HXR_FAIL,        pUnknown    );    HX_RELEASE(pUnknown);    return lReturnVal;}// IHXFileExists interface/************************************************************************ *      Method: *          IHXFileExists::DoesExist *      Purpose: */STDMETHODIMP CHTTPFileObject::DoesExist(                        const char*             /*IN*/  pPath,                        IHXFileExistsResponse* /*IN*/  pFileExistsResponse){    LOGX ((szDbgTemp, "DoesExist(%s)", pPath));

⌨️ 快捷键说明

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