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

📄 unkimp.h

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
/* ***** 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 ***** */ 

//
//
//	Macro implementation of IUnknown
//
//  Description:
//	This file defines classes and Macro's to simplify the implementation 
//	of IUnknown in RMA objects.
//	It also implements object creation methods 
//	(CreateObject, CreateInstance)
//
//  Usage Tips:
//	
//	Never use the new operator to create a class instance!!
//	    Instead use CreateObject if you need to use non-interface
//	    methods and CreateInstance otherwise.
//
//  Class(es) Defined in this file:
//
//	CUnknownIMP
//	    The COM Object implementation must inherit from this class.
//
//	CAggregateImpl
//	    Used internally to support Aggregation.
//
//  Macros Defined in this file:
//
//	DECLARE_UNKNOWN(THIS_CLASS)
//	    This must be in the class declaration.
//
//	BEGIN_INTERFACE_LIST(THIS_CLASS)
//	    This must be in the class implementation.
//
//	END_INTERFACE_LIST
//	    This must be in the class implementation.
//
//	INTERFACE_LIST_ENTRY(INTERFACE_IID, INTERFACE_CLASS)
//	    Defines the QI of a locally implemented interface.
//	    Optional: if used must be in the class implementation.
//
//	INTERFACE_LIST_ENTRY2(DERIVED_CLASS, BASE_INTERFACE_IID, BASE_CLASS)
//	    Defines the QI of a locally implemented interface that must be 
//	    disambiguated. DERIVED_CLASS is the intermediate class used to 
//	    achieve the disambiguation.
//
//	INTERFACE_LIST_ENTRY_DELEGATE(INTERFACE_IID, DELEGATE_QI_FUNCTION)
//	    Defines the QI of a single interface supported by an aggregated 
//	    object.
//	    Optional: if used must be in the class implementation.
//
//	INTERFACE_LIST_ENTRY_DELEGATE_BLIND(DELEGATE_QI_FUNCTION)
//	    Defines the QI of all interfaces supported by an aggregated object.
//	    Optional: if used must be in the class implementation.
//
//	INTERFACE_LIST_ENTRY_BASE
//	    Specifies a base class whose query interface function should be called.
//
//  Example:
//
//  rmabuffer.h
//	#include <unkimp.h>
//
//	class CHXBuffer 
//	    : public CUnknownIMP
//	    , public IHXBuffer
//	{
//	    DECLARE_UNKNOWN(CHXBuffer)
//	public:
//	    STDMETHOD(FinalConstruct)();
//	    void FinalRelease();
//
//	    // List of IHXBuffer Methods..
//
//	private:
//	    // List of private members..
//	    DECLARE_SMART_POINTER_UNKNOWN m_spunkOther;
//	    DECLARE_SMART_POINTER_UNKNOWN m_spunkYetAnother;
//	};
//
//  rmabuffer.cpp
//	#include "rmabuffer.h"
//	
//	BEGIN_INTERFACE_LIST(CHXBuffer)
//	    INTERFACE_LIST_ENTRY(IID_IHXBuffer, IHXBuffer)
//	    INTERFACE_LIST_ENTRY_DELEGATE
//	    (
//		IID_IHXOther, 
//		m_spunkOther.QueryInterface
//	    )
//	    INTERFACE_LIST_ENTRY_DELEGATE_BLIND
//	    (
//		m_spunkYetAnother.QueryInterface
//	    )
//	END_INTERFACE_LIST
//
//	STDMETHODIMP CHXBuffer::FinalConstruct()
//	{
//	    // Create the Aggregated objects here..
//	    //
//	    if 
//	    (
//		SUCCEEDED
//		(
//		    CIHXOther::CreateInstance
//		    (
//			GetControllingUnknown(),
//			&m_spunkOther
//		    )
//		)
//		&&
//		SUCCEEDED
//		(
//		    CIHXYetAnother::CreateInstance
//		    (
//			GetControllingUnknown(),
//			&m_spunkYetAnother
//		    )
//		)
//	    )
//	    {
//		return HXR_OK;
//	    }
//	    return HXR_FAIL;
//	}
//
//	void CHXBuffer::FinalRelease()
//	{
//	    // If we were not using SmartPointers, we would 
//	    // release the Aggregated objects here.
//	}
//
//	// Implement IHXBuffer methods..
//  


#ifndef __CUnknownIMP_H__
#define __CUnknownIMP_H__

#include "hxcom.h"
#include "hxassert.h"

#ifdef INCLUDE_DEBUG_LIFETIME
#include <io.h>
#include <fcntl.h>
#include "chxdataf.h"
#include "hxtrace.h"
#include "hxstring.h"
#endif // INCLUDE_DEBUG_LIFETIME

#ifdef ENABLE_UNKIMP_TRACKER
#include "ihxiunknowntracker.h"
#endif

class CUnknownIMP : public IUnknown
{
public:
    CUnknownIMP() : m_lCount(0), m_punkOuter(NULL)
#ifdef INCLUDE_DEBUG_LIFETIME
    ,m_pRaFileDebugLifetime(NULL)
#endif

    {
	m_punkControlling = this;
    }
    virtual ~CUnknownIMP()
    {}

    /*
     *	IUnknown methods
     */
    STDMETHOD(QueryInterface)
    (
	THIS_
	REFIID riid,
	void** ppvObj
    )
    {
	if(m_punkOuter)
	{
	    return m_punkOuter->QueryInterface(riid, ppvObj);
	}
	return _ActualQI(riid, ppvObj);
    }

    STDMETHOD_(ULONG32,AddRef) (THIS)
    {
	if(m_punkOuter)
	{
	    return m_punkOuter->AddRef();
	}
	return ActualAddRef();
    }

    STDMETHOD_(ULONG32,Release) (THIS)
    {
	if(m_punkOuter)
	{
	    return m_punkOuter->Release();
	}
	return ActualRelease();
    }

    const IUnknown* GetUnknown() const
    {
	return this;
    }

    IUnknown* GetUnknown()
    {
	return this;
    }
    IUnknown* GetControllingUnknown()
    {
	return m_punkControlling;
    }

    STDMETHOD(SetupAggregation)( IUnknown* pvOuterObj, IUnknown** pvResult );
    
#ifdef ENABLE_UNKIMP_TRACKER
    static void SetIUnknownTracker( IHXIUnknownTracker* pIUnknownTracker )
    {
	if (pIUnknownTracker != ms_pIUnknownTracker)
	{
	    if (ms_pIUnknownTracker)
	    {
		IHXIUnknownTracker* pIOldUnknownTracker = ms_pIUnknownTracker;
		ms_pIUnknownTracker = NULL;
		HX_RELEASE(pIOldUnknownTracker);
	    }
	    if (pIUnknownTracker)
	    {
		pIUnknownTracker->AddRef();
		ms_pIUnknownTracker = pIUnknownTracker;
	    }
	}
    }
#endif

protected:
    // This is overriden in the derived object to provide
    // an object specific imp.
    STDMETHOD(_ActualQI)(REFIID riid, void** ppvObj) PURE;

#ifdef INCLUDE_DEBUG_LIFETIME

    CHXDataFile* m_pRaFileDebugLifetime;
    CHXString m_StringFilename;

    void InitFilename(const char* pFilename)
    {
	m_StringFilename = pFilename;
    }

    STDMETHOD_(ULONG32,ActualAddRef) ()
    {
	if (m_pRaFileDebugLifetime)
	{
	    char buf[80]; /* Flawfinder: ignore */
	    sprintf(buf, "*** AddRef %d ***\r\n", m_lCount+1); /* Flawfinder: ignore */
	    m_pRaFileDebugLifetime->Write(buf, strlen(buf));
	    UINT32* pBinaryStackTrace = NULL;
	    if (GetStack(&pBinaryStackTrace))
	    {
		char* pCharStackTrace = NULL;
		if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
		{
		    m_pRaFileDebugLifetime->Write
		    (
			pCharStackTrace,
			strlen(pCharStackTrace)
		    );
		}
		HX_VECTOR_DELETE(pCharStackTrace);
	    }
	    HX_VECTOR_DELETE(pBinaryStackTrace);
	}

	return InterlockedIncrement(&m_lCount);
    }
    STDMETHOD_(ULONG32,ActualRelease) ()
    {
	if (m_pRaFileDebugLifetime)
	{
	    char buf[80]; /* Flawfinder: ignore */
	    sprintf(buf, "*** Release %d ***\r\n", m_lCount-1); /* Flawfinder: ignore */
	    m_pRaFileDebugLifetime->Write(buf, strlen(buf));

	    UINT32* pBinaryStackTrace = NULL;

	    if (GetStack(&pBinaryStackTrace))
	    {
		char* pCharStackTrace = NULL;
	    	if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
		{
		    m_pRaFileDebugLifetime->Write
		    (
			pCharStackTrace,
			strlen(pCharStackTrace)
		    );
		}
		HX_VECTOR_DELETE(pCharStackTrace);
	    }
	    HX_VECTOR_DELETE(pBinaryStackTrace);
	}

	HX_ASSERT(m_lCount>0);

	if (InterlockedDecrement(&m_lCount) > 0)
	{
	    return m_lCount;
	}

	FinalRelease();
	delete this;
	return 0;
    }
    STDMETHOD(FinalConstruct)()
    {
	if (m_StringFilename.IsEmpty())
	{
	    return HXR_OK;
	}

	char szTemp[32]; /* Flawfinder: ignore */
	m_StringFilename.GetBuffer(0)[4] = '\0';
	m_StringFilename.ReleaseBuffer();
	ltoa((UINT32)this, szTemp, 16);
	m_StringFilename += szTemp;
	m_StringFilename.GetBuffer(0)[8] = '.';
	if (m_StringFilename.GetLength() > 12)
	{                           \
	    m_StringFilename.GetBuffer(0)[11] = '\0';
	    m_StringFilename.ReleaseBuffer();
	}                           \
	m_pRaFileDebugLifetime = CHXDataFile::Construct();
	m_pRaFileDebugLifetime->Open(m_StringFilename, _O_CREAT | _O_RDWR);
	m_pRaFileDebugLifetime->Write
	(
	    "*** Created new class instance ***\r\n",
	    sizeof("*** Created new class instance ***\r\n")
	);

	UINT32* pBinaryStackTrace = NULL;

	if (GetStack(&pBinaryStackTrace))
	{
	    char* pCharStackTrace = NULL;
	    if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
	    {
		m_pRaFileDebugLifetime->Write
		(
		    pCharStackTrace,
		    strlen(pCharStackTrace)
		);
	    }
	    HX_VECTOR_DELETE(pCharStackTrace);
	}

	HX_VECTOR_DELETE(pBinaryStackTrace);

	return HXR_OK;
    }
    virtual void FinalRelease()
    {
	if (m_pRaFileDebugLifetime)
	{
	    m_pRaFileDebugLifetime->Write("*** Deleted ***\r\n", 17);
	    UINT32* pBinaryStackTrace = NULL;
	    if (GetStack(&pBinaryStackTrace))
	    {
		char* pCharStackTrace = NULL;
		if (GetStackSymbols(pBinaryStackTrace, &pCharStackTrace))
		{
		    m_pRaFileDebugLifetime->Write
		    (
			pCharStackTrace,
			strlen(pCharStackTrace)
		    );
		}
	        HX_VECTOR_DELETE(pCharStackTrace);
	    }

	    HX_VECTOR_DELETE(pBinaryStackTrace);
	    m_pRaFileDebugLifetime->Close();
	}

	HX_DELETE(m_pRaFileDebugLifetime);
    }
#else
    // These can be overriden in the derived object to provide
    // an object specific imp.
    STDMETHOD_(ULONG32,ActualAddRef) (THIS)
    {
#ifdef ENABLE_UNKIMP_TRACKER
	ULONG32 postAddRefRefCount = InterlockedIncrement(&m_lCount);

⌨️ 快捷键说明

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