networkprotocols/iphook/inhook6/include/apibase.h
changeset 0 af10295192d8
equal deleted inserted replaced
-1:000000000000 0:af10295192d8
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // apibase.h - Definitions for exporting APIs from TCP/IP stack to protocol hooks
       
    15 // Definitions for exporting APIs from TCP/IP stack to protocol hooks
       
    16 //
       
    17 
       
    18 
       
    19 
       
    20 /**
       
    21  @file apibase.h
       
    22  @publishedPartner
       
    23  @released
       
    24 */
       
    25 
       
    26 #ifndef __APIBASE_H__
       
    27 #define __APIBASE_H__
       
    28 
       
    29 #include "inet6err.h"
       
    30 
       
    31 /**
       
    32 * This interface class provides capability of introducing new interfaces for existing classes
       
    33 * in TCP/IP stack to be used by protocol hooks.
       
    34 * With this class, protocol hooks can query whether an interface is
       
    35 * supported and then use the interface. Backwards compatibility of revised interfaces is allowed by
       
    36 * versioning the interfaces. This enables independent developement of protocol hooks
       
    37 * and the TCP/IP stack while maintaining the compatibility towards older implementations.
       
    38 * This should be used as base class for all interface classes that are visible outside
       
    39 * the TCP/IP stack, or that should be prepared to export an API at some time to allow making
       
    40 * compatible modifications later on.
       
    41 *
       
    42 * There should be a constant definition of form KApiVer_<name> for each API that is exported that
       
    43 * identifies the version number of current API.
       
    44 *
       
    45 * @publishedPartner
       
    46 * @released
       
    47 */
       
    48 class MInetBase
       
    49 {
       
    50 public:
       
    51 	/**
       
    52 	* Returns a pointer to object that implements the requested API. If the the class that
       
    53 	* processes this call does not recognize the API name, it leaves with KErrNotFound.
       
    54 	* New versions
       
    55 	* of the same API should maintain binary backwards compatibility. That is, the caller
       
    56 	* requests a minimal accepted version, and if the implemented API is of the same version or
       
    57 	* higher, an object should be returned. If the implemented version is smaller than what
       
    58 	* requested, implementation of GetApiL leaves with KErrInetUnsupportedApi.
       
    59 	* If API is changed in a way that does not maintain backwards
       
    60 	* compatibility, a new API name should be allocated for it.
       
    61 	*
       
    62 	* Note: Callers should not use this method directly, but are strongly recommended to use
       
    63 	* IMPORT_API_L macro, which checks for type safety. Additionally, there is IMPORT_API_VER_L
       
    64 	* macro which can be used to explicitly request a known version and to return the actual
       
    65 	* version implemented.
       
    66 	*
       
    67 	* <em> For example: </em>
       
    68 	* @verbatim
       
    69 	* MEventService *es = IMPORT_API_L(NetworkService()->Interfacer(), MEventService);
       
    70 	* @endverbatim
       
    71 	*
       
    72 	* There should be MEventService header somewhere visible to the caller.
       
    73 	*
       
    74 	* @param aApiName API name that needs to be known by the implementator
       
    75 	* @param aVersion Requested minimum version. Later versions are also accepted by the caller.
       
    76 	*		  Overwritten by the actual version of the API when function returns,
       
    77 	*		  if matching API was found.
       
    78 	*
       
    79 	* @return Pointer to the object that implements the API. The method leaves with error if the
       
    80 	*	  instance could not be returned.
       
    81 	*
       
    82 	* @exception KErrInetUnsupportedApi Name of the API is not supported by the implementing class.
       
    83 	* @exception KErrInetUnsupportedApiVersion The given API is implemented, but the version is
       
    84 	*		  incompatible, i.e. older than requested.
       
    85 	*/
       
    86 	virtual void *GetApiL(const TDesC8& /*aApiName*/, TUint* /*aVersion*/)
       
    87 	      { User::Leave(KErrInetUnsupportedApi); return NULL; }
       
    88 
       
    89 	/**
       
    90 	* This is similar to GetApiL with returned version, but this function does not return the
       
    91 	* actual version implemented, so it can be used with constant parameters also.
       
    92 	*/
       
    93 	inline void *GetApiL(const TDesC8& aApiName, TUint aVersion)
       
    94 	      { return GetApiL(aApiName, &aVersion); }
       
    95 };
       
    96 
       
    97 
       
    98 /**
       
    99 * \def IMPORT_API_VER_L(base,api,version)
       
   100 * Returns the pointer to object that implements requested API. \a base is the class from which
       
   101 * the API is requested. \a api is the name of the virtual class that defines the API.
       
   102 * \a version is the minimum version that is requested. Later versions are required to be backwards
       
   103 * compatible, so the returned version number can be larger. See MInetBase description for more info.
       
   104 *
       
   105 * Note that IMPORT_API_VER_L does User::Leave, if the requested API was not available.
       
   106 */
       
   107 #define IMPORT_API_VER_L(base,api,version) (api *)base->GetApiL(_L8(#api), version)
       
   108 
       
   109 /**
       
   110 * \def IMPORT_API_L
       
   111 * Returns the pointer to object that implements requested API. Version is not given but it is
       
   112 * determined by looking for constant definition KApiVer_<name> in the header files that tells
       
   113 * the current version of the API.
       
   114 * \a base is the class from which the API is requested.
       
   115 * \a api is the name of the virtual class that defines the API. 
       
   116 */
       
   117 #define IMPORT_API_L(base,api) (api *)base->GetApiL(_L8(#api), KApiVer_##api);
       
   118 
       
   119 
       
   120 /**
       
   121 * This is a helper class for checking the API type safety for objects that provide an API.
       
   122 * The static class should not be used directly, but instead through EXPORT_API_L macro.
       
   123 *
       
   124 * @publishedPartner
       
   125 * @released
       
   126 */
       
   127 template<class T> class ApiChecker
       
   128 {
       
   129 public:
       
   130 	/**
       
   131 	* Returns an instance of the given API (template class T), if the current version is
       
   132 	* equal or above the version that was requested. New versions of the API
       
   133 	* are required to be (binary) backwards compatible. If version does not match, leaves with
       
   134 	* KErrInetUnsupportedApiVersion.
       
   135 	*
       
   136 	* @param aCurVersion  Current version of the API implementation
       
   137 	* @param aVersion     Version requested by the caller
       
   138 	* @param aInstance    API implementation that is returned if it is of valid version.
       
   139 	*/
       
   140 	static T* CheckVersionL(TUint aCurVersion, TUint *aVersion, T *aInstance);
       
   141 };
       
   142 
       
   143 template<class T> T* ApiChecker<T>::CheckVersionL(TUint aCurVersion,
       
   144 						  TUint *aVersion, T *aInstance)
       
   145 {
       
   146 	if (*aVersion > aCurVersion)
       
   147 	  {
       
   148 	    *aVersion = aCurVersion;
       
   149 	    User::Leave(KErrInetUnsupportedApiVersion);
       
   150 	  }
       
   151 	
       
   152 	*aVersion = aCurVersion;
       
   153 	return aInstance;
       
   154 }
       
   155 
       
   156 
       
   157 /**
       
   158 * \def EXPORT_API_L(api,instance,version)
       
   159 * To be used in MInetBase::GetApiL implementation for checking if an API and its version matches
       
   160 * the GetApiL request. Returns a pointer to API instance if the API matches.
       
   161 * Leaves with KErrInetUnsupportedApiVersion if the requested version is not supported,
       
   162 * i.e. its later than what is implemented.
       
   163 *
       
   164 * \a api is the class defining the API that is checked for. \a instance is the pointer that is
       
   165 * returned if API matches.
       
   166 * \a version is the minimum API version that is required. The actual version of API is
       
   167 * returned as output
       
   168 *
       
   169 * <em> Example of a GetApiL implementation: </em>
       
   170 * @verbatim
       
   171 * void *CIp6Manager::GetApiL(TDesC8 aApiName, TUint* aVersion)
       
   172 *	{
       
   173 *
       
   174 *	if (aApiName == _L8("MEventService"))
       
   175 *	    return EXPORT_API_L(MEventService, iEventManager, aVersion);
       
   176 *
       
   177 *	if (aApiName == _L8("MNetworkInfo"))
       
   178 *	    return EXPORT_API_L(MNetworkInfo, this, aVersion);
       
   179 *
       
   180 *	User::Leave(KErrNotFound);
       
   181 *	return NULL;
       
   182 *	}
       
   183 * @endverbatim
       
   184 */
       
   185 #define EXPORT_API_L(api,instance,version) \
       
   186 	ApiChecker<api>::CheckVersionL(KApiVer_##api, version, instance)
       
   187 
       
   188 #endif // __APIBASE_H__