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

📄 filecache.cpp

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

                if(pNewInfo->pBlock == NULL)
                    break;

                res = pNewInfo->pBlock->SetSize(ulValidDataSize);

                if(res != HXR_OK)
                    break;

                memcpy( (void*)(pNewInfo->pBlock->GetBuffer()),
                        (void*)(headInfo->pBlock->GetBuffer()+ ulInvalidDataSize),
                        ulValidDataSize );

                pNewInfo->ulOffset = headInfo->ulOffset + ulInvalidDataSize;
                pNewInfo->ulSize = ulValidDataSize;

                m_pList->AddHead( (void *)pNewInfo );

                headInfo->pBlock->Release();
                delete headInfo;
            }


            ulDiscardedData = byteCount;
            headInfo = NULL;
            res = HXR_OK;
            break;
        }

        currHead = m_pList->GetHeadPosition();
    }

    m_ulUsedCapacity -= ulDiscardedData;

    return res;

} // _DiscardDataFromHead()

// Check if utilizedData has exceeded THRESHOLD. If yes, discard 
// appropriate amount of data. Note that this
// method is not thread safe. The caller has to take care of 
// locking common data structures before calling this method.
HX_RESULT CHXFileCacheObject::_CheckForThresholdCondition()
{
    MLOG_HTTP("CHXFileCacheObject::_CheckForThresholdCondition()\n");

    if(m_ulUsedCapacity == 0)
    {
        return HXR_OK;
    }

    UINT32 ulLeastOffset = m_ulCurrentWriteOffset - m_ulUsedCapacity;
    UINT32 ulHighestOffset = m_ulCurrentWriteOffset - 1;

    HX_RESULT res = HXR_OK;

    INT32 nExcess = (m_ulCurrentReadOffset - ulLeastOffset) - 
                      (INT32)(m_lThreshold * m_ulCapacity * 0.01);

    if(nExcess > 0)
    {
        if(nExcess > m_ulUsedCapacity)
            nExcess = m_ulUsedCapacity; 

        res = _DiscardDataFromHead(nExcess, TRUE);

        INT32 nExtraFileData = m_ulFileWriteOffset - m_ulCurrentWriteOffset;
        if(nExtraFileData > 0)
        {
            UINT32 ulUnusedCapacity = m_ulCapacity - m_ulUsedCapacity;
            UINT32 ulFileReadData = ((UINT32)nExtraFileData > ulUnusedCapacity) ?
                                      ulUnusedCapacity: nExtraFileData;

            res = _CopyFromFileToTail(m_ulCurrentWriteOffset, ulFileReadData);
        }
    }

    return res;

} // _CheckForThresholdCondition()

// Discards exactly 'byteCount' amount of data from the tail.
// Note that this method is not thread safe. The caller has to take 
// care of locking common data structures before calling this method.
HX_RESULT CHXFileCacheObject::_DiscardDataFromTail(UINT32 byteCount, BOOL bWriteToFile)
{
    MLOG_HTTP("CHXFileCacheObject::_DiscardDataFromTail(%u, %d)\n", byteCount, bWriteToFile);

    HX_RESULT res = HXR_OK;

    if( (bWriteToFile) && (m_ulFileWriteOffset < m_ulCurrentWriteOffset) )
    {
        LISTPOSITION currPos = m_pList->GetTailPosition();

        while(currPos != NULL)
        {
            Info* pCurrInfo = (Info*)(m_pList->GetPrev(currPos));
            if( (m_ulFileWriteOffset >= pCurrInfo->ulOffset) &&
                (m_ulFileWriteOffset >= pCurrInfo->ulOffset + pCurrInfo->ulSize - 1) )
            {
                break;
            }

        }

        if(currPos != NULL)
        {
            Info* pCurrInfo = (Info*)(m_pList->GetAtNext(currPos));

            UINT32 ulValidData = m_ulFileWriteOffset - (pCurrInfo->ulOffset);
            UINT32 ulInvalidData = pCurrInfo->ulSize - ulValidData;

            fseek(m_pCacheFileHandle, m_ulFileWriteOffset, SEEK_SET);
            int nBytesWritten = fwrite( (void*)(pCurrInfo->pBlock->GetBuffer() + ulValidData),
                                sizeof(UCHAR), ulInvalidData, m_pCacheFileHandle);
            fflush(m_pCacheFileHandle);

            m_ulFileWriteOffset += ulInvalidData;

            pCurrInfo = (Info*)(m_pList->GetNext(currPos));
            while(pCurrInfo != NULL)
            {
                int nBytesWritten = fwrite( (void*)(pCurrInfo->pBlock->GetBuffer()),
                                sizeof(UCHAR), pCurrInfo->ulSize, m_pCacheFileHandle);
                fflush(m_pCacheFileHandle);

                m_ulFileWriteOffset += pCurrInfo->ulSize;

                pCurrInfo = (Info*)(m_pList->GetNext(currPos));
            }

        }
        else
        {
            res = HXR_UNEXPECTED;
        }
    }

    if(res != HXR_OK)
        return res;

    UINT32 ulDiscardedData = 0;

    Info *tailInfo = NULL;

    res = HXR_UNEXPECTED;

    LISTPOSITION currTail = m_pList->GetTailPosition();

    while(currTail != NULL)
    {
        tailInfo = (Info*)(m_pList->RemoveTail());

        UINT32 ulTailBlockSize = tailInfo->ulSize;

        if(ulDiscardedData + ulTailBlockSize <= byteCount)
        {
            tailInfo->pBlock->Release();
            delete tailInfo;
            
            ulDiscardedData += ulTailBlockSize;
        }
        else
        {
            if(ulDiscardedData + ulTailBlockSize > byteCount)
            {
                UINT32 ulValidDataSize = (ulDiscardedData + ulTailBlockSize - byteCount);

                Info *pNewInfo = new Info;
                if(pNewInfo == NULL)
                {
                   res = HXR_OUTOFMEMORY;
                   break;
                }

                m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
                                               (void **) &(pNewInfo->pBlock));

                if(pNewInfo->pBlock == NULL)
                    break;

                res = pNewInfo->pBlock->SetSize(ulValidDataSize);

                if(res != HXR_OK)
                    break;

                memcpy( (void*)(pNewInfo->pBlock->GetBuffer()),
                        (void*)(tailInfo->pBlock->GetBuffer()),
                        ulValidDataSize );

                pNewInfo->ulOffset = tailInfo->ulOffset;
                pNewInfo->ulSize = ulValidDataSize;

                m_pList->AddTail( (void *)pNewInfo );

                tailInfo->pBlock->Release();
                delete tailInfo;
            }


            ulDiscardedData = byteCount;
            tailInfo = NULL;
            res = HXR_OK;
            break;
        }

        currTail = m_pList->GetTailPosition();
    }

    m_ulUsedCapacity -= ulDiscardedData;
    m_ulCurrentWriteOffset -= ulDiscardedData; 

    return res;

} // _DiscardDataFromTail()


// Copies 'ulSize' amount of data from offset 'ulOffset' from
// the cache file. The blocks are added to the Tail of the list.
// The data is copied in blocks of size determined
// by CAPACITY_BLOCKSIZE_RATIO. Requires that the data is present
// in the file.
HX_RESULT CHXFileCacheObject::_CopyFromFileToTail(UINT32 ulOffset, UINT32 ulSize)
{
    MLOG_HTTP("CHXFileCacheObject::_CopyFromFileToTail(Offset = %u, Size = %u)\n", ulOffset, ulSize);

    if(ulSize == 0)
        return HXR_OK;

    m_ulCurrentWriteOffset = ulOffset;

    UINT32 ulBlockSize = m_ulCapacity/CAPACITY_BLOCKSIZE_RATIO;
    UINT32 ulRemainderBlockSize = 0;

    UINT32 ulNumFullBlocks = ulSize/ulBlockSize;
    if((ulSize%ulBlockSize) > 0)
    {
        ulRemainderBlockSize = ulSize - ulNumFullBlocks * ulBlockSize;
    }

    HX_RESULT res = HXR_OK;
    fseek(m_pCacheFileHandle, ulOffset, SEEK_SET);

    if(ulRemainderBlockSize > 0)
    {
        IHXBuffer* pRemainderBlock = NULL;
        m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
                         (void **) &pRemainderBlock);

        if(pRemainderBlock != NULL)
        {
            res = pRemainderBlock->SetSize(ulRemainderBlockSize);
        }
        else
        {
            res = HXR_OUTOFMEMORY;
        }

        if(res == HXR_OK)
        {
            fread( (void*)(pRemainderBlock->GetBuffer()),
                                    sizeof(UCHAR), ulRemainderBlockSize, m_pCacheFileHandle );

            Info* pNewInfo = new Info;
            if(pNewInfo == NULL)
            {
                res = HXR_OUTOFMEMORY;
            }
            else
            {
                // The new block should be contiguous
                pNewInfo->ulOffset = m_ulCurrentWriteOffset;
                pNewInfo->ulSize = ulRemainderBlockSize;
                pNewInfo->pBlock = pRemainderBlock;

                m_pList->AddTail( (void *)pNewInfo );

                m_ulUsedCapacity += ulRemainderBlockSize;
                m_ulCurrentWriteOffset += ulRemainderBlockSize;
            }
        }
    }

    if(res != HXR_OK)
        return res;

    for(int i = 0; i < ulNumFullBlocks; i++)
    {
        IHXBuffer* pTempBlock = NULL;
        m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
                         (void **) &pTempBlock);

        if(pTempBlock != NULL)
        {
            res = pTempBlock->SetSize(ulBlockSize);
        }
        else
        {
            res = HXR_OUTOFMEMORY;
        }

        if(res == HXR_OK)
        {
            fread( (void*)(pTempBlock->GetBuffer()),
                                    sizeof(UCHAR), ulBlockSize, m_pCacheFileHandle );

            Info* pNewInfo = new Info;
            if(pNewInfo == NULL)
            {
                res = HXR_OUTOFMEMORY;
            }
            else
            {
                // The new block should be contiguous
                pNewInfo->ulOffset = m_ulCurrentWriteOffset;
                pNewInfo->ulSize = ulBlockSize;
                pNewInfo->pBlock = pTempBlock;

                m_ulUsedCapacity += ulBlockSize;
                m_ulCurrentWriteOffset += ulBlockSize;

                m_pList->AddTail( (void *)pNewInfo );
            }
        }
    }

    return res;

} // _CopyFromFileToTail()



// Copies 'ulSize' amount of data from offset 'ulOffset' from
// the cache file. The blocks are added to the Head of the list.
// The data is copied in blocks of size determined
// by CAPACITY_BLOCKSIZE_RATIO. Requires that the data is present
// in the file.
HX_RESULT CHXFileCacheObject::_CopyFromFileToHead(UINT32 ulOffset, UINT32 ulSize)
{
    MLOG_HTTP("CHXFileCacheObject::_CopyFromFileToHead(Offset = %u, Size = %u)\n", ulOffset, ulSize);

    if(ulSize == 0)
        return HXR_OK;

    UINT32 ulBlockSize = m_ulCapacity/CAPACITY_BLOCKSIZE_RATIO;
    UINT32 ulRemainderBlockSize = 0;

    UINT32 ulNumFullBlocks = ulSize/ulBlockSize;
    if((ulSize%ulBlockSize) > 0)
    {
        ulRemainderBlockSize = ulSize - ulNumFullBlocks * ulBlockSize;
    }

    HX_RESULT res = HXR_OK;
    fseek(m_pCacheFileHandle, ulOffset + ulSize, SEEK_SET);
    UINT32 ulCurrBlockOffset = ulOffset + ulSize;

    if(ulRemainderBlockSize > 0)
    {
        IHXBuffer* pRemainderBlock = NULL;
        m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
                         (void **) &pRemainderBlock);

        if(pRemainderBlock != NULL)
        {
            res = pRemainderBlock->SetSize(ulRemainderBlockSize);
        }
        else
        {
            res = HXR_OUTOFMEMORY;
        }

        if(res == HXR_OK)
        {
            ulCurrBlockOffset -= ulRemainderBlockSize;
            fseek(m_pCacheFileHandle, ulCurrBlockOffset , SEEK_SET);
            fread( (void*)(pRemainderBlock->GetBuffer()),
                                    sizeof(UCHAR), ulRemainderBlockSize, m_pCacheFileHandle );
            fseek(m_pCacheFileHandle, ulCurrBlockOffset , SEEK_SET);

            Info* pNewInfo = new Info;
            if(pNewInfo == NULL)
            {
                res = HXR_OUTOFMEMORY;
            }
            else
            {
                // The new block should be contiguous
                pNewInfo->ulOffset = ulCurrBlockOffset;
                pNewInfo->ulSize = ulRemainderBlockSize;
                pNewInfo->pBlock = pRemainderBlock;

                m_pList->AddHead( (void *)pNewInfo );

                m_ulUsedCapacity += ulRemainderBlockSize;
            }
        }
    }

    if(res != HXR_OK)
        return res;

    for(int i = 0; i < ulNumFullBlocks; i++)
    {
        IHXBuffer* pTempBlock = NULL;
        m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
                         (void **) &pTempBlock);

        if(pTempBlock != NULL)
        {
            res = pTempBlock->SetSize(ulBlockSize);
        }
        else
        {
            res = HXR_OUTOFMEMORY;
        }

        if(res == HXR_OK)
        {
            ulCurrBlockOffset -= ulBlockSize;
            fseek(m_pCacheFileHandle, ulCurrBlockOffset, SEEK_SET);
            fread( (void*)(pTempBlock->GetBuffer()),
                                    sizeof(UCHAR), ulBlockSize, m_pCacheFileHandle );
            fseek(m_pCacheFileHandle, ulCurrBlockOffset, SEEK_SET);

            Info* pNewInfo = new Info;
            if(pNewInfo == NULL)
            {
                res = HXR_OUTOFMEMORY;
            }
            else
            {
                // The new block should be contiguous
                pNewInfo->ulOffset = ulCurrBlockOffset;
                pNewInfo->ulSize = ulBlockSize;
                pNewInfo->pBlock = pTempBlock;

                m_pList->AddHead( (void *)pNewInfo );

                m_ulUsedCapacity += ulBlockSize;

            }
        }
    }

    return res;

} // _CopyFromFileToHead()

// Copy all the data present in the list to the local file
HX_RESULT CHXFileCacheObject::_CopyAllDataToFile()
{
    MLOG_HTTP("CHXFileCacheObject::_CopyAllDataToFile()\n");

    if(m_pList == NULL)
        return HXR_UNEXPECTED;

    LISTPOSITION currPos = m_pList->GetHeadPosition();
    Info* pCurrInfo;
    while(currPos != NULL)
    {
        pCurrInfo = (Info *)m_pList->GetNext(currPos);
        UINT32 ulCurrBlockOffset = pCurrInfo->ulOffset;
        UINT32 ulCurrBlockSize = pCurrInfo->ulSize;

        // If data already written to file, no need to write again.
        if( (m_ulFileWriteOffset >= ulCurrBlockOffset) &&
            (m_ulFileWriteOffset <= ulCurrBlockOffset + ulCurrBlockSize - 1) )
        {
            UINT32 ulDataAlreadyWritten = m_ulFileWriteOffset - ulCurrBlockOffset;
            UINT32 ulDataToWrite = ulCurrBlockSize - ulDataAlreadyWritten;

            fseek(m_pCacheFileHandle, m_ulFileWriteOffset, SEEK_SET);
            int nBytesWritten = fwrite( (void*)(pCurrInfo->pBlock->GetBuffer() +
                                        ulDataAlreadyWritten), sizeof(UCHAR), 
                                        ulDataToWrite, m_pCacheFileHandle);
            fflush(m_pCacheFileHandle);

            m_ulFileWriteOffset += ulDataToWrite;
        }
    }

    return HXR_OK;

} // _CopyAllDataToFile()

⌨️ 快捷键说明

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