I18N: Pnetlib Internationalization Framework Libary =================================================== Using the library ----------------- This library provides plug-in i18n module support for C# base class libraries such as pnetlib's "runtime". The base class library uses it as follows: - Load the "I18N.dll" assembly using "System.Reflection.Assembly.Load". - Obtain the value of the static "PrimaryManager" property within the "I18N.Common.Manager" class using "System.Reflection" facilities. - Invoke methods on the manager class to obtain i18n-sensitive objects such as "CultureInfo" and "Encoding" instances. - The "I18N.Common.Manager" class loads the requested i18n object and returns it to the base class library, which can then use it in the usual fashion. A more detailed example is given in a later section. I18N handlers ------------- Because there are so many i18n-sensitive cases to be handled, the culture information has been split across several region-specific assemblies: I18N.CJK.dll I18N.MidEast.dll I18N.Other.dll I18N.Rare.dll I18N.West.dll The "I18N.dll" assembly only loads those region-specific assemblies that it needs, based on the user's requests. I18N handlers within these assemblies use the naming convention "I18N.." where: The region handler. e.g. "West", "CJK", "India", etc. The prefix for the handler type. The identifier value which is supplied by the caller. e.g. a culture identifier, an encoding name, etc. The following prefixes are supported: CP Code page handler. e.g. "CP1252". ENC Web encoding handler. e.g. "ENCiso_8869_8". CID Culture, based on identifier. e.g. "CID2c01". CIDO Culture, based on identifier, with user overrides. e.g. "CIDO2c01". Falls back to the "CID" handler if no override handler. CN Culture, based on name. e.g. "CNar_jo". CNO Culture, based on name, with user overrides. e.g. "CNOar_jo". Falls back to the "CN" handler if no override handler. Handlers that are based on name will normalize the name to be in all lower case, with all instances of '-' replaced with '_'. The "I18N.dll" assembly knows which region assembly to load from the "I18N-handlers.def" file. This file is automatically generated during the build process and contains a list of all I18N handler classes. It must reside in the same directory as "I18N.dll". Example ------- As an example of the I18N loading process, we will describe what happens when code page 932 is requested: - The user's code calls "System.Text.Encoding.GetEncoding(932)". - The "Encoding" class loads "I18N.dll" using reflection. - The "Encoding" class accesses the "PrimaryManager" property via reflection to get an instance of "I18N.Common.Manager". - The "Encoding" class calls the "GetEncoding(int)" method on the "I18N.Common.Manager" instance using reflection. - "I18N.Common.Manager" constructs the name of the handler class - "CP932". - The file "I18N-handlers.def" is consulted to determine the full namespace and name of the "CP932" class - "I18N.CJK.CP932". - The region assembly "I18N.CJK.dll" is loaded using reflection. - An instance of the class "I18N.CJK.CP923" in the loaded assembly is constructed and returned to the caller. The results of previous requests are cached to smooth overall performance of the system. Dependencies ------------ This section describes the facilities that must be available from the base class library to make the I18N framework function. The framework makes heavy use of facilities from "System.Reflection" to load assemblies and to access their contents. String resources are assumed to be embedded as manifest string resources, based on tag names. The "I18N.Common.Strings" class takes care of the resource needs of all of the I18N assemblies. It relies upon a working implementation of "ResourceManager", that can load and process manifest string resources. It is assumed that the base class library contains its own implementation of the invariant culture. i.e. the invariant culture cannot be loaded dynamically. The "I18N.CJK.dll" assembly contains a single "InternalCall" method in the "I18N.CJK.CodeTable" class if the "__PNET__" symbol is defined when the assembly is compiled. This gives more efficient access to conversion CJK tables when running on the Portable.NET runtime engine. If the "__PNET__" symbol is not defined, then the implementation will fall back to a less efficient way of loading the tables. The method "System.Reflection.Assembly.GetFile(String)" is assumed to have slightly different semantics to the .NET Framework SDK. Normally, this method accesses a file that is listed in the assembly manifest. We have extended it so that it can also access files in the same directory as the assembly, even if not mentioned in the manifest. The altered semantics is necessary to access the "I18N-handlers.def" file, which defines which assembly contains which I18N handler. This file can be altered by third parties to install new handler assemblies. If the runtime engine does not implement the altered "GetFile" semantics, the library will fall back to an internal list that must be maintained internally and which cannot be dynamically extended by third parties. Security considerations ----------------------- The "GetAddress" and "GetFile" methods need to be implemented carefully to prevent arbitrary applications using them to circumvent system security.