|
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__ |