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

📄 chunkres.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: chunkres.cpp,v 1.14.32.4 2004/07/09 01:44:51 hubbe Exp $ *  * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. *  * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks.  You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL.  Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. *  * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. *  * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. *  * Technology Compatibility Kit Test Suite(s) Location: *    http://www.helixcommunity.org/content/tck *  * Contributor(s): *  * ***** END LICENSE BLOCK ***** */#include "hxslist.h"#include "chunkres.h"#include "hlxclib/stdlib.h"		// needed for MAX_PATH#include "hlxclib/stdio.h"		// for fopen(), etc.#include "hlxclib/limits.h"		// for INT_MAX, etc.#include "hlxclib/fcntl.h"	// for O_CREAT, etc.#include "hlxclib/io.h"#include "hlxclib/windows.h"#include "chxdataf.h"	// cross platform file object#ifdef _MACINTOSH#ifdef _MAC_MACHO#include <unistd.h> // for unlink call#else#include <unix.h>		// for unlink call#undef _UNIX	//defined in unixmac.h#endif#endif#ifdef _UNIX#include <unistd.h> 	// for unlink#ifndef _MAX_PATH#define _MAX_PATH		256#endif#endif#ifdef _SYMBIAN#include <unistd.h> //for unlink#endif#include "hxheap.h"#ifdef _DEBUG#undef HX_THIS_FILEstatic const char HX_THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::OpenResource()////	Purpose:////		Opens an existing resource or creates a new resource.////	Parameters:////		CChunkyRes** ppChunkyRes//		Memory location that will be filled in on output with the pointer//		to the opened CChunkRes object.////		const char* pResName//		Unique name of the resource to open or create.////	Return:////		HX_RESULT//		Possible errors include: TBD.//HX_RESULT CChunkyResMgr::OpenResource(CChunkyRes** ppChunkyRes, const char* pResName){    HX_RESULT theErr = HXR_OK;    HX_ASSERT(ppChunkyRes && pResName);        void* pData;    if (m_OpenResources.Lookup(pResName, pData))    {	*ppChunkyRes = (CChunkyRes*)pData;    }    else if (m_ClosedResources.Lookup(pResName, pData))    {	*ppChunkyRes = (CChunkyRes*)pData;	HX_VERIFY(m_ClosedResources.RemoveKey(pResName));	m_OpenResources.SetAt(pResName, pData);	RemoveFromLRU(pResName);    }    else    {	*ppChunkyRes = new CChunkyRes;	if (*ppChunkyRes)	{	    m_OpenResources.SetAt(pResName, (void*)*ppChunkyRes);	}	else	{	    theErr = HXR_OUTOFMEMORY;	}    }    return theErr;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::CloseResource()////	Purpose:////		Closes an existing resource. Closed resources may be discarded.////	Parameters:////		CChunkyRes* pChunkyRes//		Pointer to a previously opened CChunkRes object.////	Return:////		HX_RESULT//		Possible errors include: TBD.//HX_RESULT CChunkyResMgr::CloseResource(CChunkyRes* pChunkyRes){    HX_RESULT theErr = HXR_FAIL;    POSITION pPos = m_OpenResources.GetStartPosition();    while (pPos)    {	CHXString key;	void* pData;	m_OpenResources.GetNextAssoc(pPos, key, pData);	if (pData == (void*)pChunkyRes)	{	    HX_VERIFY(m_OpenResources.RemoveKey(key));	    m_ClosedResources.SetAt(key, pData);	    HX_ASSERT(!m_LRUResources.FindString(key));	    m_LRUResources.AddTailString(key);	    theErr = HXR_OK;	}    }    if (theErr == HXR_OK)    {	DiscardDiskData();    }    return theErr;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::CloseResource()////	Purpose:////		Closes an existing resource. Closed resources may be discarded.////	Parameters:////		const char* pResName//		Unique name of a previously opened resource.////	Return:////		HX_RESULT//		Possible errors include: TBD.//HX_RESULT CChunkyResMgr::CloseResource(const char* pResName){    HX_RESULT theErr = HXR_FAIL;    void* pData;    if (m_OpenResources.Lookup(pResName, pData))    {	HX_VERIFY(m_OpenResources.RemoveKey(pResName));	m_ClosedResources.SetAt(pResName, pData);	HX_ASSERT(!m_LRUResources.FindString(pResName));	m_LRUResources.AddTailString(pResName);	theErr = HXR_OK;    }    if (theErr == HXR_OK)    {	DiscardDiskData();    }    return theErr;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::DiscardResource()////	Purpose:////		Discards a resource. Closed resources may be discarded.////	Parameters:////		const char* pResName//		Unique name of a previously opened resource.////	Return:////		HX_RESULT//		Possible errors include: TBD.//HX_RESULT CChunkyResMgr::DiscardResource(const char* pResName){    HX_RESULT theErr = HXR_FAIL;    void* pData;    if (m_OpenResources.Lookup(pResName, pData))    {	HX_VERIFY(m_OpenResources.RemoveKey(pResName));	CChunkyRes* pRes = (CChunkyRes*)pData;	delete pRes;	theErr = HXR_OK;    }    if (m_ClosedResources.Lookup(pResName, pData))    {	HX_VERIFY(m_ClosedResources.RemoveKey(pResName));	RemoveFromLRU(pResName);	CChunkyRes* pRes = (CChunkyRes*)pData;	delete pRes;	theErr = HXR_OK;    }    return theErr;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::FindResource()////	Purpose:////		Looks to see if the resource exists.////	Parameters:////		const char* pResName//		Unique name of a previously opened resource.////	Return:////		HX_RESULTHX_RESULTCChunkyResMgr::FindResource(const char* pResName){    void* pData;    if (m_OpenResources.Lookup(pResName, pData) ||	m_ClosedResources.Lookup(pResName, pData))    {	return HXR_OK;    }    return HXR_FAIL;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::SetDiskUsageThreshold()////	Purpose:////		Sets the Disk Usage threshold for the chunky resource manager.//		If closed resources amount to more than the threshold, then they//		will be discarded.////	Parameters:////		ULONG32 diskUsage//		Disk usage in bytes which will be allowed for closed resources.////	Return:////		None.//void CChunkyResMgr::SetDiskUsageThreshold(ULONG32 diskUsage){    m_ulDiskUsage = diskUsage;    DiscardDiskData();}void CChunkyResMgr::DiscardDiskData(){    void* pData = NULL;    CChunkyRes* pRes = NULL;    ULONG32 ulTotal = 0;    // Count the total disk usage    POSITION pPos = m_ClosedResources.GetStartPosition();    while (pPos)    {	CHXString key;	m_ClosedResources.GetNextAssoc(pPos, key, pData);	HX_ASSERT(pData);	pRes = (CChunkyRes*)pData;	ulTotal += pRes->GetDiskUsage();    }    // Trim as much as we need until we're under the disk usage threshold.    pPos = m_LRUResources.GetHeadPosition();    while (pPos && ulTotal > m_ulDiskUsage)    {	CHXString* pResName = m_LRUResources.GetNext(pPos);	HX_ASSERT(pResName);	if (m_ClosedResources.Lookup(*pResName, pData))	{	    HX_ASSERT(pData);	    pRes = (CChunkyRes*)pData;	    ULONG32 ulSize = pRes->GetDiskUsage();	    if (ulSize)	    {		HX_ASSERT(ulSize <= ulTotal);		ulTotal -= ulSize;		m_ClosedResources.RemoveKey(*pResName);		RemoveFromLRU(*pResName);		delete pRes;	    }	}    }}void CChunkyResMgr::RemoveFromLRU(const char* pResName){    POSITION pPos = m_LRUResources.GetHeadPosition();    POSITION pPrev;     while (pPos)    {	pPrev = pPos;	CHXString* pStr = m_LRUResources.GetNext(pPos);	if (!strcmp(*pStr, pResName))	{	    m_LRUResources.RemoveAt(pPrev);	}    }}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::CChunkyResMgr()////	Purpose:////		Construtor for chunky resource manager.////	Parameters:////		None.////	Return:////		N/A//CChunkyResMgr::CChunkyResMgr()    : m_ulDiskUsage(0){}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyResMgr::~CChunkyResMgr()////	Purpose:////		Destructor for chunky resource manager.////	Parameters:////		None.////	Return:////		N/A//CChunkyResMgr::~CChunkyResMgr(){    CHXString	key;    CChunkyRes* pRes;    POSITION	p;        p = m_OpenResources.GetStartPosition();    while (p)    {	m_OpenResources.GetNextAssoc(p, key, (void*&)pRes);	HX_DELETE(pRes);    }    p = m_ClosedResources.GetStartPosition();    while (p)    {	m_ClosedResources.GetNextAssoc(p, key, (void*&)pRes);	HX_DELETE(pRes);    }}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyRes::DiscardRange()////	Purpose:////		Discards the specified range of the file.////	Parameters:////		The location and length of the range to be discarded.////	Return:////		HX_RESULT//		Possible errors include: TBD.//HX_RESULT CChunkyRes::DiscardRange( ULONG32 offset, ULONG32 count ){    HX_RESULT theErr = HXR_OK;        // Big picture of this function is that it takes    // care of the end cases, where part of a chunk may    // be invalidated; then it totally removes all the    // chunks wholly contained by the range.        ULONG32 ulOffsetIntoChunk;        ULONG32 ulFirstChunk = offset/DEF_CHUNKYRES_CHUNK_SIZE;        ulOffsetIntoChunk = offset % DEF_CHUNKYRES_CHUNK_SIZE;        ULONG32 ulLastChunk  = (offset+count)/DEF_CHUNKYRES_CHUNK_SIZE;        if (ulFirstChunk == ulLastChunk)    {	// if the range is all in one chunk, deal with that simplest	// case and ignore the more complicated scenarios.		CChunkyResChunk* pChunk = (CChunkyResChunk*)m_Chunks[ulFirstChunk];		HX_ASSERT(pChunk);		pChunk->AddValidRange(ulOffsetIntoChunk, count, FALSE);		return theErr;    }        if (ulOffsetIntoChunk)    {        // OK, we have a chunk that needs to be partially invalidated.        	CChunkyResChunk* pChunk = (CChunkyResChunk*)m_Chunks[ulFirstChunk];		HX_ASSERT(pChunk);		pChunk->AddValidRange(ulOffsetIntoChunk, DEF_CHUNKYRES_CHUNK_SIZE - ulOffsetIntoChunk, FALSE);	        ulFirstChunk++;    }        ulOffsetIntoChunk = (offset+count) % DEF_CHUNKYRES_CHUNK_SIZE;    if (ulOffsetIntoChunk)    {        // OK, the final chunk needs to be partially invalidated.        	CChunkyResChunk* pChunk = (CChunkyResChunk*)m_Chunks[ulLastChunk];		HX_ASSERT(pChunk);		pChunk->AddValidRange(0, ulOffsetIntoChunk, FALSE);    }        for (ULONG32 ulWhichChunk = ulFirstChunk; ulWhichChunk < ulLastChunk; ulWhichChunk++)    {	CChunkyResChunk* pChunk = (CChunkyResChunk*)m_Chunks[ulWhichChunk];	// if the chunk doesn't (yet?) exist, then it's considered invalid.		if (pChunk)	{	    ULONG32 ulTempOffset = pChunk->GetTempFileOffset();	    if (ulTempOffset)	    {		m_FreeDiskOffsets.AddHead((void*)ulTempOffset);	    }	    	    delete pChunk;	    m_Chunks[ulWhichChunk] = NULL;	}    }        return theErr;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyRes::GetDiskUsage()////	Purpose:////		Returns the entire disk usage of a resource.////	Parameters:////		None.////	Return:////		ULONG32//		Total amount of diskspace the resource's chunks consume.//ULONG32 CChunkyRes::GetDiskUsage() const{	return (m_Chunks.GetSize() * DEF_CHUNKYRES_CHUNK_SIZE);}BOOL CChunkyRes::HasPartialData(ULONG32 length, ULONG32 offset /* = 0 */){	return (GetContiguousLength(offset) >= length);}ULONG32 CChunkyRes::GetContiguousLength(ULONG32 offset /* = 0 */){	ULONG32 contiguousLength = 0;	int ndx;	int startNdx = offset / DEF_CHUNKYRES_CHUNK_SIZE;	if (startNdx < m_Chunks.GetSize())	{		CChunkyResChunk* pChunk = (CChunkyResChunk*)m_Chunks[startNdx];				if (!pChunk) goto exit;				contiguousLength = pChunk->GetValidLength(offset % DEF_CHUNKYRES_CHUNK_SIZE);				if (contiguousLength != DEF_CHUNKYRES_CHUNK_SIZE - (offset % DEF_CHUNKYRES_CHUNK_SIZE))		{			goto exit;		}	}	startNdx++;		for (ndx = startNdx; ndx < m_Chunks.GetSize(); ndx++)	{		CChunkyResChunk* pChunk = (CChunkyResChunk*)m_Chunks[ndx];		// if there is no chunk then we are no longer contiguous.		if (!pChunk)		{			break;		}		ULONG32 chunkLength = pChunk->GetValidLength();		contiguousLength += chunkLength;		// if this chunk is not the max length then we are no longer contiguous		if (chunkLength < DEF_CHUNKYRES_CHUNK_SIZE)		{			break;		}	}exit:	return contiguousLength;}/////////////////////////////////////////////////////////////////////////////////	Method:////		CChunkyRes::GetData()////	Purpose:////		Gets a block of data out of a resource.////	Parameters:

⌨️ 快捷键说明

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