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

📄 clntxres.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 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 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (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.  
 *  
 * 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 "hxresult.h"
#include "hxassert.h"
#include "hxheap.h"
#include "hxslist.h"
#include "netbyte.h"
#include "hxstrutl.h"
#include "hxver.h"

#include "clntxres.ver"
#include "clntxres.h"
#include "hxmarsh.h"

#include "hlxclib/string.h"
#include "hlxclib/stdlib.h"

#ifdef _MACINTOSH
#pragma export on
#endif

#ifdef _AIX
#include "dllpath.h"
ENABLE_MULTILOAD_DLLACCESS_PATHS(Pnxres);
#endif

STDAPI HXCreateInstance(IUnknown**  /*OUT*/	ppIUnknown);
		
#ifdef _MACINTOSH
#pragma export off
#endif

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static const char HX_THIS_FILE[] = __FILE__;
#endif


/*
 * PNCreateInstance
 * -----------------
 * Entry point into this resource manager.
 * 
 * input:
 * IUnknown** ppIUnknown	- Pointer to mem where we store pointer to new ob.
 *
 * output:
 * STDAPI						
 * 
 */
STDAPI 
HXCreateInstance
(
    IUnknown**  /*OUT*/	ppIUnknown
)
{
    *ppIUnknown = (IUnknown*)(IHXPlugin*)new CHXXResFile;
    if (*ppIUnknown != NULL) 
    {
	(*ppIUnknown)->AddRef();
	return HXR_OK;
    }

    // Out of memory...
    return HXR_OUTOFMEMORY;
}

STDAPI ENTRYPOINT(CanUnload2)(void)
{
    return (CHXBaseCountingObject::ObjectsActive() > 0 ? HXR_FAIL : HXR_OK );
}



/*
 * QueryInterface
 * --------------
 * Used to get interfaces supported by us.
 *
 * input:
 * REFIID riid				- Id of interface.
 * void **ppvObj			- Place to copy interface pointer.
 *
 */
STDMETHODIMP 
CHXXResFile::QueryInterface
(
    REFIID riid, 
    void** ppvObj
)
{
    QInterfaceList qiList[] =
        {
            { GET_IIDHANDLE(IID_IHXXResFile), (IHXXResFile*)this },
            { GET_IIDHANDLE(IID_IHXPlugin), (IHXPlugin*)this },
            { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXXResFile*)this },
        };
    
    return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}




/* 
 * AddRef
 * ------
 * Increments the ref count by one.
 *
 * input:
 * void
 *
 * output:
 * ULONG32			- The count.
 *
 */
STDMETHODIMP_ (ULONG32) 
CHXXResFile::AddRef
(
    void
)
{
    return InterlockedIncrement(&m_lRefCount);
}





/*
 * Release
 * -------
 * Decrements the ref count by one, deleting 
 * self if count reaches zero.
 *
 * input:
 * void
 * 
 * output:
 * ULONG32			- Current ref count.
 *
 */
STDMETHODIMP_(ULONG32) 
CHXXResFile::Release
(
    void
)
{
    // Decrement, return count if possible.
    if (InterlockedDecrement(&m_lRefCount) > 0) return m_lRefCount; 

    // Else, delete self.
    delete this;
    return 0;
}



// IHXPlugin methods

/************************************************************************
 *  Method:
 *    IHXPlugin::InitPlugin
 *  Purpose:
 *    Initializes the plugin for use. This interface must always be
 *    called before any other method is called. This is primarily needed 
 *    so that the plugin can have access to the context for creation of
 *    IHXBuffers and IMalloc.
 */
STDMETHODIMP CHXXResFile::InitPlugin(IUnknown* /*IN*/ pContext)
{
    m_pContext = pContext;
    m_pContext->AddRef();

    m_pContext->QueryInterface(IID_IHXCommonClassFactory,
	    (void**)&m_pCommonClassFactory);

    return HXR_OK;
}

const char* const CHXXResFile::zm_pName		    = "PNXRes";
const char* const CHXXResFile::zm_pDescription	    = "External Resource File Reader";
const char* const CHXXResFile::zm_pCopyright	    = HXVER_COPYRIGHT;
const char* const CHXXResFile::zm_pMoreInfoURL	    = HXVER_MOREINFO;

/************************************************************************
 *  Method:
 *    IHXPlugin::GetPluginInfo
 *  Purpose:
 *    Returns the basic information about this plugin. Including:
 *
 *    bLoadMultiple	whether or not this plugin DLL can be loaded
 *			multiple times. All File Formats must set
 *			this value to TRUE.
 *    pDescription	which is used in about UIs (can be NULL)
 *    pCopyright	which is used in about UIs (can be NULL)
 *    pMoreInfoURL	which is used in about UIs (can be NULL)
 */
STDMETHODIMP CHXXResFile::GetPluginInfo
(
    REF(BOOL)        /*OUT*/ bLoadMultiple,
    REF(const char*) /*OUT*/ pDescription,
    REF(const char*) /*OUT*/ pCopyright,
    REF(const char*) /*OUT*/ pMoreInfoURL,
    REF(ULONG32)     /*OUT*/ ulVersionNumber
)
{
    bLoadMultiple = TRUE;   // Must be true for file formats.

    pDescription    = zm_pDescription;
    pCopyright	    = zm_pCopyright;
    pMoreInfoURL    = zm_pMoreInfoURL;
    ulVersionNumber = TARVER_ULONG32_VERSION;

    return HXR_OK;
}

CHXXResFile::CHXXResFile():
    mCacheList(NULL)
    ,mCachePos(0)
    ,mLanguageId(0x0409)    // default US English
    ,mMaxCachedData(kDefaultCacheLimit)
    ,mLoadedCache(NULL)
    ,m_lRefCount(0)
    ,m_pCommonClassFactory(NULL)
    ,m_pContext(NULL)
    ,m_nCodePage(0)
    ,m_nResFileRef(0)
{
}

CHXXResFile::~CHXXResFile()
{
    KillCache();

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

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

    HX_RELEASE(m_pCommonClassFactory);
    HX_RELEASE(m_pContext);
}


//
//	Open the specified file and read in all the data about where resources
//  are stored in the file.
//
STDMETHODIMP_(HX_RESULT)
CHXXResFile::Open(const char*  path)
{    
    HX_RESULT rc = CHXPeff::open(path);
    
    if (rc != HXR_OK) 
    {
	return rc;
    }

    //
    //	Read the data in the file header, and determine where to start reading from in the file.
    //	
    if(HXR_OK != FindResourceData())
    {
	return HXR_RESOURCE_NODATA;
    }
    
    CacheResourceEntries();

    return rc;
}

//
//	Close the file.
//
STDMETHODIMP_(HX_RESULT)
CHXXResFile::Close()
{
    CHXPeff::close();
    FlushCache();
    return HXR_OK;
}


//
//	Allow the resources to be accessed by type, and ID.
//

STDMETHODIMP_(HX_RESULT)	
CHXXResFile::GetResource	  (ULONG32	type, ULONG32  ID,  IHXXResource** resource)
{
    XResCacheEntry*	entry = NULL;
    HX_RESULT		rc = HXR_OK;	
    char*		buffer = NULL;
    HX_RESULT		err;
    CHXXResource* 	newresource;
    UCHAR*		data;
    ULONG32 		readsize;
    UCHAR*		tempdata;
    
    HX_ASSERT(resource);
    
    if (!resource)
    {
	return HXR_INVALID_PARAMETER;
    }
 
#ifdef _MACINTOSH
    INT16 nSavedResFile = 0;
    // if loading from resource fork, set current res file.
    if (m_nResFileRef)
    {
    	nSavedResFile = ::CurResFile();
    	::UseResFile(m_nResFileRef);
    }
#endif

    rc = FindInCache(type, ID, &entry);

    if (rc != HXR_OK)
    {
	err = HXR_RESOURCE_NOT_FOUND;
	goto Cleanup;
    }

    if (!mLoadedCache)
    {
	mLoadedCache = new CHXSimpleList();
    }

    HX_ASSERT(mLoadedCache);

    if (!mLoadedCache)
    {
	err = HXR_OUTOFMEMORY;
	goto Cleanup;
    }
    
    //
    //	We can't continue if the requested resource wasn't in the cache.
    //
    if (!entry)
    {
	err = HXR_FAIL;
	goto Cleanup;
    }
    
    //
    //	Okay new we need a buffer
    //
    
    buffer = new char[entry->size];
    
    if (!buffer)
    {
        err = HXR_OUTOFMEMORY;
	goto Cleanup;
    }
    
    newresource = 
	new CHXXResource(buffer, entry->size, entry->id,
			entry->type, entry->language,this);
    
    if (!newresource)
    {
	delete [] buffer;
	err = HXR_OUTOFMEMORY;
	goto Cleanup;
    }	

    *resource = newresource;
    newresource->AddRef();

    //
    //	Okay now check to see if the data for the resource was already cached.
    //
    //	If the data was cached already then return the pointer to the data already in memory.
    //

    if (entry->cached == TRUE)
    {
	if (entry->cached_data == NULL)
	{
	    err = HXR_RESOURCE_NODATA;
	    goto Cleanup;
	}

	//
	//	BUFFER
	//
	memcpy(buffer, entry->cached_data, entry->size); /* Flawfinder: ignore */
	err = HXR_OK;
	goto Cleanup;
    }

    
    //
    //	If we got here, we need to load the resource from the file.
    //

    if (!entry->location)
    {
	delete newresource;
	err = HXR_RESOURCE_NODATA;
	goto Cleanup;
    }


    //
    //	Seek to the resource's physical location in the file.
    //
    rc = mFile->Seek(entry->location, 0);

    if (rc != HXR_OK)
    {
        delete newresource;
        err = rc;
	goto Cleanup;
    }

    //
    //	Allocate a buffer to load the data into.
    //
    data = new UCHAR[entry->size];
    HX_ASSERT(data);
    if (!data)
    {
        delete newresource;
        err = HXR_OUTOFMEMORY;
	goto Cleanup;
    }

    //
    //	Okay read in the data.
    //

    readsize = mFile->Read((char*)data, entry->size);
    if (readsize != entry->size)
    {
	delete newresource;
	err = HXR_AT_END;
	goto Cleanup;
    }
    
    //
    //	Copy in the end of resource marker.
    //
    //	This is used in certain resources to detect the end of the resource data.
    //	This makes it easy for us to just pass around one ptr, instead of having to 
    //	otherwise pass the length around to the processing functions.
    //
    
    tempdata = data;
    
    tempdata = data + entry->size;
    tempdata -= sizeof(kEndOfResourceMarker);
    if(TestBigEndian())
    {
	putlong(tempdata,kEndOfResourceMarker);
    }
    else
    {
	(*(ULONG32*)tempdata)=kEndOfResourceMarker;
    }	

    //
    //	Trim the Cached Data now so we don't delete the data we loaded
    //	for the cached entry.
    //
    TrimCachedData(entry->size);


    //
    //	Setup the cached entry.
    //	Setup the data that we return.
    //
    entry->cached = TRUE;
    entry->cached_data = data;

    

    mLoadedCache->AddHead(entry);
    memcpy(buffer, data, entry->size); /* Flawfinder: ignore */
    err = HXR_OK;
    
Cleanup:
    //
    //	Okay we got here, no errors.
    //
#ifdef _MACINTOSH
    if (nSavedResFile)
    {
    	::UseResFile(nSavedResFile);
    }
#endif

    return err;
}



	//
	//	HIGH LEVEL FUNCTIONS
	//

⌨️ 快捷键说明

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