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

📄 clntxres.cpp

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

	//
	//	Return a 'C' string from the given ID.
	//
#define	STRINGTABLEMASK	0xFFF0
#define	STRINGENTRYMASK	0x000F

STDMETHODIMP_(IHXXResource*)
CHXXResFile::GetString	  (ULONG32	ID)
{
    HX_ASSERT(this);

    UINT16  wID = (UINT16)ID;
    
    UINT16  StringTableID = wID & STRINGTABLEMASK;
    StringTableID = StringTableID >> 4;		
    StringTableID++;

    UINT16  StringEntryID = wID & STRINGENTRYMASK;

    //
    //	Okay now after determining the string ID, we must
    //	actually load the data.
    //

    char*			StringTable = NULL; 
    char*			ResultString = NULL;
    char*			tempstring = NULL;
    IHXXResource*		OriginalStringTable = NULL;
    IHXXResource*		result = NULL;

    ULONG32			bufferlength = 0;
    HX_RESULT			rc = HXR_OK;
    UINT16			counter = 0;
    UINT16			len = 0;


    rc = GetResource(HX_RT_STRING,StringTableID,&OriginalStringTable);
	    
    if (rc != HXR_OK)
    {
	goto CleanUp;
    }
    
    HX_ASSERT(OriginalStringTable);

    StringTable=(char*)OriginalStringTable->ResourceData();
    
    //
    //	Okay now we have the String Table resource data. Let's parse it.
    //

    while (counter < StringEntryID)
    {
	UINT16  len = *((UINT16*)StringTable);
	ReverseWORD(len);

	//
	//	Jump past the length word.
	//
	StringTable += 2;
	
	HX_ASSERT(StringTable);

	//
	//	Jump ahead len * 2
	//

	StringTable += (2 * len);
	HX_ASSERT(StringTable);
	
	counter++;
    }

    //
    //	Okay we should now be at the string we wnat.
    //
    
    len = *((UINT16*)StringTable);
    ReverseWORD(len);
    
    if (!len)
    {
	goto CleanUp;
    }
    
    StringTable += 2;

    //
    //	Make buffer for holoding the string, add 2 bytes to make it long enough for two \0's
    //
    ResultString = new char[(len * 2) + 2];
    HX_ASSERT(ResultString);

    if (!ResultString)
    {
        return NULL;
    }

    memset(ResultString, 0, (len * 2) + 2);
    memcpy(ResultString, StringTable, (len * 2)); /* Flawfinder: ignore */

    //
    //	Okay turn the string into a normal ASCII string.
    //

    tempstring = new char[ (len+1) * 2];
    HX_ASSERT(tempstring);

    if (!tempstring)
    {
        goto CleanUp;
    }

#ifdef _WIN32
    WideCharToMultiByte(GetCodePage(),  0, (unsigned short*)ResultString, len+1, tempstring, (len+1) * 2, "", 0);
#else
    if (HXR_OK != ProcessFromUnicode((const char*)ResultString, len * 2, 
				    tempstring, len * 2))
    {
	delete [] ResultString;
	ResultString=NULL;

	delete [] tempstring;
	tempstring=NULL;

	goto CleanUp;
    }
#endif

    //
    //	Here we return the string that was output from the ProcessFromUnicode function.
    //
    delete [] ResultString;

    ResultString = tempstring;

    //
    //      We return it as an IHXXResource so that deletion happens correctly.
    //
    result = new CHXXResource(ResultString, strlen(ResultString)+1,
	    ID, HX_RT_STRING, OriginalStringTable->Language(), this);
    
    HX_ASSERT(result);
    
    if (result)
    {
	result->AddRef();
    }
    
    if (!result)
    {
	delete [] ResultString;
    }

CleanUp:
    
    if (OriginalStringTable)
    {
	OriginalStringTable->Release();
	OriginalStringTable=NULL;
	StringTable=NULL;
    }

    return result;

}

STDMETHODIMP_(IHXXResource*)
CHXXResFile::GetVersionInfo()
{
    IHXXResource* pRes = NULL;

    GetResource(HX_RT_VERSION, 1, &pRes);
    return pRes;
}


//
//	Return a "BITMAP" from the given ID.
//
	
STDMETHODIMP_(IHXXResource*)
CHXXResFile::GetBitmap	  (ULONG32	ID)
{
    IHXXResource*	result = NULL;
    
    HX_RESULT rc = GetResource(HX_RT_BITMAP, ID, &result);
    
    return result;
}


//
//	Return a "DIALOG" from the given ID.
//
STDMETHODIMP_(IHXXResource*)
CHXXResFile::GetDialog	  (ULONG32	ID)
{
    IHXXResource*	result = NULL;

    HX_RESULT rc = GetResource(HX_RT_DIALOG, ID, &result);
    
    return result;
}


//
//	This function removes extra resource data chunks, that are loaded
//	when a resource is loaded.
//
STDMETHODIMP_(HX_RESULT)
CHXXResFile::FlushCache(void)
{
    if (!mCacheList) 
    {
        return HXR_OK;
    }

    //
    //	Scan all entries looking for the matching type, and id. 
    //
    XResCacheEntry*	 curEntry = NULL;
    
    LISTPOSITION	 listpos = mCacheList->GetHeadPosition();
    
    while (listpos)
    {
        curEntry=(XResCacheEntry*) mCacheList->GetNext(listpos);
	if (curEntry->cached_data)
	{
	    delete [] curEntry->cached_data;
	    curEntry->cached_data = NULL;
	    curEntry->cached = FALSE;
	}
    }	
    /*
       This fixes a bug causing an infinite loop in the TrimCacheData
    */
    if (mLoadedCache)
    {
	listpos = mLoadedCache->GetHeadPosition();
    
	while (listpos)
	{		
	    curEntry = (XResCacheEntry*)mLoadedCache->GetAt(listpos);
	    curEntry->cached_data = NULL;
	    curEntry->cached = FALSE;
	    mLoadedCache->RemoveAt(listpos);
	
	    listpos = mLoadedCache->GetHeadPosition();
	}
    }
    return HXR_OK;
}


//
//	Sets the amount of memory that can be filled with cached resource data.
//

STDMETHODIMP_(HX_RESULT)
CHXXResFile::SetCacheLimit(ULONG32	MaxCachedData)  
{ 
    mMaxCachedData=MaxCachedData; 
    return HXR_OK;
};


//
//	Sets the Language ID of resources to be loaded.
//

STDMETHODIMP_(HX_RESULT) 
CHXXResFile::SetLanguage(ULONG32	id)
{
    //
    //	Eventually check a list and determine if the language is valid.
    //	

    mLanguageId=id;
    return HXR_OK;
}

STDMETHODIMP
CHXXResFile::UseResourceFile(INT16 nResourceFileRef)
{
    m_nResFileRef = nResourceFileRef;
    return HXR_OK;
}
		


//
//
//
//	SUPPORT METHODS
//
//


HX_RESULT	CHXXResFile::FindResourceData()
{
    HX_RESULT			rc = HXR_OK;
    ULONG32			size;
    ULONG32			pos;
    HX_IMAGE_SECTION_HEADER	sectionheader;

    rc = GetSectionHeaderNamed(".rsrc", sectionheader);
    if (rc != HXR_OK)
    {	
        return rc;
    }
    mResSectionVirtualAddress = sectionheader.VirtualAddress;

    //
    //	This actually moves us to the data portion of the section.
    //
    rc = FindSectionNamed(".rsrc",size,pos);
    
    if (rc != HXR_OK) 
    {
	return rc;
    }
    
    //
    //	Save the location of the ResourceData for a later time.
    //
    mResourceDataPosition = pos;

    return HXR_OK;
}





//
//	This function searches the resource tree, and caches the resource data.
//	This helps later, we basically just do a search of this cache and save
//	moocho time, instead of reading through the resource tree again.
//
//	Also if the resource had already been loaded, it's data may have been cached already
//	So we check this later, and return the cached data as well, instead of going back to 
//	disk.
//

HX_RESULT	CHXXResFile::CacheResourceEntries(void)
{
    if (mCacheList)
    {
	KillCache();
	delete mCacheList;
	mCacheList = NULL;
    }

    if (mLoadedCache)
    {
	delete mLoadedCache;
	mLoadedCache = NULL;
    }

    mCacheList = new CHXSimpleList();

    if (mCacheList == NULL)
    {
	return HXR_OUTOFMEMORY;
    }

    HX_RESULT	rc = HXR_OK;

    rc = ReadResourceHeader();
    if (rc != HXR_OK)
    {
	return rc;
    }


    rc = ReadInAllResources();

    if (rc != HXR_OK)
    {
	return rc;
    }

    return HXR_OK;
}

HX_RESULT	CHXXResFile::ReadResourceHeader(void)
{

    return GetResourceDirEntry(mResourceHeader);

}

//
//	This function is what actually does the resource reading.
//	Currently named resources are not being supported.
//
HX_RESULT	CHXXResFile::ReadInAllResources(void)
{
    // Skip ahead over the named resources.

    mFile->Seek(8*mResourceHeader.NumberOfNamedEntries,1);

    // Now read each of the tree branches for the entries left.

    ULONG32	 count=mResourceHeader.NumberOfIdEntries;
    ULONG32	 counter=0;

    for (counter=1; counter <= count; counter++)
    {
	HX_IMAGE_RESOURCE_DIRECTORY_ENTRY	   type;
	HX_IMAGE_RESOURCE_DIRECTORY_ENTRY	   id;
	HX_IMAGE_RESOURCE_DIRECTORY_ENTRY	   language;
	HX_IMAGE_RESOURCE_DATA_ENTRY		   data;

	ULONG32	    curtoplevelpos;
	ULONG32	    rootpos;

	//
	//	Get the top level directory entries. It is synonymous with type.
	//
	rootpos = mFile->Tell();
	GetResourceEntry(type);
	curtoplevelpos = mFile->Tell();
	type.OffsetToData = type.OffsetToData ^ 0x80000000;
	mFile->Seek(type.OffsetToData+mResourceDataPosition, 0);

	//
	//	Get teh second level directory.  It is synonymous with ID.
	//
	
	ULONG32	idoffset = mFile->Tell();
	
	HX_IMAGE_RESOURCE_DIRECTORY	 dir_id;
	
	GetResourceDirEntry(dir_id);

	//
	// scan all the entries in the id directory.
	//

	for (ULONG32 id_counter = 1; 
	    id_counter <= dir_id.NumberOfIdEntries; 
	    id_counter++)
	{
	    GetResourceEntry(id);	
	    ULONG32	 curIdPos = mFile->Tell();
	    
	    id.OffsetToData = id.OffsetToData ^ 0x80000000;
	    mFile->Seek(id.OffsetToData+mResourceDataPosition, 0);


	    //
	    //	Scan all the language entries for the given id.
	    //
	    HX_IMAGE_RESOURCE_DIRECTORY	  dir_language;

	    GetResourceDirEntry(dir_language);

	    for (ULONG32   lang_counter = 1; 
		lang_counter <= dir_language.NumberOfIdEntries; 
		lang_counter++)
	    {
		GetResourceEntry(language);
		ULONG32	 curLangPos = mFile->Tell();

		mFile->Seek(language.OffsetToData+mResourceDataPosition, 0);
		
		//
		//	Get the Data attributes for this file.
		//

		ReadDWord(data.OffsetToData);
		ReadDWord(data.Size);
		ReadDWord(data.CodePage);
		ReadDWord(data.Reserved);

		//
		//	The data offset is VIRTUAL. 
		//	However it is relative to the VIRTUAL address of the section 
		//	we are currently in.  This adjusts for that, giving us the physical location of the resource.
		//

		data.OffsetToData -= mResSectionVirtualAddress;

		//
		//	Okay cache the data. 
		//
		XResCacheEntry*	 newentry = new XResCacheEntry;
		
		HX_ASSERT_VALID_PTR(newentry);
		
		if (!newentry)
		{
    		    return HXR_OUTOFMEMORY;
		}

		memset(newentry, 0, sizeof(XResCacheEntry));

		newentry->type	    = type.Name;
		newentry->id	    = id.Name;
		newentry->language  = language.Name;
		newentry->size	    = data.Size + sizeof(kEndOfResourceMarker);
		newentry->location  = data.OffsetToData + mResourceDataPosition;


		//
		//	Add the entry to the cache for later.
		//
		mCacheList->AddTail(newentry);

		//
		//	Seek back to the next language directory entry.
		//
		mFile->Seek(curLangPos,0);
	    }

	    //
	    //	Seek back to the next ID directory entry
	    //
	    
	    mFile->Seek(curIdPos,0);

	}

	//
	//	Reset to the position in the file where the next resource branch starts.
	//

	mFile->Seek(curtoplevelpos,0);
    }

    return HXR_OK;
}


HX_RESULT	CHXXResFile::GetResourceEntry(HX_IMAGE_RESOURCE_DIRECTORY_ENTRY&		h)
{
    IF_ERROR_RETURN(ReadDWord(h.Name));
    IF_ERROR_RETURN(ReadDWord(h.OffsetToData));

    return HXR_OK;
}

⌨️ 快捷键说明

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