home *** CD-ROM | disk | FTP | other *** search
- /*
- *******************************************************************************
- * *
- * COPYRIGHT: *
- * IBM Open Class Library *
- * (C) Copyright Taligent, Inc., 1996 *
- * (C) Copyright International Business Machines Corporation, 1996-1998 *
- * Licensed Material - Program-Property of IBM - All Rights Reserved. *
- * US Government Users Restricted Rights - Use, duplication, or disclosure *
- * restricted by GSA ADP Schedule Contract with IBM Corp. *
- * *
- *******************************************************************************
- */
- // $Revision: 1.3 $
- //
- // Provides functionality for mapping between
- // LCID and Posix IDs.
- //
- // Note: All classes and code in this file are
- // intended for internal use only.
- //
- // Methods of interest:
- // void initializeMapRegions();
- // unsigned long convertToLCID(const int8_t*);
- // const int8_t* convertToPosix(unsigned long);
- //
- // Kathleen Wilson, 4/30/96
- //
- // Date Name Description
- // 3/11/97 aliu Fixed off-by-one bug in assignment operator. Added
- // setId() method and safety check against
- // MAX_ID_LENGTH.
- // 04/23/99 stephen Added C wrapper for convertToPosix.
-
-
- #include <math.h>
-
- #include "locmap.h"
- #include "locid.h"
- #include "mutex.h"
- #include "cmemory.h"
- #include "cstring.h"
-
- int32_t IGlobalLocales::fgLocaleCount = 0;
- uint32_t IGlobalLocales::fgStdLang = 0x0400;
- const uint32_t IGlobalLocales::kMapSize = 40;
- ILcidPosixMap* IGlobalLocales::fgPosixIDmap = 0;
-
- ////////////////////////////////////////////
- //
- // Create the table of LCID to POSIX Mapping
- //
- ////////////////////////////////////////////
-
-
- void
- IGlobalLocales::initializeMapRegions()
- {
-
- if (fgPosixIDmap != 0) // already mapped
- return;
-
-
- ILcidPosixMap *newPosixIDmap = new ILcidPosixMap[40];
- newPosixIDmap[0].initialize(0x0436, "af_ZA"); // 0
- newPosixIDmap[1].initialize(0x01, "ar", 16); // 1
- newPosixIDmap[2].initialize(0x0423, "be_BY"); // 2
- newPosixIDmap[3].initialize(0x0402, "bg_BG"); // 3
- newPosixIDmap[4].initialize(0x0403, "ca_ES"); // 4
- newPosixIDmap[5].initialize(0x0405, "cs_CS"); // 5
- newPosixIDmap[6].initialize(0x0406, "da_DK"); // 6
- newPosixIDmap[7].initialize(0x07, "de", 5); // 7
- newPosixIDmap[8].initialize(0x0408, "el_GR"); // 8
- newPosixIDmap[9].initialize(0x09, "en", 9); // 9
- newPosixIDmap[10].initialize(0x0a, "es", 16); // 10
- newPosixIDmap[11].initialize(0x0425, "et_EE"); // 11
- newPosixIDmap[12].initialize(0x042d, "eu_ES"); // 12
- newPosixIDmap[13].initialize(0x0429, "fa_IR"); // 13
- newPosixIDmap[14].initialize(0x040b, "fi_FI"); // 14
- newPosixIDmap[15].initialize(0x0c, "fr", 5); // 15
- newPosixIDmap[16].initialize(0x041a, "hr_HR"); // 16
- newPosixIDmap[17].initialize(0x040e, "hu_HU"); // 17
- newPosixIDmap[18].initialize(0x0421, "in_ID"); // 18
- newPosixIDmap[19].initialize(0x040f, "is_IS"); // 19
- newPosixIDmap[20].initialize(0x10, "it", 2); // 20
- newPosixIDmap[21].initialize(0x040d, "iw_IL"); // 21
- newPosixIDmap[22].initialize(0x0411, "ja_JP"); // 22
- newPosixIDmap[23].initialize(0x12, "ko", 2); // 23
- newPosixIDmap[24].initialize(0x0427, "lt_LT"); // 24
- newPosixIDmap[25].initialize(0x0426, "lv_LV"); // 25
- newPosixIDmap[26].initialize(0x13, "nl", 2); // 26
- newPosixIDmap[27].initialize(0x14, "no", 2); // 27
- newPosixIDmap[28].initialize(0x0415, "pl_PL"); // 28
- newPosixIDmap[29].initialize(0x16, "pt", 2); // 29
- newPosixIDmap[30].initialize(0x0418, "ro_RO"); // 30
- newPosixIDmap[31].initialize(0x0419, "ru_RU"); // 31
- newPosixIDmap[32].initialize(0x041b, "sk_SK"); // 32
- newPosixIDmap[33].initialize(0x0424, "sl_SI"); // 33
- newPosixIDmap[34].initialize(0x041c, "sq_AL"); // 34
- newPosixIDmap[35].initialize(0x041d, "sv_SE"); // 35
- newPosixIDmap[36].initialize(0x041e, "th_TH"); // 36
- newPosixIDmap[37].initialize(0x041f, "tr_TR"); // 37
- newPosixIDmap[38].initialize(0x0422, "uk_UA"); // 38
- newPosixIDmap[39].initialize(0x04, "zh", 4); // 39
- newPosixIDmap[1].addRegion(0x3801, "ar_AE");
- newPosixIDmap[1].addRegion(0x3c01, "ar_BH");
- newPosixIDmap[1].addRegion(0x1401, "ar_DZ");
- newPosixIDmap[1].addRegion(0x0c01, "ar_EG");
- newPosixIDmap[1].addRegion(0x0801, "ar_IQ");
- newPosixIDmap[1].addRegion(0x2c01, "ar_JO");
- newPosixIDmap[1].addRegion(0x3401, "ar_KW");
- newPosixIDmap[1].addRegion(0x3001, "ar_LB");
- newPosixIDmap[1].addRegion(0x1001, "ar_LY");
- newPosixIDmap[1].addRegion(0x1801, "ar_MA");
- newPosixIDmap[1].addRegion(0x2001, "ar_OM");
- newPosixIDmap[1].addRegion(0x4001, "ar_QA");
- newPosixIDmap[1].addRegion(0x0401, "ar_SA");
- newPosixIDmap[1].addRegion(0x2801, "ar_SY");
- newPosixIDmap[1].addRegion(0x1c01, "ar_TN");
- newPosixIDmap[1].addRegion(0x2401, "ar_YE");
-
- newPosixIDmap[7].addRegion(0x0c07, "de_AT");
- newPosixIDmap[7].addRegion(0x0807, "de_CH");
- newPosixIDmap[7].addRegion(0x0407, "de_DE");
- newPosixIDmap[7].addRegion(0x1407, "de_LI");
- newPosixIDmap[7].addRegion(0x1007, "de_LU");
-
- newPosixIDmap[9].addRegion(0x0c09, "en_AU");
- newPosixIDmap[9].addRegion(0x1009, "en_CA");
- newPosixIDmap[9].addRegion(0x0809, "en_GB");
- newPosixIDmap[9].addRegion(0x1809, "en_IE");
- newPosixIDmap[9].addRegion(0x2009, "en_JM");
- newPosixIDmap[9].addRegion(0x1409, "en_NZ");
- newPosixIDmap[9].addRegion(0x0409, "en_US");
- newPosixIDmap[9].addRegion(0x2409, "en_VI");
- newPosixIDmap[9].addRegion(0x1c09, "en_ZA");
-
- newPosixIDmap[10].addRegion(0x2c0a, "es_AR");
- newPosixIDmap[10].addRegion(0x400a, "es_BO");
- newPosixIDmap[10].addRegion(0x340a, "es_CL");
- newPosixIDmap[10].addRegion(0x240a, "es_CO");
- newPosixIDmap[10].addRegion(0x140a, "es_CR");
- newPosixIDmap[10].addRegion(0x1c0a, "es_DO");
- newPosixIDmap[10].addRegion(0x300a, "es_EC");
- newPosixIDmap[10].addRegion(0x0c0a, "es_ES");
- newPosixIDmap[10].addRegion(0x040a, "es_ES_T");
- newPosixIDmap[10].addRegion(0x100a, "es_GT");
- newPosixIDmap[10].addRegion(0x080a, "es_MX");
- newPosixIDmap[10].addRegion(0x180a, "es_PA");
- newPosixIDmap[10].addRegion(0x280a, "es_PE");
- newPosixIDmap[10].addRegion(0x3c0a, "es_PY");
- newPosixIDmap[10].addRegion(0x380a, "es_UY");
- newPosixIDmap[10].addRegion(0x200a, "es_VE");
-
- newPosixIDmap[15].addRegion(0x080c, "fr_BE");
- newPosixIDmap[15].addRegion(0x0c0c, "fr_CA");
- newPosixIDmap[15].addRegion(0x100c, "fr_CH");
- newPosixIDmap[15].addRegion(0x040c, "fr_FR");
- newPosixIDmap[15].addRegion(0x140c, "fr_LU");
-
- newPosixIDmap[20].addRegion(0x0810, "it_CH");
- newPosixIDmap[20].addRegion(0x0410, "it_IT");
-
- newPosixIDmap[23].addRegion(0x0812, "ko_KR");
- newPosixIDmap[23].addRegion(0x0412, "ko_KR");
-
- newPosixIDmap[26].addRegion(0x0813, "nl_BE");
- newPosixIDmap[26].addRegion(0x0413, "nl_NL");
-
- newPosixIDmap[27].addRegion(0x0414, "no_NO");
- newPosixIDmap[27].addRegion(0x0814, "no_NO_NY");
-
- newPosixIDmap[29].addRegion(0x0416, "pt_BR");
- newPosixIDmap[29].addRegion(0x0816, "pt_PT");
-
- newPosixIDmap[39].addRegion(0x0804, "zh_CN");
- newPosixIDmap[39].addRegion(0x0c04, "zh_HK");
- newPosixIDmap[39].addRegion(0x1004, "zh_SG");
- newPosixIDmap[39].addRegion(0x0404, "zh_TW");
-
- {
- Mutex m;
- if(fgPosixIDmap == 0)
- {
- fgPosixIDmap = newPosixIDmap;
- fgLocaleCount = 105;
- newPosixIDmap = 0; // successfully assigned it
- }
- }
-
- delete newPosixIDmap; // If it wasn't assigned. Don't delete these 40 inside a mutex.
- }
-
- //////////////////////////////////////
- //
- // LCID --> POSIX
- //
- /////////////////////////////////////
-
- const char*
- IGlobalLocales::convertToPosix(uint32_t hostid)
- {
- initializeMapRegions();
-
- uint16_t langID = languageLCID(hostid);
- uint32_t index;
- for (index = 0; index < kMapSize; index++)
- {
- if (langID == fgPosixIDmap[index].hostLangID())
- {
- return fgPosixIDmap[index].posixID(hostid);
- }
- }
-
- //no match found
- return ILcidPosixMap::fgWildCard;
- }
-
- U_CFUNC const char*
- T_convertToPosix(int32_t hostid)
- {
- return IGlobalLocales::convertToPosix(hostid);
- }
-
-
- //////////////////////////////////////
- //
- // POSIX --> LCID
- //
- /////////////////////////////////////
-
- uint32_t
- IGlobalLocales::convertToLCID(const char* posixID)
- {
- if (!posixID || strlen(posixID) < 2)
- return 0;
-
- initializeMapRegions();
-
- //Binary search for the map entry
-
- uint32_t low = 0, mid = 0;
- uint32_t high = kMapSize - 1;
-
- char langID[3];
- langID[0] = posixID[0];
- langID[1] = posixID[1];
- langID[2] = 0;
-
- while (low <= high) {
-
- mid = (low + high) / 2;
-
- int32_t compVal = icu_strcmp(langID, fgPosixIDmap[mid].posixLangID());
-
- if (mid == 0) // not found
- break;
- if (compVal < 0)
- high = mid - 1;
- else if (compVal > 0)
- low = mid + 1;
- else // found match!
- return fgPosixIDmap[mid].hostID(posixID);
- }
- // no match found
- return 0;
- }
-
- uint16_t
- IGlobalLocales::languageLCID(uint32_t hostID)
- {
- return (uint16_t)(0x00FF & hostID);
- }
-
- /////////////////////////////////////////////////////
- //
- // Given a hexadecimal number in decimal notation,
- // find the decimal notation for the two lowest bits.
- //
- // e.g. given 0x3456 return 0x56 in decimal notation.
- //
- /////////////////////////////////////////////////////
-
- ILcidPosixElement::ILcidPosixElement(uint32_t hid,
- const char* pid)
- {
- fHostID = hid;
- int32_t len = setId(pid);
-
- if (len == 2)
- {
- fPosixID[2] = '_';
- fPosixID[3] = '?';
- fPosixID[4] = '?';
- fPosixID[5] = 0;
- }
-
- }
-
- int32_t ILcidPosixElement::setId(const char* id)
- {
- int32_t len = strlen(id);
- if (len >= MAX_ID_LENGTH) len = MAX_ID_LENGTH - 1;
- int32_t index;
-
- for (index = 0; index < len; index++)
- {
- fPosixID[index] = id[index];
- }
- fPosixID[len] = 0; //null terminate
- return len;
- }
-
- ILcidPosixElement::ILcidPosixElement()
- {
- fHostID = 0;
- fPosixID[0] = 0;
- }
-
-
- ILcidPosixElement::ILcidPosixElement(const ILcidPosixElement& that)
- {
- fHostID = that.fHostID;
- setId(that.fPosixID);
- }
-
- ILcidPosixElement&
- ILcidPosixElement::operator=(const ILcidPosixElement& that)
- {
- if (this != &that)
- {
- fHostID = that.fHostID;
- setId(that.fPosixID);
- }
- return *this;
- }
-
-
- ILcidPosixElement::~ILcidPosixElement()
- {
- }
-
-
- const char* ILcidPosixMap::fgWildCard = "??_??";
-
- void
- ILcidPosixMap::initialize (uint32_t hostID,
- const char* posixID,
- uint32_t totalRegions)
- {
- fHostLangID = IGlobalLocales::languageLCID(hostID);
-
- fPosixLangID[0] = posixID[0]; // don't care about these being called twice. not critical.
- fPosixLangID[1] = posixID[1];
- fPosixLangID[2] = 0;
-
- fMapSize = totalRegions + 1;
- fNumRegions=0;
-
- fRegionMaps = new ILcidPosixElement[fMapSize];
-
- //The first element will always be wild card
- fRegionMaps[0] =
- ILcidPosixElement(fHostLangID, fPosixLangID);
-
- if (totalRegions == 1 && strlen(posixID) >= 5)
- {
- fNumRegions++;
-
- fRegionMaps[1] =
- ILcidPosixElement(hostID, posixID);
- }
- }
-
- //default constructor is private, cannot be used.
- ILcidPosixMap::ILcidPosixMap()
- {
- fHostLangID = 0;
- fPosixLangID[0] = '?';
- fPosixLangID[1] = '?';
- fPosixLangID[2] = 0;
-
- fRegionMaps = 0;
- fMapSize = 0;
- fNumRegions = 0;
- }
-
- //copy constructor is private, cannot be used.
- ILcidPosixMap::ILcidPosixMap(const ILcidPosixMap& that)
- {
- fHostLangID = that.fHostLangID;
- fPosixLangID[0] = that.fPosixLangID[0];
- fPosixLangID[1] = that.fPosixLangID[1];
- fPosixLangID[2] = 0;
-
- fRegionMaps = 0;
- fMapSize = 0;
- fNumRegions = 0;
- }
-
- //assignment operator is private, cannot be used.
- ILcidPosixMap&
- ILcidPosixMap::operator=(const ILcidPosixMap& that)
- {
- if (this != &that)
- {
- fHostLangID = that.fHostLangID;
- fPosixLangID[0] = that.fPosixLangID[0];
- fPosixLangID[1] = that.fPosixLangID[1];
- fPosixLangID[2] = 0;
-
- fRegionMaps = 0;
- fMapSize = 0;
- fNumRegions = 0;
- }
- return *this;
- }
-
- ILcidPosixMap::~ILcidPosixMap()
- {
- if (fMapSize)
- delete [] fRegionMaps;
- }
-
- void ILcidPosixMap::addRegion (uint32_t hostID,
- const char* posixID)
- {
- if (fMapSize && fNumRegions < (fMapSize - 1))
- {
- ILcidPosixElement save(hostID,posixID);
- fNumRegions++;
-
- fRegionMaps[fNumRegions] = save;
- }
- }
-
-
- //assumes Posix IDs are sorted alphabetically
- uint32_t
- ILcidPosixMap::hostID(const char* posixID) const
- {
- if (!fMapSize || strlen(posixID) < 5) //incomplete id
- return fHostLangID;
-
- //Binary search for the map entry
- //The element at index 0 is always the POSIX wild card,
- //so start search at index 1.
-
- uint32_t low = 1, mid = 1;
- uint32_t high = fNumRegions;
-
- while (low <= high) {
-
- mid = (low + high) / 2;
-
- int32_t compVal = icu_strcmp(posixID, fRegionMaps[mid].fPosixID);
-
- if (compVal < 0)
- high = mid - 1;
- else if (compVal > 0)
- low = mid + 1;
- else // found match!
- return fRegionMaps[mid].fHostID;
- }
-
- //no match found
- return fHostLangID;
- }
-
- const char*
- ILcidPosixMap::posixID(uint32_t hostID) const
- {
- uint32_t i;
- for (i = 0; i <= fNumRegions; i++)
- {
- if (fRegionMaps[i].fHostID == hostID)
- {
- return fRegionMaps[i].fPosixID;
- }
- }
-
- //if you get here, then no matching region was found,
- //so return the language id with the wild card region.
- return fRegionMaps[0].fPosixID;
- }
-
-