1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/unicode/icuplug.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,371 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* 1.7 +* Copyright (C) 2009-2012, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +****************************************************************************** 1.11 +* 1.12 +* FILE NAME : icuplug.h 1.13 +* 1.14 +* Date Name Description 1.15 +* 10/29/2009 sl New. 1.16 +****************************************************************************** 1.17 +*/ 1.18 + 1.19 +/** 1.20 + * \file 1.21 + * \brief C API: ICU Plugin API 1.22 + * 1.23 + * <h2>C API: ICU Plugin API</h2> 1.24 + * 1.25 + * <p>C API allowing run-time loadable modules that extend or modify ICU functionality.</p> 1.26 + * 1.27 + * <h3>Loading and Configuration</h3> 1.28 + * 1.29 + * <p>At ICU startup time, the environment variable "ICU_PLUGINS" will be 1.30 + * queried for a directory name. If it is not set, the preprocessor symbol 1.31 + * "DEFAULT_ICU_PLUGINS" will be checked for a default value.</p> 1.32 + * 1.33 + * <p>Within the above-named directory, the file "icuplugins##.txt" will be 1.34 + * opened, if present, where ## is the major+minor number of the currently 1.35 + * running ICU (such as, 44 for ICU 4.4, thus icuplugins44.txt)</p> 1.36 + * 1.37 + * <p>The configuration file has this format:</p> 1.38 + * 1.39 + * <ul> 1.40 + * <li>Hash (#) begins a comment line</li> 1.41 + * 1.42 + * <li>Non-comment lines have two or three components: 1.43 + * LIBRARYNAME ENTRYPOINT [ CONFIGURATION .. ]</li> 1.44 + * 1.45 + * <li>Tabs or spaces separate the three items.</li> 1.46 + * 1.47 + * <li>LIBRARYNAME is the name of a shared library, either a short name if 1.48 + * it is on the loader path, or a full pathname.</li> 1.49 + * 1.50 + * <li>ENTRYPOINT is the short (undecorated) symbol name of the plugin's 1.51 + * entrypoint, as above.</li> 1.52 + * 1.53 + * <li>CONFIGURATION is the entire rest of the line . It's passed as-is to 1.54 + * the plugin.</li> 1.55 + * </ul> 1.56 + * 1.57 + * <p>An example configuration file is, in its entirety:</p> 1.58 + * 1.59 + * \code 1.60 + * # this is icuplugins44.txt 1.61 + * testplug.dll myPlugin hello=world 1.62 + * \endcode 1.63 + * <p>Plugins are categorized as "high" or "low" level. Low level are those 1.64 + * which must be run BEFORE high level plugins, and before any operations 1.65 + * which cause ICU to be 'initialized'. If a plugin is low level but 1.66 + * causes ICU to allocate memory or become initialized, that plugin is said 1.67 + * to cause a 'level change'. </p> 1.68 + * 1.69 + * <p>At load time, ICU first queries all plugins to determine their level, 1.70 + * then loads all 'low' plugins first, and then loads all 'high' plugins. 1.71 + * Plugins are otherwise loaded in the order listed in the configuration file.</p> 1.72 + * 1.73 + * <h3>Implementing a Plugin</h3> 1.74 + * \code 1.75 + * U_CAPI UPlugTokenReturn U_EXPORT2 1.76 + * myPlugin (UPlugData *plug, UPlugReason reason, UErrorCode *status) { 1.77 + * if(reason==UPLUG_REASON_QUERY) { 1.78 + * uplug_setPlugName(plug, "Simple Plugin"); 1.79 + * uplug_setPlugLevel(plug, UPLUG_LEVEL_HIGH); 1.80 + * } else if(reason==UPLUG_REASON_LOAD) { 1.81 + * ... Set up some ICU things here.... 1.82 + * } else if(reason==UPLUG_REASON_UNLOAD) { 1.83 + * ... unload, clean up ... 1.84 + * } 1.85 + * return UPLUG_TOKEN; 1.86 + * } 1.87 + * \endcode 1.88 + * 1.89 + * <p>The UPlugData* is an opaque pointer to the plugin-specific data, and is 1.90 + * used in all other API calls.</p> 1.91 + * 1.92 + * <p>The API contract is:</p> 1.93 + * <ol><li>The plugin MUST always return UPLUG_TOKEN as a return value- to 1.94 + * indicate that it is a valid plugin.</li> 1.95 + * 1.96 + * <li>When the 'reason' parameter is set to UPLUG_REASON_QUERY, the 1.97 + * plugin MUST call uplug_setPlugLevel() to indicate whether it is a high 1.98 + * level or low level plugin.</li> 1.99 + * 1.100 + * <li>When the 'reason' parameter is UPLUG_REASON_QUERY, the plugin 1.101 + * SHOULD call uplug_setPlugName to indicate a human readable plugin name.</li></ol> 1.102 + * 1.103 + * 1.104 + * \internal ICU 4.4 Technology Preview 1.105 + */ 1.106 + 1.107 + 1.108 +#ifndef ICUPLUG_H 1.109 +#define ICUPLUG_H 1.110 + 1.111 +#include "unicode/utypes.h" 1.112 + 1.113 + 1.114 +/* === Basic types === */ 1.115 + 1.116 +#ifndef U_HIDE_INTERNAL_API 1.117 +/** 1.118 + * @{ 1.119 + * Opaque structure passed to/from a plugin. 1.120 + * use the APIs to access it. 1.121 + * @internal ICU 4.4 Technology Preview 1.122 + */ 1.123 + 1.124 +struct UPlugData; 1.125 +typedef struct UPlugData UPlugData; 1.126 + 1.127 +/** @} */ 1.128 + 1.129 +/** 1.130 + * Random Token to identify a valid ICU plugin. Plugins must return this 1.131 + * from the entrypoint. 1.132 + * @internal ICU 4.4 Technology Preview 1.133 + */ 1.134 +#define UPLUG_TOKEN 0x54762486 1.135 + 1.136 +/** 1.137 + * Max width of names, symbols, and configuration strings 1.138 + * @internal ICU 4.4 Technology Preview 1.139 + */ 1.140 +#define UPLUG_NAME_MAX 100 1.141 + 1.142 + 1.143 +/** 1.144 + * Return value from a plugin entrypoint. 1.145 + * Must always be set to UPLUG_TOKEN 1.146 + * @see UPLUG_TOKEN 1.147 + * @internal ICU 4.4 Technology Preview 1.148 + */ 1.149 +typedef uint32_t UPlugTokenReturn; 1.150 + 1.151 +/** 1.152 + * Reason code for the entrypoint's call 1.153 + * @internal ICU 4.4 Technology Preview 1.154 + */ 1.155 +typedef enum { 1.156 + UPLUG_REASON_QUERY = 0, /**< The plugin is being queried for info. **/ 1.157 + UPLUG_REASON_LOAD = 1, /**< The plugin is being loaded. **/ 1.158 + UPLUG_REASON_UNLOAD = 2, /**< The plugin is being unloaded. **/ 1.159 + UPLUG_REASON_COUNT /**< count of known reasons **/ 1.160 +} UPlugReason; 1.161 + 1.162 + 1.163 +/** 1.164 + * Level of plugin loading 1.165 + * INITIAL: UNKNOWN 1.166 + * QUERY: INVALID -> { LOW | HIGH } 1.167 + * ERR -> INVALID 1.168 + * @internal ICU 4.4 Technology Preview 1.169 + */ 1.170 +typedef enum { 1.171 + UPLUG_LEVEL_INVALID = 0, /**< The plugin is invalid, hasn't called uplug_setLevel, or can't load. **/ 1.172 + UPLUG_LEVEL_UNKNOWN = 1, /**< The plugin is waiting to be installed. **/ 1.173 + UPLUG_LEVEL_LOW = 2, /**< The plugin must be called before u_init completes **/ 1.174 + UPLUG_LEVEL_HIGH = 3, /**< The plugin can run at any time. **/ 1.175 + UPLUG_LEVEL_COUNT /**< count of known reasons **/ 1.176 +} UPlugLevel; 1.177 + 1.178 +/** 1.179 + * Entrypoint for an ICU plugin. 1.180 + * @param plug the UPlugData handle. 1.181 + * @param status the plugin's extended status code. 1.182 + * @return A valid plugin must return UPLUG_TOKEN 1.183 + * @internal ICU 4.4 Technology Preview 1.184 + */ 1.185 +typedef UPlugTokenReturn (U_EXPORT2 UPlugEntrypoint) ( 1.186 + UPlugData *plug, 1.187 + UPlugReason reason, 1.188 + UErrorCode *status); 1.189 + 1.190 +/* === Needed for Implementing === */ 1.191 + 1.192 +/** 1.193 + * Request that this plugin not be unloaded at cleanup time. 1.194 + * This is appropriate for plugins which cannot be cleaned up. 1.195 + * @see u_cleanup() 1.196 + * @param plug plugin 1.197 + * @param dontUnload set true if this plugin can't be unloaded 1.198 + * @internal ICU 4.4 Technology Preview 1.199 + */ 1.200 +U_INTERNAL void U_EXPORT2 1.201 +uplug_setPlugNoUnload(UPlugData *plug, UBool dontUnload); 1.202 + 1.203 +/** 1.204 + * Set the level of this plugin. 1.205 + * @param plug plugin data handle 1.206 + * @param level the level of this plugin 1.207 + * @internal ICU 4.4 Technology Preview 1.208 + */ 1.209 +U_INTERNAL void U_EXPORT2 1.210 +uplug_setPlugLevel(UPlugData *plug, UPlugLevel level); 1.211 + 1.212 +/** 1.213 + * Get the level of this plugin. 1.214 + * @param plug plugin data handle 1.215 + * @return the level of this plugin 1.216 + * @internal ICU 4.4 Technology Preview 1.217 + */ 1.218 +U_INTERNAL UPlugLevel U_EXPORT2 1.219 +uplug_getPlugLevel(UPlugData *plug); 1.220 + 1.221 +/** 1.222 + * Get the lowest level of plug which can currently load. 1.223 + * For example, if UPLUG_LEVEL_LOW is returned, then low level plugins may load 1.224 + * if UPLUG_LEVEL_HIGH is returned, then only high level plugins may load. 1.225 + * @return the lowest level of plug which can currently load 1.226 + * @internal ICU 4.4 Technology Preview 1.227 + */ 1.228 +U_INTERNAL UPlugLevel U_EXPORT2 1.229 +uplug_getCurrentLevel(void); 1.230 + 1.231 + 1.232 +/** 1.233 + * Get plug load status 1.234 + * @return The error code of this plugin's load attempt. 1.235 + * @internal ICU 4.4 Technology Preview 1.236 + */ 1.237 +U_INTERNAL UErrorCode U_EXPORT2 1.238 +uplug_getPlugLoadStatus(UPlugData *plug); 1.239 + 1.240 +/** 1.241 + * Set the human-readable name of this plugin. 1.242 + * @param plug plugin data handle 1.243 + * @param name the name of this plugin. The first UPLUG_NAME_MAX characters willi be copied into a new buffer. 1.244 + * @internal ICU 4.4 Technology Preview 1.245 + */ 1.246 +U_INTERNAL void U_EXPORT2 1.247 +uplug_setPlugName(UPlugData *plug, const char *name); 1.248 + 1.249 +/** 1.250 + * Get the human-readable name of this plugin. 1.251 + * @param plug plugin data handle 1.252 + * @return the name of this plugin 1.253 + * @internal ICU 4.4 Technology Preview 1.254 + */ 1.255 +U_INTERNAL const char * U_EXPORT2 1.256 +uplug_getPlugName(UPlugData *plug); 1.257 + 1.258 +/** 1.259 + * Return the symbol name for this plugin, if known. 1.260 + * @param plug plugin data handle 1.261 + * @return the symbol name, or NULL 1.262 + * @internal ICU 4.4 Technology Preview 1.263 + */ 1.264 +U_INTERNAL const char * U_EXPORT2 1.265 +uplug_getSymbolName(UPlugData *plug); 1.266 + 1.267 +/** 1.268 + * Return the library name for this plugin, if known. 1.269 + * @param plug plugin data handle 1.270 + * @param status error code 1.271 + * @return the library name, or NULL 1.272 + * @internal ICU 4.4 Technology Preview 1.273 + */ 1.274 +U_INTERNAL const char * U_EXPORT2 1.275 +uplug_getLibraryName(UPlugData *plug, UErrorCode *status); 1.276 + 1.277 +/** 1.278 + * Return the library used for this plugin, if known. 1.279 + * Plugins could use this to load data out of their 1.280 + * @param plug plugin data handle 1.281 + * @return the library, or NULL 1.282 + * @internal ICU 4.4 Technology Preview 1.283 + */ 1.284 +U_INTERNAL void * U_EXPORT2 1.285 +uplug_getLibrary(UPlugData *plug); 1.286 + 1.287 +/** 1.288 + * Return the plugin-specific context data. 1.289 + * @param plug plugin data handle 1.290 + * @return the context, or NULL if not set 1.291 + * @internal ICU 4.4 Technology Preview 1.292 + */ 1.293 +U_INTERNAL void * U_EXPORT2 1.294 +uplug_getContext(UPlugData *plug); 1.295 + 1.296 +/** 1.297 + * Set the plugin-specific context data. 1.298 + * @param plug plugin data handle 1.299 + * @param context new context to set 1.300 + * @internal ICU 4.4 Technology Preview 1.301 + */ 1.302 +U_INTERNAL void U_EXPORT2 1.303 +uplug_setContext(UPlugData *plug, void *context); 1.304 + 1.305 + 1.306 +/** 1.307 + * Get the configuration string, if available. 1.308 + * The string is in the platform default codepage. 1.309 + * @param plug plugin data handle 1.310 + * @return configuration string, or else null. 1.311 + * @internal ICU 4.4 Technology Preview 1.312 + */ 1.313 +U_INTERNAL const char * U_EXPORT2 1.314 +uplug_getConfiguration(UPlugData *plug); 1.315 + 1.316 +/** 1.317 + * Return all currently installed plugins, from newest to oldest 1.318 + * Usage Example: 1.319 + * \code 1.320 + * UPlugData *plug = NULL; 1.321 + * while(plug=uplug_nextPlug(plug)) { 1.322 + * ... do something with 'plug' ... 1.323 + * } 1.324 + * \endcode 1.325 + * Not thread safe- do not call while plugs are added or removed. 1.326 + * @param prior pass in 'NULL' to get the first (most recent) plug, 1.327 + * otherwise pass the value returned on a prior call to uplug_nextPlug 1.328 + * @return the next oldest plugin, or NULL if no more. 1.329 + * @internal ICU 4.4 Technology Preview 1.330 + */ 1.331 +U_INTERNAL UPlugData* U_EXPORT2 1.332 +uplug_nextPlug(UPlugData *prior); 1.333 + 1.334 +/** 1.335 + * Inject a plugin as if it were loaded from a library. 1.336 + * This is useful for testing plugins. 1.337 + * Note that it will have a 'NULL' library pointer associated 1.338 + * with it, and therefore no llibrary will be closed at cleanup time. 1.339 + * Low level plugins may not be able to load, as ordering can't be enforced. 1.340 + * @param entrypoint entrypoint to install 1.341 + * @param config user specified configuration string, if available, or NULL. 1.342 + * @param status error result 1.343 + * @return the new UPlugData associated with this plugin, or NULL if error. 1.344 + * @internal ICU 4.4 Technology Preview 1.345 + */ 1.346 +U_INTERNAL UPlugData* U_EXPORT2 1.347 +uplug_loadPlugFromEntrypoint(UPlugEntrypoint *entrypoint, const char *config, UErrorCode *status); 1.348 + 1.349 + 1.350 +/** 1.351 + * Inject a plugin from a library, as if the information came from a config file. 1.352 + * Low level plugins may not be able to load, and ordering can't be enforced. 1.353 + * @param libName DLL name to load 1.354 + * @param sym symbol of plugin (UPlugEntrypoint function) 1.355 + * @param config configuration string, or NULL 1.356 + * @param status error result 1.357 + * @return the new UPlugData associated with this plugin, or NULL if error. 1.358 + * @internal ICU 4.4 Technology Preview 1.359 + */ 1.360 +U_INTERNAL UPlugData* U_EXPORT2 1.361 +uplug_loadPlugFromLibrary(const char *libName, const char *sym, const char *config, UErrorCode *status); 1.362 + 1.363 +/** 1.364 + * Remove a plugin. 1.365 + * Will request the plugin to be unloaded, and close the library if needed 1.366 + * @param plug plugin handle to close 1.367 + * @param status error result 1.368 + * @internal ICU 4.4 Technology Preview 1.369 + */ 1.370 +U_INTERNAL void U_EXPORT2 1.371 +uplug_removePlug(UPlugData *plug, UErrorCode *status); 1.372 +#endif /* U_HIDE_INTERNAL_API */ 1.373 + 1.374 +#endif