Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



InterfaceDefinition: interface definition example code


Example code

Found in: examples\SysLibs\ECom\InterfaceDefinition\

//
// Interface.h
// Copyright © 1997-2001 Symbian Ltd. All rights reserved.
//

#ifndef _CEXAMPLEINTERFACE__
#define _CEXAMPLEINTERFACE__

#include <e32base.h>
#include <ECom.h>
#include <badesca.h>

// UID of this interface
const TUid KCExampleInterfaceUid = {0x10009DC0};

/**
    An example abstract class being representative of the
    concrete class which the client wishes to use.

    It acts as a base, for a real class to provide all the 
    functionality that a client requires.  
    It supplies instantiation & destruction by using
    the ECom framework, and functional services
    by using the methods of the actual class.
 */
class CExampleInterface : public CBase
    {
public:
    // The interface for passing initialisation parameters
    // to the derived class constructor.
    struct TExampleInterfaceInitParams
        {
        TInt integer;
        const TDesC* descriptor;
        };

    // Instantiates an object of this type 
    static CExampleInterface* NewL();

    // Instantiates an object of this type 
    // using the aMatchString as the resolver parameters.
    static CExampleInterface* NewL(const TDesC8& aMatchString);

    // Instantiates an object of this type
    // using the aMatchString as the resolver parameters
    // and passing the aParams parameters 
    static CExampleInterface* NewL(const TDesC8& aMatchString, TExampleInterfaceInitParams& aParams);

    // Destructor.
    virtual ~CExampleInterface();

    // Request a list of all available implementations which 
    // satisfy this given interface.
    static void ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray);

    // Pure interface method
    // Representative of a method provided on the interface by 
    // the interface definer.
    virtual void DoMethodL(TDes& aString) = 0;

protected:
    //Default c'tor
    inline CExampleInterface();

private:
    // Unique instance identifier key
    TUid iDtor_ID_Key;
    };

#include "Interface.inl"

#endif 

//
// Interface.inl
// Copyright © 1997-2001 Symbian Ltd. All rights reserved.
//

// Set default to be first implementation found by resolver
_LIT8(KDefaultImplementation,"*");

inline CExampleInterface::CExampleInterface()
    {
    }

inline CExampleInterface::~CExampleInterface()
    {
    // Destroy any instance variables and then
    // inform the framework that this specific 
    // instance of the interface has been destroyed.
    REComSession::DestroyedImplementation(iDtor_ID_Key);
    }

inline CExampleInterface* CExampleInterface::NewL()
    {
    // Set up the interface find for the default resolver.
    TEComResolverParams resolverParams;
    resolverParams.SetDataType(KDefaultImplementation());
    resolverParams.SetWildcardMatch(ETrue);     // Allow wildcard matching

    // Set up some empty initialisation parameters
    TExampleInterfaceInitParams initParams;
    initParams.integer      = 0;
    initParams.descriptor   = NULL;

    const TUid KExResolverUid = {0x10009DD0};
    return REINTERPRET_CAST(CExampleInterface*, 
                            REComSession::CreateImplementationL(KCExampleInterfaceUid, 
                                                               _FOFF(CExampleInterface,iDtor_ID_Key),
                                                               &initParams,
                                                               resolverParams,
                                                               KExResolverUid));
    }

inline CExampleInterface* CExampleInterface::NewL(const TDesC8& aMatchString)
    {
    // Set up the interface find for the default resolver.
    TEComResolverParams resolverParams;
    resolverParams.SetDataType(aMatchString);
    resolverParams.SetWildcardMatch(ETrue);     // Allow wildcard matching

    // Set up some empty initialisation parameters
    TExampleInterfaceInitParams initParams;
    initParams.integer      = 0;
    initParams.descriptor   = NULL;

    return REINTERPRET_CAST(CExampleInterface*, 
                            REComSession::CreateImplementationL(KCExampleInterfaceUid, 
                                                               _FOFF(CExampleInterface,iDtor_ID_Key), 
                                                               &initParams,
                                                               resolverParams));
    }

inline CExampleInterface* CExampleInterface::NewL(const TDesC8& aMatchString, TExampleInterfaceInitParams& aParams)
    {
    // Set up the interface find for the default resolver.
    TEComResolverParams resolverParams;
    resolverParams.SetDataType(aMatchString);
    resolverParams.SetWildcardMatch(ETrue);     // Allow wildcard matching

    // The CreateImplementationL method will return
    // the created item.
    return REINTERPRET_CAST(CExampleInterface*, REComSession::CreateImplementationL(KCExampleInterfaceUid,
                                                _FOFF(CExampleInterface,iDtor_ID_Key),
                                                &aParams,
                                                resolverParams));
    }

inline void CExampleInterface::ListAllImplementationsL(RImplInfoPtrArray& aImplInfoArray)
    {
    REComSession::ListImplementationsL(KCExampleInterfaceUid, aImplInfoArray);
    }

//
// ExampleResolver.h
// Copyright © 2001 Symbian Ltd. All rights reserved.
//

#ifndef __EXAMPLERESOLVER_H__
#define __EXAMPLERESOLVER_H__

#include <Resolver.h>
#include <PublicRegistry.h>

class TEComResolverParams;

// Example resolver's UID
const TUid KExResolverUid = {0x10009DD0};

/**
    Implements a non-default resolver.

    This controls the identification, (resolution), of which implementation 
    will be used to satisfy an interface implementation instantiation.
 */
class CExampleResolver : public CResolver
    {
public:
    // Factory function: 
    static CExampleResolver* NewL(MPublicRegistry & aRegistry);
    ~CExampleResolver();

    /**
    Request that the resolver identify the most appropriate interface implementation.
    @param          aInterfaceUid The interface for which implementations are requested
    @param          aAdditionalParameters Data to be used to refine the search further
    @return         The Uid of the best fit interface implementation - KNullUid if no match is found
    */
    TUid IdentifyImplementationL(TUid aInterfaceUid, 
        const TEComResolverParams& aAdditionalParameters) const;

    /**
    List all the implementations which satisfy the specified interface.
    @param          aInterfaceUid The interface for which implementations are requested
    @param          aAdditionalParameters Data to be used to refine the search further
    @return         Pointer to an array of suitable implementations. Ownership of this array
    is passed to the calling function.
    */
    RImplInfoArray* ListAllL(TUid aInterfaceUid, 
        const TEComResolverParams& aAdditionalParameters) const;

private:
    // Ctor
    explicit CExampleResolver(MPublicRegistry& aRegistry);

    /**
    Called by IdentifyImplementationL to select an appropriate implementation from a list of possibles
    @param          aImplementationsInfo Information on the potential implementations
    @param          aAdditionalParameters The data to match against to detemine the 
                    implementation
    @return         The Uid of the selected implementation - KNullUid if no match is found
 */
    TUid Resolve(const RImplInfoArray& aImplementationsInfo, 
                 const TEComResolverParams& aAdditionalParameters) const;

/**
    Searches for a match of a data type on an implementation type.
    Match returns ETrue if aMatchType is found within aImplementationType according to 
    the following rules:
    1) aImplementationType is treated as a series of descriptors separated by double 
    bars (||). ETrue is returned if aMatchType matches exactly any of the short 
    descriptors.  If no double bar is present then aImplementationType is treated as a
    single descriptor.
    2) If aUseWildcards == ETrue then a '?' in aMatchType will be matched to any single
    character and '*' will be matched to any series of characters.

    @param          aImplementationType The implementation data type to search for a match
    @param          aMatchType The data to search for
    @param          aUseWildcards ETrue if wildcard matching should be allowed
    @return         ETrue if a match was found, EFalse otherwise
 */
    TBool Match(const TDesC8& aImplementationType, 
                const TDesC8& aMatchType, 
                TBool aUseWildcards) const;

private:
    mutable RImplInfoArray* iImplementationInfoArray;
    };

#endif // __EXAMPLERESOLVER_H__

//
// ExampleResolver.cpp
// Copyright © 1997-2001 Symbian Ltd. All rights reserved.
//


#include <ECom.h>
#include <EComErrorCodes.h>
#include <EComResolverParams.h>
#include <ImplementationInformation.h>
#include <PublicRegistry.h>

#include "ExampleResolver.h"

CExampleResolver* CExampleResolver::NewL(MPublicRegistry& aRegistry)
    {
    return new(ELeave) CExampleResolver(aRegistry);
    }

CExampleResolver::~CExampleResolver()
    {
    if(iImplementationInfoArray)
        {
        iImplementationInfoArray->Reset();
        delete iImplementationInfoArray;
        }
    }

CExampleResolver::CExampleResolver(MPublicRegistry& aRegistry)
: CResolver(aRegistry)
    {
    // Do nothing here
    }

TUid CExampleResolver::IdentifyImplementationL(TUid aInterfaceUid, 
    const TEComResolverParams& aAdditionalParameters) const
    {
    RImplInfoArray& implementationsInfo = iRegistry.ListImplementationsL(aInterfaceUid);
    TUid found = KNullUid;
    if(implementationsInfo.Count())
        {
        found = Resolve(implementationsInfo, aAdditionalParameters);
        }
    return found;
    }

TUid CExampleResolver::Resolve(const RImplInfoArray& aImplementationsInfo, 
    const TEComResolverParams& aAdditionalParameters) const
    {
    // Loop through the implementations matching on type
    const TInt count = aImplementationsInfo.Count();
    for(TInt index = 0; index < count; ++index)
        {
        const CImplementationInformation& impData = *aImplementationsInfo[index];
        // As soon as we get a match on the datatype then return uid of the 
        // implementation found.
        if (Match(impData.DataType(),                      // The Datatype of this implementation
                  aAdditionalParameters.DataType(),           // The type we are trying to find
                  aAdditionalParameters.IsWildcardMatch()))   // If wildcards should be used
            return impData.ImplementationUid();
        }

    return KNullUid;
    }

RImplInfoArray* CExampleResolver::ListAllL(TUid aInterfaceUid, 
    const TEComResolverParams& aAdditionalParameters) const
    {
    // Use the member var to create the array so that we get proper cleanup behaviour
    iImplementationInfoArray = new(ELeave) RImplInfoArray;
    RImplInfoArray* retList = iImplementationInfoArray;

    RImplInfoArray& fullList = iRegistry.ListImplementationsL(aInterfaceUid);

    const TBool useWildcards = aAdditionalParameters.IsWildcardMatch();
    const TDesC8& matchType = aAdditionalParameters.DataType();
    const TInt numImps = fullList.Count();
    for(TInt index = 0; index < numImps; ++index)
        {
        if(Match(fullList[index]->DataType(), matchType, useWildcards))
            {
            User::LeaveIfError(retList->Append(fullList[index]));
            }
        }

    // Reset the member variable because we are passing ownership back
    iImplementationInfoArray = NULL;
    return retList;
    }

TBool CExampleResolver::Match(const TDesC8& aImplementationType, 
    const TDesC8& aMatchType, 
    TBool aUseWildcards) const
    {
    TInt matchPos = KErrNotFound;

    _LIT8(dataSeparator, "||");
    const TInt separatorLength = dataSeparator().Length();

    // Look for the section separator marker '||'
    TInt separatorPos = aImplementationType.Find(dataSeparator);
    if(separatorPos == KErrNotFound)
        {
        // Match against the whole string
        if(aUseWildcards)
            matchPos = aImplementationType.Match(aMatchType);
        else
            matchPos = aImplementationType.Compare(aMatchType);
        }
    else
        {
        // Find the first section, up to the separator
        TPtrC8 dataSection = aImplementationType.Left(separatorPos);
        TPtrC8 remainingData = aImplementationType.Mid(separatorPos + separatorLength);
        // Match against each section in turn
        while(separatorPos != KErrNotFound)
            {
            // Search this section
            if(aUseWildcards)
                matchPos = dataSection.Match(aMatchType);
            else
                matchPos = dataSection.Compare(aMatchType);

            // If we found it then no need to continue, so return
            if(matchPos != KErrNotFound)
                return ETrue;

            // Move on to the next section
            separatorPos = remainingData.Find(dataSeparator);
            if(separatorPos != KErrNotFound)
                {
                dataSection.Set(remainingData.Left(separatorPos));
                remainingData.Set(remainingData.Mid(separatorPos + separatorLength));
                }
            else
                dataSection.Set(remainingData);
            }

        // Check the final part
        if(aUseWildcards)
            matchPos = dataSection.Match(aMatchType);
        else
            matchPos = dataSection.Compare(aMatchType);

        }
    return matchPos != KErrNotFound;
    }

// 100098ea.RSS
//
// Copyright (c) 1997-2001 Symbian Ltd.  All rights reserved.
//

#include "RegistryInfo.rh"

// Declares the interface implementation provided: a custom resolver
RESOURCE REGISTRY_INFO theInfo
    {
    dll_uid = 0x100098ea;
    interfaces = 
        {
        INTERFACE_INFO
            {
            // Interface UID of resolvers
            interface_uid = 0x10009D90;
            implementations = 
                {
                IMPLEMENTATION_INFO
                    {
                    implementation_uid = 0x10009DD0;
                    version_no = 1;
                    display_name = "";
                    default_data = "";
                    opaque_data = "";
                    }
                };
            }
        };
    }

//
// Proxy.cpp
// Copyright © 1997-2001 Symbian Ltd. All rights reserved.
//

#include <e32std.h>
#include <ImplementationProxy.h>

#include "ExampleResolver.h"


// Map the interface UIDs
const TImplementationProxy ImplementationTable[] = 
    {
        IMPLEMENTATION_PROXY_ENTRY(0x10009DD0,  CExampleResolver::NewL)
    };

// Exported proxy for instantiation method resolution
EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
    {
    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);

    return ImplementationTable;
    }

// InterfaceDefinition.mmp
//
// Copyright (c) 2001 Symbian Ltd.  All rights reserved.
//

TARGET ExampleResolver.dll
TARGETTYPE PLUGIN

// ECom Dll recognition UID followed by the unique UID for this dll
UID 0x10009D8D 0x100098ea
VENDORID 0x70000001
CAPABILITY All -TCB

SOURCEPATH  .
SOURCE      main.cpp
SOURCE      Proxy.cpp
SOURCE      ExampleResolver.cpp

USERINCLUDE    .
SYSTEMINCLUDE  \epoc32\include 
SYSTEMINCLUDE  \epoc32\include\ecom

start resource 100098ea.rss
TARGET ExampleResolver.rsc
end

LIBRARY euser.lib

[Top]


Description

InterfaceDefinition provides an example ECom interface definition. It declares a base class, CExampleInterface, from which implementations of the interface should derive.

CExampleInterface provides three NewL() functions that allow clients to get respectively:

CExampleInterface uses the overloads of REComSession::CreateImplementation() to implement these functions.

CExampleInterface declares one pure virtual function, DoMethodL(), which supplies a service to the client. Implementations must implement this function.

InterfaceDefinition also provides an example of a custom resolver, called CExampleResolver. Its behaviour is the same as ECom's default resolver. Because a resolver is an implementation of the ECom CResolver interface, it requires a registration resource file (100098ea.rss), and an exported factory table (Proxy.cpp).

[Top]


Usage

Building InterfaceDefinition exports the files that contain the interface definition, Interface.h and Interface.inl, to epoc32\include\; produces a DLL ExampleResolver.dll; and compiles a resource file ExampleResolver.rsc in the \resource\plugins\ directory.

Implementations of the interface are provided in the InterfaceImplementation example.

A client program that accesses the interface is provided in the InterfaceClient example.

[Top]


Classes used