/* ******************************************************************************* * * Copyright (C) 2000-2004, X.Net, Inc. Lafayette, California, USA * All Rights Reserved. * * Open source license http://www.opensource.org/licenses/xnet.html * * This product includes software developed by * International Business Machines Corporation and others * for use in ICU (http://oss.software.ibm.com/icu/). * * This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/). * ******************************************************************************* * * mod_xiua.c: * Implements APIs for the Apache use of ICU * Modification History: * * Date Name Description * 04/05/00 brown initial version * 05/18/00 brown Add Apache support * 06/15/00 brown Add Apache type manager * 08/27/00 brown Update for ICU 1.6 * 04/03/01 brown Update for ICU 1.8 * 05/15/01 brown Add thread support * 08/02/01 brown xIUA 3.0 initial testing complete * 08/24/01 brown Added GB18030 and accept-charset support * 09/01/01 brown Added locale class & invalid character support * 09/07/01 brown Open a codepage locale with utf-8 charset * 10/08/01 brown/maynard const fixes & linux bug fixes * 10/10/01 brown UTF-8/CP signed/unsigned char * 10/10/01 brown xIUA 3.1 complete * 12/06/01 brown xIUA 3.2 complete (ICU 1.8.1-2.0 support) * 10/03/02 brown xIUA 3.3 complete (ICU 2.1-2.2 support) * 12/17/02 brown xIUA 3.4 complete (ICU 2.4 support) * 06/14/03 brown xIUA 3.5 complete (ICU 2.6 support) * 02/05/04 brown xIUA 3.6 complete (ICU 2.8 support) * 02/22/04 brown Filter times zones and build tz offset table */ #include "unicode/utypes.h" /* APP_NO_THREADS is an old symbol. We'll honor it if present. */ #ifdef APP_NO_THREADS # define ICU_USE_THREADS 0 #endif /* Default: use threads. */ #ifndef ICU_USE_THREADS # define ICU_USE_THREADS 1 #endif #if defined(POSIX) && (ICU_USE_THREADS==1) # include /* must be first, so that we get the multithread versions of things. */ #endif #include #include #include #include "unicode/uchar.h" #include "unicode/uloc.h" #include "unicode/ucnv.h" #include "unicode/unum.h" #include "unicode/udat.h" #include "unicode/ucal.h" #include "unicode/ucol.h" #include "unicode/ures.h" #include "unicode/ustring.h" #include "unicode/udata.h" #include "unicode/utf.h" #include "unicode/utf8.h" #include "unicode/utf16.h" #include "unicode/ucnv_err.h" #include "unicode/ucnv_cb.h" #include "xiua.h" #include "xiux.h" #if defined(WIN32) #include #endif #if defined(APACHE_SERVER) #include "mod_xiua.h" #define CORE_PRIVATE #include "httpd.h" #include "http_config.h" #include "http_core.h" #include "http_log.h" #include "http_main.h" #include "http_protocol.h" #include "http_request.h" #include "fnmatch.h" /* * Define Apache module block prototype */ module MODULE_VAR_EXPORT xiua_module; #endif #define MAXWRKBUFFSIZE 8192 #define MAXCNVBUFFSIZE 4096 #ifndef Min #define Min(x,y) (x < y) ? x : y #endif static int32_t UTF16toUTF32Chunk (UChar32 *target, const int32_t targetLen, UChar ** source, const int32_t sourceLen, XIUA_Thread * curr_thread); static int32_t UTF16toUTF8Chunk (char *target, const int32_t targetLen, UChar ** source, const int32_t sourceLen, XIUA_Thread * curr_thread); static int32_t UTF16toCharChunk (char *target, const int32_t targetLen, UChar ** source, const int32_t sourceLen, XIUA_Thread * curr_thread, const void * conv); static int32_t UTF32toUTF16Chunk (UChar *target, const int32_t targetLen, UChar32 ** source, const int32_t sourceLen, XIUA_Thread * curr_thread); static int32_t UTF8toUTF16Chunk(UChar *target, const int32_t targetLen, char ** source, const int32_t numChars, const int32_t numBytes, XIUA_Thread * curr_thread); static int32_t ChartoUTF16Chunk (UChar *target, const int32_t targetLen, char ** source, const int32_t sourceLen, XIUA_Thread * curr_thread, const void * conv); static XIUA_Thread * getCurrentThreadEx(void); static UBool chkWorkSize(int wrkSize); static void GetPOSIXDefaultLocale (char * locale); static const char * defaultCodePageForLocale(const char *locale); static void extractLocale(char* LocaleID,const char* POSIXLocale, XIUA_Thread * curr_thread); static void extractCharset(char* Charset,const char* POSIXLocale, XIUA_Thread * curr_thread); static XIUA_Locale * FindLocale(char * source, XIUA_DataFormat format); static UBool chkLocale(const char * path, const char * locale, XIUA_LocIterate iterate, XIUA_Thread * curr_thread); static UBool chkCharset(const char * charset, const char * locale, int32_t * index); static int32_t cpCharLen(const CpCharU *cs, XIUA_Thread * curr_thread); static int32_t getUTCtime(); #if (XIUA_ICU_LEVEL == 0) static int32_t itou(UChar *target, uint32_t source, int32_t targetBase, int32_t targetLen); static void XIUA_FROM_U_CALLBACK_ESCAPE( void *context, UConverterFromUnicodeArgs *fromArgs, const UChar *codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode * err); #endif static UBool xiua_init_ws = FALSE; /* Set switches below if Windows version prior to Win2000/XP */ #if defined(WIN32) static UBool xiua_Is_Win9x_Me = FALSE; /* Not Win95/98/Me */ static UBool xiua_Is_WinNT = FALSE; /* Not WinNT */ #endif #if defined(WIN32) && (ICU_USE_THREADS==1) typedef struct xTLSKey { DWORD key; } xTLSKey; #define xiua_get_tls_pointer(x) TlsGetValue(x.key) #elif defined(POSIX) && (ICU_USE_THREADS==1) typedef struct xTLSKey { pthread_key_t key; } xTLSKey; ret = ; GetRxLocalValue #define xiua_get_tls_pointer(x) pthread_getspecific(x.key) #else typedef struct xTLSKey { void * key; } xTLSKey; #define xiua_get_tls_pointer(x) (x.key) #endif static xTLSKey xiua_tls_key; /* the xIUA global mutex.*/ XMTX xGlobalMutex = NULL; /* UTF-8 Conversion DATA */ static const uint32_t xkMaximumUCS2 = 0x0000FFFF; static const uint32_t xkMaximumUTF16 = 0x0010FFFF; static const int8_t xhalfShift = 10; static const uint32_t xhalfBase = 0x0010000; static const uint32_t xhalfMask = 0x3FF; static const uint32_t xkSurrogateHighStart = 0xD800; static const uint32_t xkSurrogateHighEnd = 0xDBFF; static const uint32_t xkSurrogateLowStart = 0xDC00; static const uint32_t xkSurrogateLowEnd = 0xDFFF; static const uint32_t xoffsetsFromUTF8[7] = {0, (uint32_t) 0x00000000, (uint32_t) 0x00003080, (uint32_t) 0x000E2080, (uint32_t) 0x03C82080, (uint32_t) 0xFA082080, (uint32_t) 0x82082080 }; static const int8_t xbytesFromUTF8[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; /* UTF-16 Unicode sort order table */ static const UChar utf16Fixup[32]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2000, 0xf800, 0xf800, 0xf800, 0xf800 }; /* DBCS validate table 0x01 = ASCII 0x00 - 0x7F 0x02 = HANKATA 0xA1 - 0xDF 0x04 = SJIS (CP932) byte 1 0x81 - 0x9F & 0xE0 - 0xEF 0x08 = SJIS byte 2 0x40 - 0xFC 0x10 = Big5 (CP950)byte 1 or CP936 byte 1 or 2 0xA1 - 0xFE 0x20 = Big5 byte 2 0x40 - 0x7E & 0xA1 - 0xFE 0x40 = KSC (CP949) byte 1 0x81 - 0xFE 0x80 = KSC byte 2 0x41 - 0x7E & 0x81 - 0xFE The following table is a bit map table of valid fisrt and second bytes for various */ static uint8_t DBCStable[256]={ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x29, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0x09, 0x08, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xC8, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xF0, 0xF0, 0x00, }; /* character length calculation tables */ static int32_t CodeSetMaxLen[16]={ 1, /* XCP1BYTE Single Byte */ 2, /* XCPSJIS Shift JIS */ 2, /* XCPKSC KSC_5601 */ 2, /* XCPBIG5 Big 5 */ 2, /* XCP936 CP936 */ 3, /* XCPEUCJ EUC_J */ 2, /* XCPEUCK EUC_K */ 4, /* XCPEUCH EUC_H */ 2, /* XCPEUCC EUC_C */ 4, /* XCPGB18030 GB18030 */ 8, /* XCP2022 2022 */ 6, /* XCP2022J 2022_JP */ 6, /* XCP2022K 2022_KR */ 8, /* XCP2022C 2022_CN */ 4, /* XCPUTF8 UTF-8 */ 0 }; struct { char * ibm; char * mime; int codeset; } _ConvToCodesetTable[] = { { "ibm-936", "CP936", XCP936 }, { "ibm-943", "Shift_JIS", XCPSJIS}, { "ibm-949", "KS_C_5601-1987", XCPKSC }, { "ibm-950", "Big-5", XCPBIG5 }, { "ibm-964", "EUC-TW", XCPEUCTW }, { "ibm-970", "EUC-KR", XCPEUCKR }, { "ibm-1363", "KSC", XCPKSC }, { "ibm-1370", "Big5", XCPBIG5 }, { "ibm-1383", "EUC-CN", XCPEUCCN }, { "ibm-1386", "cp936", XCP936 }, { "ibm-1392", "gb18030", XCPGB18030 }, { "ibm-33722", "EUC-JP", XCPEUCJP }, { "ISO_2022_JP","ISO-2022-JP", XCP2022J }, { "ISO_2022_KR","ISO-2022-KR", XCP2022K }, { "ISO_2022_CN","ISO-2022-CN", XCP2022C }, { "ISO_2022", "ISO-2022", XCP2022 }, { "UTF8", "utf-8", XCPUTF8 }, { NULL, "XXXXXXXX", XCP1BYTE } }; static const char * const _languageToDefaultlocaleTableX [] = { "af_ZA", "ar_AE", "ar_BH", "ar_DZ", "ar_EG", "ar_IQ", "ar_JO", "ar_KW", "ar_LB", "ar_LY", "ar_MA", "ar_OM", "ar_QA", "ar_SA", "ar_SD", "ar_SY", "ar_TN", "ar_YE", "be_BY", "bg_BG", "ca_ES", "cs_CZ", "da_DK", "de_DE", "de_AT", "de_CH", "de_LU", "el_GR", "en_US", "en_GB", "en_AU", "en_NZ", "en_BE", "en_BW", "en_CA", "en_IE", "en_IN", "en_HK", "en_PH", "en_SG", "en_ZA", "en_ZW", "es_ES", "es_MX", "es_AR", "es_BO", "es_CL", "es_CO", "es_CR", "es_DO", "es_EC", "es_GT", "es_HN", "es_NI", "es_PA", "es_PE", "es_PR", "es_PY", "es_SV", "es_US", "es_UY", "es_VE", "et_EE", "eu_ES", "fa_IR", "fi_FI", "fo_FO", "fr_BE", "fr_CA", "fr_CH", "fr_FR", "fr_LU", "ga_IE", "gl_ES", "gv_GB", "he_IL", "hi_IN", "hr_HR", "hu_HU", "id_ID", "is_IS", "it_IT", "it_CH", "ja_JP", "kl_GL", "ko_KR", "kok_IN", "kw_GB", "lt_LT", "lv_LV", "mk_MK", "mr_IN", "mt_MT", "nb_NO", "nl_BE", "nl_NL", "nn_NO", "pl_PL", "pt_BR", "pt_PT", "ro_RO", "ru_RU", "ru_UA", "sh_YU", "sk_SK", "sl_SI", "sq_AL", "sr_YU", "sv_FI", "sv_SE", "sw_KE", "sw_TZ", "ta_IN", "te_IN", "th_TH", "tr_TR", "uk_UA", "vi_VN", "zh_CN", "zh_TW", "zh_HK", "zh_SG", NULL }; struct { char * loc; char * charmap; } _localeToDefaultCharmapTableX [] = { /* See: http://czyborra.com/charsets/iso8859.html */ /* xx_XX locales first, so they will match: */ { "zh_TW", "big5" }, /* Chinese TW (Traditional) */ { "zh_TW", "cp-950" }, { "zh_TW", "euc-tw" }, { "zh_HK", "big5" }, /* Chinese HK (Traditional) */ { "zh_TW", "cp-950" }, { "zh_TW", "euc-tw" }, { "zh", "gb2312" }, /* Chinese other (Simplified) */ { "zh", "cp-936" }, { "zh", "euc-cn" }, { "zh", "gb18030" }, { "ar", "iso-8859-6" }, /* Arabic */ { "ar", "windows-1256" }, { "be", "iso-8859-5" }, /* Byelorussian */ { "be", "windows-1251" }, { "be", "koi8" }, { "be", "koi8-r" }, { "bg", "iso-8859-5" }, /* Bulgarian */ { "bg", "windows-1251" }, { "bg", "koi8" }, { "bg", "koi8-r" }, { "cs", "iso-8859-2" }, /* Czech */ { "cs", "windows-1250" }, { "el", "iso-8859-7" }, /* Greek */ { "el", "windows-1253" }, { "eo", "iso-8859-3" }, /* Esperanto */ { "et", "iso-8859-4" }, /* Estonian */ { "et", "windows-1257" }, { "he", "iso-8859-8" }, /* hebrew */ { "he", "windows-1255" }, { "hr", "iso-8859-2" }, /* Croatian */ { "hr", "windows-1250" }, { "hu", "iso-8859-2" }, /* Hungarian */ { "hu", "windows-1250" }, { "iw", "iso-8859-8" }, /* hebrew (obsolete) */ { "iw", "windows-1255" }, { "ja", "shift_jis" }, /* Japanese */ { "ja", "cp-932" }, { "ja", "euc-jp" }, { "ji", "iso-8859-8" }, /* Yiddish */ { "kl", "iso-8859-4" }, /* Greenlandic */ { "kl", "windows-1257" }, { "ko", "ksc_5601" }, /* korean */ { "ko", "ks_c_5601-1987" }, { "ko", "cp-949" }, { "ko", "euc-kr" }, { "lt", "iso-8859-4" }, /* Lithuanian */ { "lt", "windows-1257" }, { "lv", "iso-8859-4" }, /* latvian (lettish) */ { "lv", "windows-1257" }, { "mk", "iso-8859-5" }, /* Macedonian */ { "mk", "windows-1251" }, { "mk", "koi8" }, { "mk", "koi8-r" }, { "mt", "iso-8859-3" }, /* Maltese */ { "pl", "iso-8859-2" }, /* Polish */ { "pl", "windows-1250" }, { "ro", "iso-8859-2" }, /* Romanian */ { "ro", "windows-1250" }, { "ru", "iso-8859-5" }, /* Russian */ { "ru", "windows-1251" }, { "ru", "koi8" }, { "ru", "koi8-r" }, { "sk", "iso-8859-2" }, /* Slovak */ { "sk", "windows-1250" }, { "sl", "iso-8859-2" }, /* Slovenian */ { "sl", "windows-1250" }, { "sr", "iso-8859-5" }, /* Serbian */ { "sr", "windows-1251" }, { "sr", "koi8" }, { "sr", "koi8-r" }, { "th", "tis-620" }, /* Thai */ { "th", "windows-874" }, { "tr", "iso-8859-9" }, /* Turkish */ { "tr", "windows-1254" }, { "uk", "iso-8859-5" }, /* pre 1990 Ukranian... see: */ { "vi", "windows-1258" }, /* Vietnamese */ { NULL, NULL } }; /* END OF UTF-8 Conversion DATA */ #if U_CHARSET_FAMILY==U_EBCDIC_FAMILY #ifdef OS390 /* * These maps for ASCII to/from EBCDIC are from * "UTF-EBCDIC - EBCDIC-Friendly Unicode (or UCS) Transformation Format" * at http://www.unicode.org/unicode/reports/tr16/ * (which should reflect codepage 1047) * but modified to explicitly exclude the variant * control and graphical characters that are in ASCII-based * codepages at 0x80 and above. * Also, unlike in Version 6.0 of the UTR on UTF-EBCDIC, * the Line Feed mapping varies according to the environment. * * These tables do not establish a converter or a codepage. */ /* on S/390 Open Edition, ASCII 0xa (LF) maps to 0x15 and ISO-8 0x85 maps to 0x25 */ # define E_LF 0x15 # define A_15 0x0a # define A_25 0x20 # if 0 /* the CDRA variation of 1047 is not currently used - see tables in #else below */ /* in standard EBCDIC (CDRA), ASCII 0xa (LF) maps to 0x25 and ISO-8 0x85 maps to 0x15 */ # define E_LF 0x25 # define A_15 0x20 # define A_25 0x0a # endif static uint8_t asciiFromEbcdic[256]={ 0x00, 0x01, 0x02, 0x03, 0x20, 0x09, 0x20, 0x7F, 0x20, 0x20, 0x20, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x20, A_15, 0x08, 0x20, 0x18, 0x19, 0x20, 0x20, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x20, 0x20, 0x20, 0x20, A_25, 0x17, 0x1B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x05, 0x06, 0x07, 0x20, 0x20, 0x16, 0x20, 0x20, 0x20, 0x20, 0x04, 0x20, 0x20, 0x20, 0x20, 0x14, 0x15, 0x20, 0x1A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, 0x26, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, 0x2D, 0x2F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x5B, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5D, 0x20, 0x20, 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5C, 0x20, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; static uint8_t ebcdicFromAscii[128]={ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, E_LF, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07 }; #else /* * These maps for ASCII to/from EBCDIC were generated * using the ICU converter for codepage 37 on 2000-may-22. * They explicitly exclude the variant * control and graphical characters that are in ASCII-based * codepages at 0x80 and above. * * These tables do not establish a converter or a codepage. */ static uint8_t asciiFromEbcdic[256]={ 0x00, 0x01, 0x02, 0x03, 0x20, 0x09, 0x20, 0x7f, 0x20, 0x20, 0x20, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x20, 0x20, 0x08, 0x20, 0x18, 0x19, 0x20, 0x20, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x17, 0x1b, 0x20, 0x20, 0x20, 0x20, 0x20, 0x05, 0x06, 0x07, 0x20, 0x20, 0x16, 0x20, 0x20, 0x20, 0x20, 0x04, 0x20, 0x20, 0x20, 0x20, 0x14, 0x15, 0x20, 0x1a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, 0x26, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x20, 0x2d, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, 0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5b, 0x5d, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; static uint8_t ebcdicFromAscii[128]={ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xba, 0xe0, 0xbb, 0xb0, 0x6d, 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07 }; #endif #endif #if ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==8)) extern const uint8_t U_IMPORT icudt28_dat[]; #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==6)) extern const uint8_t U_IMPORT icudt26_dat[]; #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==4)) extern const uint8_t U_IMPORT icudt24_dat[]; #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==2)) extern const uint8_t U_IMPORT icudt22_dat[]; #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==1)) extern const uint8_t U_IMPORT icudt21_dat[]; #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==0)) extern const uint8_t U_IMPORT icudt20_dat[]; #elif ((U_ICU_VERSION_MAJOR_NUM == 1) && (U_ICU_VERSION_MINOR_NUM ==9)) extern const uint8_t U_IMPORT icudt19_dat[]; #else extern const uint8_t U_IMPORT icudata_dat[]; #endif /* Initiate XIUA */ UErrorCode xiua_Init() { #if defined(WIN32) LONG ret_val; char *NameOfSubKey1 = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Time Zones"; char *NameOfSubKey2 = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\GMT"; HKEY hkey; #endif UErrorCode status; if (xiua_init_ws) return U_ZERO_ERROR; status = U_ZERO_ERROR; #if ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==8)) udata_setCommonData((const void*)icudt28_dat, &status); #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==6)) udata_setCommonData((const void*)icudt26_dat, &status); #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==4)) udata_setCommonData((const void*)icudt24_dat, &status); #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==2)) udata_setCommonData((const void*)icudt22_dat, &status); #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==1)) udata_setCommonData((const void*)icudt21_dat, &status); #elif ((U_ICU_VERSION_MAJOR_NUM == 2) && (U_ICU_VERSION_MINOR_NUM ==0)) udata_setCommonData((const void*)icudt20_dat, &status); #elif ((U_ICU_VERSION_MAJOR_NUM == 1) && (U_ICU_VERSION_MINOR_NUM ==9)) udata_setCommonData((const void*)icudt19_dat, &status); #else udata_setCommonData((const void*)icudata_dat, &status); #endif #if defined(WIN32) ret_val = RegOpenKeyEx( (HKEY)HKEY_LOCAL_MACHINE, NameOfSubKey1, 0, KEY_QUERY_VALUE, &hkey ); if ( ret_val == ERROR_SUCCESS ) { xiua_Is_Win9x_Me = TRUE; /* Is win95/98/Me */ } RegCloseKey (hkey); if (!xiua_Is_Win9x_Me) { ret_val = RegOpenKeyEx( (HKEY)HKEY_LOCAL_MACHINE, NameOfSubKey2, 0, KEY_QUERY_VALUE, &hkey ); if ( ret_val == ERROR_SUCCESS ) { xiua_Is_WinNT = TRUE; /* Is winNT */ } RegCloseKey (hkey); } #endif xmtx_init(NULL); xmtx_lock(NULL); if (!xiua_init_ws) { #if defined(WIN32) && (ICU_USE_THREADS==1) xiua_tls_key.key = TlsAlloc(); if (xiua_tls_key.key == -1) status = U_INTERNAL_PROGRAM_ERROR; #elif defined(POSIX) && (ICU_USE_THREADS==1) if (pthread_key_create(xiua_tls_key.key, ((void (*) (void *))NULL)) != 0) status = U_INTERNAL_PROGRAM_ERROR; #else xiua_tls_key.key = NULL; #endif xiua_init_ws = TRUE; } xmtx_unlock(NULL); if (status <= U_ZERO_ERROR) return xiua_InitThread(); return status; } /* Initiate XIUA */ UErrorCode xiua_InitThread() { UErrorCode status = U_ZERO_ERROR; XIUA_Thread * curr_thread; int i; curr_thread = xiua_get_tls_pointer(xiua_tls_key); if (curr_thread == NULL) { curr_thread = malloc(sizeof(XIUA_Thread)); if (curr_thread == NULL) { status = U_MEMORY_ALLOCATION_ERROR; } else { memset((void *)curr_thread,0,sizeof(XIUA_Thread)); curr_thread->First_locale = NULL; for (i=0;i<=XLCMAX;i++) { curr_thread->Locale_Clases[i] = NULL; } curr_thread->Curr_locale = NULL; curr_thread->last_str = NULL; curr_thread->work_buff = malloc(256); curr_thread->work_size = 256; if (curr_thread->work_buff == NULL) { status = U_MEMORY_ALLOCATION_ERROR; free((void *)curr_thread); } else { #if defined(WIN32) && (ICU_USE_THREADS==1) if(TlsSetValue(xiua_tls_key.key, curr_thread) == FALSE) { status = U_INTERNAL_PROGRAM_ERROR; free((void *)curr_thread->work_buff); free((void *)curr_thread); } #elif defined(POSIX) && (ICU_USE_THREADS==1) if (pthread_setspecific(xiua_tls_key.key, curr_thread) != 0) { status = U_INTERNAL_PROGRAM_ERROR; free((void *)curr_thread->work_buff); free((void *)curr_thread); } #else xiua_tls_key.key = (void *)curr_thread; #endif } } } if (status < U_ZERO_ERROR) status = U_ZERO_ERROR; return status; } /* Terminate XIUA */ void xiua_TermThread() { XIUA_Thread * curr_thread; curr_thread = xiua_get_tls_pointer(xiua_tls_key); if (curr_thread != NULL) { free((void *)curr_thread); #if defined(WIN32) && (ICU_USE_THREADS==1) TlsSetValue(xiua_tls_key.key, NULL); #elif defined(POSIX) && (ICU_USE_THREADS==1) pthread_setspecific(xiua_tls_key.key, NULL); #else xiua_tls_key.key = NULL; #endif } return; } void xiua_Term() { xiua_TermThread(); #if defined(WIN32) && (ICU_USE_THREADS==1) TlsFree(xiua_tls_key.key); #elif defined(POSIX) && (ICU_USE_THREADS==1) pthread_key_delete(xiua_tls_key.key); /* #else xiua_tls_key = (xTLSKey *)NULL; */ #endif xmtx_term(NULL); } UErrorCode * xiua_CurrentStatus() { XIUA_Thread * curr_thread; curr_thread = getCurrentThreadEx(); return &curr_thread->status; } XIUA_Locale * xiua_OpenLocale(const char * source, const XIUA_DataFormat format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; XIUA_Locale * open_locale; XIUA_LocIterate iterate = XLOC_MATCH_VARIANT; const char * defchar; char *t; char charsetdef[] = "windows-1252"; char WrkName[XIUA_MAXFULLLOCALESIZE]; char LocName[XIUA_MAXLOCALESIZE]; char WrkCset[XIUA_MAXCHARSETSIZE]; char IBMCset[XIUA_MAXCHARSETSIZE]; char * Charset; int locale_len; int i, j; curr_thread = getCurrentThreadEx(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (source && source[0]) { strncpy(WrkName,source,XIUA_MAXFULLLOCALESIZE); } else { GetPOSIXDefaultLocale(WrkName); } WrkName[XIUA_MAXFULLLOCALESIZE-1] = 0; t = &WrkName[0]; if((t = strchr(t, '#')) != NULL) { *t++ = 0; } extractLocale(LocName,(char*)WrkName, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; { } chkLocale(NULL,( const char *) LocName, iterate, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; open_locale = FindLocale(LocName, format); if (open_locale) { curr_thread->Curr_locale = open_locale; curr_thread->status = U_LOCALE_REOPENED_WARNING; return open_locale; } open_locale = (XIUA_Locale *)malloc(sizeof(XIUA_Locale)); memset((char *)open_locale,0,sizeof(XIUA_Locale)); open_locale->next = NULL; open_locale->prev = NULL; open_locale->thread = (void *)curr_thread; open_locale->locale = &open_locale->locale_val[0]; open_locale->charset = &open_locale->charset_val[0]; open_locale->tzone = NULL; open_locale->conv = NULL; open_locale->open_format = format; open_locale->format = format; open_locale->codeset = XCP1BYTE; strncpy(open_locale->locale_val,LocName,XIUA_MAXLOCALESIZE); open_locale->locale_val[XIUA_MAXLOCALESIZE] = 0; if (curr_locale) { strcpy(open_locale->tzone_val,curr_locale->tzone_val); if (*open_locale->tzone_val) { open_locale->tzone = &open_locale->tzone_val[0]; } } extractCharset(open_locale->charset_val,(char*)WrkName,curr_thread); if (U_FAILURE(curr_thread->status)) { open_locale->charset_val[0] = 0; curr_thread->status = U_ZERO_ERROR; } if (t) { strncpy(open_locale->tzone_val,t,XIUA_MAXTIMEZONESIZE); open_locale->tzone_val[XIUA_MAXTIMEZONESIZE-1] = 0; open_locale->tzone = &open_locale->tzone_val[0]; if (strcmp(open_locale->tzone,"GMT") == 0) { strcpy((char *)open_locale->tzone,"Africa/Casablanca"); } } if (!open_locale->charset[0]) { defchar = defaultCodePageForLocale(open_locale->locale); if (defchar == NULL) { defchar = (char *)&charsetdef[0]; } strncpy((char *)open_locale->charset,defchar,XIUA_MAXCHARSETSIZE); open_locale->charset_val[XIUA_MAXCHARSETSIZE-1] = 0; if (U_FAILURE(curr_thread->status)) { free(open_locale); return NULL; } } strcpy(open_locale->charset_name,open_locale->charset); if (open_locale->charset[0]) { open_locale->conv = (void *)ucnv_open((const char *)open_locale->charset, &curr_thread->status); if (U_FAILURE(curr_thread->status)) { free(open_locale); return NULL; } ucnv_setFallback(open_locale->conv, TRUE); strcpy(WrkCset,ucnv_getName(open_locale->conv,&curr_thread->status)); if (U_FAILURE(curr_thread->status)) { free(open_locale); return NULL; } strcpy(IBMCset,WrkCset); Charset = (char *)ucnv_getStandardName(WrkCset, "MIME", &curr_thread->status); if (Charset == NULL) { curr_thread->status = U_ZERO_ERROR; Charset = (char *)ucnv_getStandardName(WrkCset, "IANA", &curr_thread->status); } curr_thread->status = U_ZERO_ERROR; if (Charset != NULL) strcpy(open_locale->charset_name,Charset); i = 0; while (_ConvToCodesetTable[i].ibm) { j = strlen(_ConvToCodesetTable[i].mime); if (strncmp(open_locale->charset_name, _ConvToCodesetTable[i].mime,j) == 0) break; if (strncmp(IBMCset, _ConvToCodesetTable[i].mime,j) == 0) break; j = strlen(_ConvToCodesetTable[i].ibm); if (strncmp(open_locale->charset_name, _ConvToCodesetTable[i].ibm,j) == 0) break; if (strncmp(IBMCset, _ConvToCodesetTable[i].ibm,j) == 0) break; i++; } open_locale->codeset = _ConvToCodesetTable[i].codeset; if (open_locale->codeset == XCPUTF8 && open_locale->format >= XDFCODEPAGE) open_locale->format = XDFUTF8; } locale_len = strlen(open_locale->locale); if (curr_locale) { open_locale->next = curr_locale->next; open_locale->prev = (void *)curr_locale; curr_locale->next = (void *)open_locale; } curr_thread->Curr_locale = open_locale; if (!curr_thread->Locale_Clases[XLCDEFAULT]) curr_thread->Locale_Clases[XLCDEFAULT] = open_locale; if (!curr_thread->First_locale) curr_thread->First_locale = open_locale; return open_locale; } XIUA_Locale * xiua_SetLocaleHdl(const XIUA_Locale * Locale) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (Locale != NULL) { if (Locale->thread != (void *)curr_thread) { curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return curr_locale; } curr_thread->Curr_locale = (XIUA_Locale *)Locale; } return curr_locale; } XIUA_Locale * xiua_SetLocaleClassHdl(const XIUA_Locale * Locale, const XIUA_LocaleClass lclass) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (Locale != NULL) { if (Locale->thread != (void *)curr_thread) { curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return curr_locale; } curr_thread->Locale_Clases[lclass] = (XIUA_Locale *)Locale; return (XIUA_Locale *)Locale; } else { curr_thread->Locale_Clases[lclass] = curr_locale; } return curr_locale; } XIUA_Locale * xiua_GetLocaleClassHdl(const XIUA_LocaleClass lclass) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (lclass >= XLCDEFAULT && lclass <= XLCMAX) return curr_thread->Locale_Clases[lclass]; curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return NULL; } XIUA_Locale * xiua_SetLocaleInvalidCharHdl(const XIUA_Locale * Locale, const XIUA_InvalidChar ichar) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UConverterFromUCallback oldFromAction; UConverterToUCallback oldToAction; void *oldContext; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (Locale != NULL) { if (Locale->thread != (void *)curr_thread) { curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return curr_locale; } curr_locale = (XIUA_Locale *)Locale; } switch (ichar) { case XICSKIP: ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_SKIP,NULL, &oldFromAction,&oldContext,&curr_thread->status); ucnv_setToUCallBack (curr_locale->conv, UCNV_TO_U_CALLBACK_SKIP,NULL, &oldToAction,&oldContext,&curr_thread->status); break; case XICSUBSTITUTE: ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_SUBSTITUTE,NULL, &oldFromAction,&oldContext,&curr_thread->status); ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_SUBSTITUTE,NULL, &oldToAction,&oldContext,&curr_thread->status); break; case XICSTOP: ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_STOP,NULL, &oldFromAction,&oldContext,&curr_thread->status); ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_STOP,NULL, &oldToAction,&oldContext,&curr_thread->status); break; case XICFROM_U_ESCAPE_ICU: ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_ICU, &oldFromAction,&oldContext,&curr_thread->status); break; case XICTO_U_ESCAPE_ICU: ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_ESCAPE,UCNV_ESCAPE_ICU, &oldToAction,&oldContext,&curr_thread->status); break; case XICFROM_U_ESCAPE_JAVA: ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_JAVA, &oldFromAction,&oldContext,&curr_thread->status); break; case XICTO_U_ESCAPE_JAVA: ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_ESCAPE,UCNV_ESCAPE_JAVA, &oldToAction,&oldContext,&curr_thread->status); break; case XICFROM_U_ESCAPE_C: #if (XIUA_ICU_LEVEL == 0) ucnv_setFromUCallBack(curr_locale->conv, XIUA_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_C, &oldFromAction,&oldContext,&curr_thread->status); #else ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_C, &oldFromAction,&oldContext,&curr_thread->status); #endif break; case XICTO_U_ESCAPE_C: ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_ESCAPE,UCNV_ESCAPE_C, &oldToAction,&oldContext,&curr_thread->status); break; case XICFROM_U_ESCAPE_XML_DEC: #if (XIUA_ICU_LEVEL == 0) ucnv_setFromUCallBack(curr_locale->conv, XIUA_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_XML_DEC, &oldFromAction,&oldContext,&curr_thread->status); #else ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_XML_DEC, &oldFromAction,&oldContext,&curr_thread->status); #endif break; case XICTO_U_ESCAPE_XML_DEC: ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_ESCAPE,UCNV_ESCAPE_XML_DEC, &oldToAction,&oldContext,&curr_thread->status); break; case XICFROM_U_ESCAPE_XML_HEX: #if (XIUA_ICU_LEVEL == 0) ucnv_setFromUCallBack(curr_locale->conv, XIUA_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_XML_HEX, &oldFromAction,&oldContext,&curr_thread->status); #else ucnv_setFromUCallBack(curr_locale->conv, UCNV_FROM_U_CALLBACK_ESCAPE,UCNV_ESCAPE_XML_HEX, &oldFromAction,&oldContext,&curr_thread->status); #endif break; case XICTO_U_ESCAPE_XML_HEX: ucnv_setToUCallBack(curr_locale->conv, UCNV_TO_U_CALLBACK_ESCAPE,UCNV_ESCAPE_XML_HEX, &oldToAction,&oldContext,&curr_thread->status); break; case XICNO_FALLBACK: ucnv_setFallback(curr_locale->conv, FALSE); break; case XICUSE_FALLBACK: ucnv_setFallback(curr_locale->conv, TRUE); break; default: curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return curr_locale; } return curr_locale; } XIUA_Locale * xiua_CloseLocale(const char * source, const XIUA_DataFormat format, const XIUA_LocaleClass lclass) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; XIUA_Locale * clos_locale; XIUA_LocIterate iterate = XLOC_MATCH_VARIANT; char *t; char WrkName[XIUA_MAXFULLLOCALESIZE]; char LocName[XIUA_MAXLOCALESIZE]; curr_thread = getCurrentThreadEx(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (!curr_locale) return NULL; if (source && source[0]) { strncpy(WrkName,source,XIUA_MAXFULLLOCALESIZE); } else { GetPOSIXDefaultLocale(WrkName); } WrkName[XIUA_MAXFULLLOCALESIZE-1] = 0; t = &WrkName[0]; if((t = strchr(t, '#')) != NULL) { *t++ = 0; } extractLocale(LocName,(char*)WrkName, curr_thread); if (U_FAILURE(curr_thread->status)) return curr_locale; chkLocale(NULL,( const char *) LocName, iterate, curr_thread); if (U_FAILURE(curr_thread->status)) return curr_locale; clos_locale = FindLocale(LocName, format); if (!clos_locale) return curr_locale; curr_locale = xiua_CloseLocaleHdl(clos_locale, lclass); return curr_locale; } XIUA_Locale * xiua_CloseLocaleHdl(const XIUA_Locale * Locale, const XIUA_LocaleClass lclass) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; XIUA_Locale * next_locale; XIUA_Locale * prev_locale; int i; curr_thread = getCurrentThreadEx(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (!curr_locale) return NULL; if (Locale == NULL) { Locale = curr_locale; } next_locale = (XIUA_Locale *)Locale->next; prev_locale = (XIUA_Locale *)Locale->prev; if (next_locale) { next_locale->prev = Locale->prev; } if (prev_locale) { prev_locale->next = Locale->next; } if (Locale == curr_thread->First_locale) { curr_thread->First_locale = Locale->next; } for (i=0;i<=XLCMAX;i++) { if (Locale == curr_thread->Locale_Clases[i]) curr_thread->Locale_Clases[i] = NULL; } if (curr_thread->Locale_Clases[XLCDEFAULT] == NULL) { if (prev_locale) { curr_thread->Locale_Clases[XLCDEFAULT] = prev_locale; } else { curr_thread->Locale_Clases[XLCDEFAULT] = next_locale; } } if (lclass >= XLCDEFAULT && lclass <= XLCMAX) { curr_thread->Curr_locale = curr_thread->Locale_Clases[lclass]; } else { if (Locale == curr_thread->Curr_locale) { if (prev_locale) { curr_thread->Curr_locale = prev_locale; } else { curr_thread->Curr_locale = next_locale; } } } curr_locale = curr_thread->Curr_locale; if (Locale->conv) { ucnv_close(Locale->conv); } free((void *)Locale); return curr_locale; } void xiua_CloseLocaleAll(void) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = getCurrentThreadEx(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; while(curr_locale) { curr_locale = xiua_CloseLocaleHdl(curr_locale, XLCNONE); } return; } void xiua_SetTZone(const XIUA_Locale * hlocale, const char * zonename) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (hlocale) { curr_locale = (XIUA_Locale *)hlocale; } if (!curr_locale) return; strncpy(curr_locale->tzone_val,zonename,XIUA_MAXTIMEZONESIZE); curr_locale->tzone_val[XIUA_MAXTIMEZONESIZE-1] = 0; curr_locale->tzone = &curr_locale->tzone_val[0]; return; } const char * xiua_CurrentLocale(void) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; return curr_locale->locale; } int32_t xiua_GetLocaleName(char * locale, const int32_t size, const XIUA_Locale * hlocale) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; char LocName[XIUA_MAXFULLLOCALESIZE]; char WrkName[XIUA_MAXLOCALESIZE]; char *v; int i; /* Format: (no spaces) ll [_CC ] [.MM ] [ @VV] [#TT] ll = lang, CC = ctry, MM = charmap, VV = variant, TT = time zone */ curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (hlocale) { curr_locale = (XIUA_Locale *)hlocale; } if (!curr_locale) return 0; strcpy(WrkName,curr_locale->locale); v = &WrkName[0]; if((v = strchr(v, '_')) != NULL) { v++; if((v = strchr(v, '_')) != NULL) { *v++ = 0; } } strcpy(LocName,WrkName); if (curr_locale->charset[0]) { strcat(LocName,"."); strcat(LocName,curr_locale->charset); } if (v) { strcat(LocName,"@"); strcat(LocName,v); } if (curr_locale->tzone) { strcat(LocName,"#"); strcat(LocName,curr_locale->tzone); } i = strlen(LocName); strncpy(locale,LocName,size); if (i >= (int)size) { i = size - 1; locale[i] = 0; } return i; } int32_t xiua_ScanDir(char * locale, const char * dir) { XIUA_Thread * curr_thread; int32_t i; int32_t dirLevel = 0; char *CurrNode; char WrkLocale[XIUA_MAXLOCALESIZE]; XIUA_LocIterate iterate = XLOC_MATCH_VARIANT; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (dir == NULL || (i = strlen(dir)) <2) return 0; if (!chkWorkSize(i+1)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } if (dir[1] == ':') /* Skip Windows drive letter */ { strcpy(curr_thread->work_buff,dir+2); } else { strcpy(curr_thread->work_buff,dir); } CurrNode = (char *)xicp_strtok((CpChar *)curr_thread->work_buff,(CpChar *)"/\\"); while(CurrNode) { dirLevel++; strcpy(WrkLocale,CurrNode); if (chkLocale(NULL,WrkLocale,iterate,curr_thread)) { strcpy(locale,WrkLocale); return dirLevel; } CurrNode = (char *)xicp_strtok(NULL,(CpChar *)"/\\"); } return 0; } int32_t xiua_AcceptLanguage(char * lang, const char * languages) { XIUA_Thread * curr_thread; int32_t i; int32_t CurrQ; CpChar *CurrNode; CpChar *CurrToken; CpChar *QNum; CpChar *WrkAddr1; CpChar *WrkAddr2; CpChar *Ptr1; CpChar *Ptr2; CpChar **PtrAddr1; CpChar **PtrAddr2; char NumWrk[8]; char WrkLang[XIUA_MAXLOCALESIZE]; char BestLang[XIUA_MAXLOCALESIZE]; XIUA_LocIterate iterate = XLOC_MATCH_VARIANT; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; /* see http://www.w3.org/Protocols/rfc2068/rfc2068 */ if (languages == NULL || (i = strlen(languages)) <2) return 0; i++; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } WrkAddr1 = (CpChar *)&curr_thread->work_buff[0]; WrkAddr2 = (CpChar *)&curr_thread->work_buff[i]; BestLang[0] = 0; CurrQ = 0; strcpy(curr_thread->work_buff,languages); Ptr1 = NULL; PtrAddr1 = &Ptr1; CurrNode = xicp_strtok_r(WrkAddr1,(CpChar *)",", PtrAddr1); while(CurrNode) { strcpy((char *)WrkAddr2,(const char *)CurrNode); Ptr2 = NULL; PtrAddr2 = &Ptr2; CurrToken = xicp_strtok_r(WrkAddr2,(CpChar *)"; ", PtrAddr2); strcpy(WrkLang, (const char *)CurrToken); if (chkLocale(NULL,WrkLang,iterate,curr_thread)) { if (BestLang[0] == 0) strcpy(BestLang,WrkLang); i = 1000; while (CurrToken) { CurrToken = xicp_strtok_r(NULL,(CpChar *)"; ", PtrAddr2); if (!CurrToken) break; if (strlen((const char *)CurrToken) < 3 || (memcmp(CurrToken,"q=",2) != 0) || CurrToken[2] == '1') break; QNum = (CpChar *)strchr((const char *)CurrToken,'.'); if (QNum) { QNum++; strncpy(NumWrk,(const char *)QNum,3); NumWrk[3] = 0; strcat(NumWrk,"000"); NumWrk[3] = 0; i = atoi(NumWrk); } else { i = 0; } } if (i > CurrQ) { CurrQ = i; strcpy(BestLang,WrkLang); } } if (CurrQ >= 1000) break; CurrNode = xicp_strtok_r(NULL,(CpChar *)",", PtrAddr1); } i = strlen(BestLang); if (i > 0) strcpy(lang,BestLang); return i; } /* Get browser configured locale from language code */ void xiua_FindLocaleFromLang (char * locale, const char * language) { XIUA_Thread * curr_thread; char WrkName[XIUA_MAXLOCALESIZE]; char ChkName[XIUA_MAXLOCALESIZE]; char LocName[XIUA_MAXLOCALESIZE]; char lang[8]; char variant[12]; char *l; char *c; int32_t i, j; XIUA_LocIterate iterate_exact = XLOC_MATCH_EXACT; XIUA_LocIterate iterate_variant = XLOC_MATCH_VARIANT; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; LocName[0] = 0; extractLocale(WrkName,language, curr_thread); c = strchr(WrkName,'_'); if (c) { strcpy(LocName, WrkName); chkLocale(NULL,LocName,iterate_variant,curr_thread); } else { /* If no country code you can set explicit country defaults by adding %%ALIAS members to ICU. For example en_ZX.txt en_ZX { "%%ALIAS" { "en_US" } } These files have to be added to icu/data/resfiles.mk. Do not add them to index.txt. */ strncpy(lang,WrkName,3); /* create name for ZX compare and one where */ lang[3] = 0; /* first 3 bytes are "ll_" or "lll" for table */ strcat(lang,"_ZX"); /* lookup */ strcpy(ChkName,lang); if (chkLocale(NULL,ChkName,iterate_variant,curr_thread)) { strcpy(LocName, ChkName); } } /* Use xIUA internal default table to find the default country */ if (!*LocName) { for(i=0; _languageToDefaultlocaleTableX[i]; i++) { if(memcmp(lang, _languageToDefaultlocaleTableX[i], 3) == 0) { strcpy(ChkName,_languageToDefaultlocaleTableX[i]); if (chkLocale(NULL,ChkName,iterate_variant,curr_thread)) { strcpy(LocName,ChkName); break; } } } } /* Use ICU index.txt table to find the default country */ if (!*LocName) { i = uloc_countAvailable(); j = 0; while (j < i) { curr_thread->status = U_ZERO_ERROR; l = (char *)uloc_getAvailable(j); j++; if (memcmp(lang,l,3) != 0) continue; if ((uloc_getCountry(l,variant, 12, &curr_thread->status)) < 3) continue; if ((uloc_getVariant(l,variant, 12, &curr_thread->status)) > 9) continue; strcpy(ChkName,l); if (!(chkLocale(NULL,( const char *) ChkName, iterate_exact, curr_thread))) continue; strcpy(LocName,ChkName); break; } } if (!*LocName) { strcpy(LocName,WrkName); } strcpy(locale,LocName); return; } int32_t xiua_AcceptCharset(char * posix_locale, const char * locale, const char * charsets) { XIUA_Thread * curr_thread; int32_t i; int32_t index; int32_t CurrQ; CpChar *CurrNode; CpChar *CurrToken; CpChar *QNum; CpChar *WrkAddr1; CpChar *WrkAddr2; CpChar *Ptr1; CpChar *Ptr2; CpChar **PtrAddr1; CpChar **PtrAddr2; char NumWrk[8]; char WrkCharset[XIUA_MAXCHARSETSIZE]; char BestCharset[XIUA_MAXCHARSETSIZE]; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; /* see http://www.w3.org/Protocols/rfc2068/rfc2068 */ if (charsets == NULL || (i = strlen(charsets)) <2) return 0; i++; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } WrkAddr1 = (CpChar *)&curr_thread->work_buff[0]; WrkAddr2 = (CpChar *)&curr_thread->work_buff[i]; index = -1; BestCharset[0] = 0; CurrQ = 0; strcpy(curr_thread->work_buff,charsets); Ptr1 = NULL; PtrAddr1 = &Ptr1; CurrNode = xicp_strtok_r(WrkAddr1,(CpChar *)",", PtrAddr1); while(CurrNode) { strcpy((char *)WrkAddr2,(const char *)CurrNode); Ptr2 = NULL; PtrAddr2 = &Ptr2; CurrToken = xicp_strtok_r(WrkAddr2,(CpChar *)"; ", PtrAddr2); strcpy(WrkCharset,(const char *)CurrToken); if (*WrkCharset == '*' || chkCharset(WrkCharset,locale,&index)) { if (BestCharset[0] == 0) strcpy(BestCharset,WrkCharset); i = 1000; while (CurrToken) { CurrToken = xicp_strtok_r(NULL,(CpChar *)"; ", PtrAddr2); if (!CurrToken) break; if (strlen((const char *)CurrToken) < 3 || (memcmp(CurrToken,"q=",2) != 0) || CurrToken[2] == '1') break; QNum = (CpChar *)strchr((const char *)CurrToken,'.'); if (QNum) { QNum++; strncpy(NumWrk,(const char *)QNum,3); NumWrk[3] = 0; strcat(NumWrk,"000"); NumWrk[3] = 0; i = atoi(NumWrk); } else { i = 0; } } if (i > CurrQ) { CurrQ = i; strcpy(BestCharset,WrkCharset); } } if (CurrQ >= 1000) break; CurrNode = xicp_strtok_r(NULL,(CpChar *)",", PtrAddr1); } i = strlen(BestCharset); strcpy(posix_locale,locale); strcat(posix_locale,"."); if (i > 0) { if (*BestCharset != '*') { strcat(posix_locale,BestCharset); } else { strcat(posix_locale,defaultCodePageForLocale(locale)); } i = strlen(posix_locale); } else { strcat(posix_locale,defaultCodePageForLocale(locale)); } return i; } /* Test locale */ UBool xiua_ChkLocale(char * target, const char * source, const XIUA_LocIterate iterate) { XIUA_Thread * curr_thread; char LocName[XIUA_MAXLOCALESIZE]; size_t loc_len; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; memset(LocName,0,XIUA_MAXLOCALESIZE); strncpy(LocName,source,XIUA_MAXLOCALESIZE-1); loc_len = strlen(LocName); if (loc_len < 2) { curr_thread->status = U_INVALID_FORMAT_ERROR; return FALSE; } i = loc_len -1; if (chkLocale(NULL,( const char *) LocName, iterate, curr_thread)) { strncpy(target,LocName,XIUA_MAXLOCALESIZE-1); target[XIUA_MAXLOCALESIZE-1] = 0; return TRUE; } return FALSE; } int32_t xiua_GetNextLocale(char *target, const int32_t numBytes, int32_t * next, int32_t * max, const XIUA_LocaleType type) { XIUA_Thread * curr_thread; char LocName[XIUA_MAXLOCALESIZE]; char variant[12]; const char *locale; int32_t i; XIUA_LocIterate iterate = XLOC_MATCH_EXACT; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (*max < 0) *max = uloc_countAvailable(); if (*next < 0) *next = 0; while (*next < *max) { curr_thread->status = U_ZERO_ERROR; locale = uloc_getAvailable(*next); *next = *next + 1; strncpy(LocName,locale,XIUA_MAXLOCALESIZE-1); if (!(chkLocale(NULL,( const char *) LocName, iterate, curr_thread))) continue; /* if (strcmp(locale,LocName) != 0) continue; skip if %%ALIAS */ i = uloc_getCountry(LocName,variant, 12, &curr_thread->status); if (type == XLTLANGUAGE) { #if (XIUA_ICU_LEVEL == 0) if (i > 2) continue; #else if (i > 1) continue; #endif } else if (type == XLTCOUNTRY) { #if (XIUA_ICU_LEVEL == 0) if (i < 3) continue; #else if (i < 2) continue; #endif } /* if ((uloc_getVariant(LocName,variant, 12, &curr_thread->status)) > 9) continue; */ strncpy(target,LocName, numBytes); target[numBytes-1] = 0; return strlen(target); } return 0; } int32_t xiua_DisplayLocale(char *target, const int32_t targetLen, const char * source, const XIUA_LocaleList listlang) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (2 * xiu2_DisplayLocale((UChar *)target, (targetLen / 2),source, listlang)); case XDFUTF32: return (4 * xiu4_DisplayLocale((UChar32 *)target, (targetLen / 4),source, listlang)); case XDFUTF8: return xiu8_DisplayLocale((UChar8 *)target, targetLen,source, listlang); default: return xicp_DisplayLocale((CpChar *)target, targetLen,source, listlang); } curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } int32_t xiu2_DisplayLocale(UChar *target, const int32_t targetLen, const char * source, const XIUA_LocaleList listlang) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar *myTarget = target; int32_t myTargetSize; int32_t numDispChar = 0; int32_t numUBytes; char inlocale_val[] = "en_US"; char * inlocale = &inlocale_val[0]; char * enlocale = &inlocale_val[0]; UBool en_lang = FALSE; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (memcmp(curr_locale->locale,"en",2) == 0) { inlocale = (char *)curr_locale->locale; } else { switch (listlang) { case XLLBOTH: en_lang = TRUE; case XLLLOCALE: inlocale = (char *)curr_locale->locale; break; default: break; } } xiux_strToNUChars(myTarget,source,targetLen); myTarget[targetLen - 1] = 0; numUBytes = u_strlen(myTarget); if (targetLen < 20) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; return 0; } myTarget += numUBytes; while(numUBytes < 10) { *myTarget++ = 0x0020; numUBytes++; } *myTarget++ = 0x0020; *myTarget++ = 0x002D; *myTarget++ = 0x0020; numUBytes += 3; myTargetSize = targetLen - numUBytes; if (en_lang) { numDispChar = uloc_getDisplayLanguage((const char*)source, enlocale, myTarget, myTargetSize, (UErrorCode *)&curr_thread->status); numUBytes += numDispChar; myTarget += (numDispChar); *myTarget++ = 0x0020; } numDispChar = uloc_getDisplayName((const char*)source, inlocale, myTarget, myTargetSize, (UErrorCode *)&curr_thread->status); numDispChar += numUBytes; return numDispChar; } int32_t xiu4_DisplayLocale(UChar32 *target, const int32_t targetLen, const char * source, const XIUA_LocaleList listlang) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = targetLen * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiu2_DisplayLocale((UChar *)curr_thread->work_buff, (i / 2),source, listlang); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiu8_DisplayLocale(UChar8 *target, const int32_t targetLen, const char * source, const XIUA_LocaleList listlang) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = targetLen * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiu2_DisplayLocale((UChar *)curr_thread->work_buff, (i / 2),source, listlang); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xicp_DisplayLocale(CpChar *target, const int32_t targetLen, const char * source, const XIUA_LocaleList listlang) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = targetLen * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiu2_DisplayLocale((UChar *)curr_thread->work_buff, (i / 2),source, listlang); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiua_GetTZoneOffset(const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar ZoneName[XIUA_MAXTIMEZONESIZE]; /* should not exceed 25 characters */ UChar *myWork = &ZoneName[0]; int32_t offset; UCalendarDateFields get_offset = UCAL_ZONE_OFFSET; UCalendarType cal_greg = UCAL_GREGORIAN; UCalendar * myCal; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (source && source[0]) { xiux_strToNUChars(ZoneName,source,XIUA_MAXTIMEZONESIZE); } else { myWork = NULL; } myCal = ucal_open ((const UChar *) myWork, -1, (const char*)curr_locale->locale,cal_greg, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; offset = ucal_get((const UCalendar *)myCal, get_offset, &curr_thread->status); ucal_close(myCal); if (U_FAILURE(curr_thread->status)) return 0; return offset / 1000; } int32_t xiua_DisplayTZone(char *target, const int32_t targetLen, const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (2 * xiu2_DisplayTZone((UChar *)target, (targetLen / 2),source)); case XDFUTF32: return (4 * xiu4_DisplayTZone((UChar32 *)target, (targetLen / 4),source)); case XDFUTF8: return xiu8_DisplayTZone((UChar8 *)target, targetLen,source); default: return xicp_DisplayTZone((CpChar *)target, targetLen,source); } return 0; } int32_t xiu2_DisplayTZone(UChar *target, const int32_t targetLen, const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar *myTarget = target; int32_t myTargetSize = targetLen; int32_t numDispChar = 0; int32_t ByteLen; int32_t offset; int32_t dstadj = 0; int32_t i, j, k; UBool dstind; char dstdsp[2] = "*"; char ZoneGMT[13]; UChar ZoneName[XIUA_MAXTIMEZONESIZE]; UCalendar * myCal; UConverter* myConv; UCalendarDisplayNameType get_tzname = UCAL_SHORT_STANDARD; UCalendarDateFields zone_offset = UCAL_ZONE_OFFSET; UCalendarDateFields dst_offset = UCAL_DST_OFFSET; UCalendarType cal_greg = UCAL_GREGORIAN; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; myConv = (UConverter*)curr_locale->conv; if (targetLen < 20) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; return 0; } xiux_strToNUChars(ZoneName,source,XIUA_MAXTIMEZONESIZE); myCal = ucal_open ((const UChar *) ZoneName, -1, (const char*)curr_locale->locale,cal_greg, &curr_thread->status); offset = ucal_get((const UCalendar *)myCal, zone_offset, &curr_thread->status); dstind = ucal_inDaylightTime ((const UCalendar *)myCal, &curr_thread->status); if (U_SUCCESS(curr_thread->status)) { if (dstind) { dstadj = ucal_get((const UCalendar *)myCal, dst_offset, &curr_thread->status); if (dstadj == 3600000) { dstdsp[0] = '*'; } else { dstdsp[0] = '#'; } } else { dstdsp[0] = ' '; } j = offset + dstadj; i = abs(j) / 1000; /* millisecs to secs */ j = i / 3600; /* hours */ k = i % 3600; /* remaining secs */ i = k / 60; /*mins*/ k = k % 60; /*secs*/ if (offset >= 0) { if (k == 0) { sprintf((char *)ZoneGMT,"GMT+%u:%02u%s ",j,i,dstdsp); } else { sprintf((char *)ZoneGMT,"GMT+%u:%02u:%02u ",j,i,k); } } else { sprintf((char *)ZoneGMT,"GMT-%u:%02u%s ",j,i,dstdsp); } } else { memset(ZoneGMT,' ',12); } ZoneGMT[12] = 0; xiux_strToUChars(myTarget,ZoneGMT); u_strncat(myTarget,ZoneName,myTargetSize); myTarget[myTargetSize-1] = 0; ByteLen = u_strlen(myTarget); if (U_SUCCESS(curr_thread->status) && (ByteLen + 14) <= targetLen) { myTarget += ByteLen; *myTarget++ = 0x0020; *myTarget++ = 0x0028; ByteLen += 3; myTargetSize -= (ByteLen + 1); if (dstind) get_tzname = UCAL_SHORT_DST; numDispChar = ucal_getTimeZoneDisplayName ((const UCalendar *)myCal, get_tzname, (const char*)curr_locale->locale, myTarget, myTargetSize, &curr_thread->status); if (U_FAILURE(curr_thread->status)) { *myTarget++ = 0x003F; *myTarget++ = 0x003F; *myTarget++ = 0x003F; } if (myTarget[0] == 0x0047 && myTarget[1] == 0x004D && myTarget[2] == 0x0054 && (myTarget[3] == 0x002B || myTarget[3] == 0x002D)) { myTarget -= 2; ByteLen -= 3; numDispChar = 0; } else { myTarget += numDispChar; *myTarget++ = 0x0029; } *myTarget++ = 0; } ucal_close(myCal); numDispChar += ByteLen; return numDispChar; } int32_t xiu4_DisplayTZone(UChar32 *target, const int32_t targetLen, const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = targetLen * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiu2_DisplayTZone((UChar *)curr_thread->work_buff, (i / 2),source); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiu8_DisplayTZone(UChar8 *target, const int32_t targetLen, const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = targetLen * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiu2_DisplayTZone((UChar *)curr_thread->work_buff, (i / 2),source); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xicp_DisplayTZone(CpChar *target, const int32_t targetLen, const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = targetLen * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiu2_DisplayTZone((UChar *)curr_thread->work_buff, (i / 2),source); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiua_CharLenMax(void) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (curr_locale->format >= XDFCODEPAGE) { return xicp_CharLenMax(); } return 4; } int32_t xiu2_CharLenMax(void) { return 2; } int32_t xiu4_CharLenMax(void) { return 1; } int32_t xiu8_CharLenMax(void) { return 4; } int32_t xicp_CharLenMax(void) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (curr_locale->codeset <= XCPMAX) return CodeSetMaxLen[curr_locale->codeset]; return 1; } int32_t xiua_CharLenMin(void) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (curr_locale->format == XDFUTF16) return 2; if (curr_locale->format == XDFUTF32) return 4; return 1; } int32_t xiu2_CharLenMin(void) { return 1; } int32_t xiu4_CharLenMin(void) { return 1; } int32_t xiu8_CharLenMin(void) { return 1; } int32_t xicp_CharLenMin(void) { return 1; } int32_t xiua_CharLen(const char * pointer) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (2 * xiu2_CharLen((const UChar *) pointer)); case XDFUTF32: return 4; case XDFUTF8: return xiu8_CharLen((const UChar8 *)pointer); default: return cpCharLen((const CpCharU *)pointer, curr_thread); } return 1; } int32_t xiu2_CharLen(const UChar * pointer) { if (UTF_IS_SURROGATE(*pointer)) return 2; return 1; } int32_t xiu4_CharLen(const UChar32 * pointer) { if (*pointer) return 1; return 1; } int32_t xiu8_CharLen(const UChar8 * pointer) { int32_t i; i = xbytesFromUTF8[(UChar8U)*pointer]; if (i > 0) return i; return 1; } int32_t xicp_CharLen(const CpChar * pointer) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); return cpCharLen((CpCharU *)pointer, curr_thread); } int32_t xiua_CharCnt(const char *source, const int32_t limit) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (limit >= 0) { return xiu2_CharCnt((const UChar *)source,(limit/2)); } return xiu2_CharCnt((const UChar *)source,limit); case XDFUTF32: if (limit >= 0) { return xiu4_CharCnt((const UChar32 *)source,(limit/4)); } return xiu4_CharCnt((const UChar32 *)source,limit); case XDFUTF8: return xiu8_CharCnt((const UChar8 *)source,limit); default: return xicp_CharCnt((const CpChar *)source,limit); } return 1; } int32_t xiu2_CharCnt(const UChar *source, const int32_t limit) { XIUA_Thread * curr_thread; int32_t sourceLength = 0; int32_t sourceIndex = 0; UChar ch; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = source[sourceIndex]; while (ch && (limit < 0 || sourceIndex < limit)) { if (UTF_IS_SURROGATE(*source)) sourceIndex ++; sourceIndex ++; /* Next lead byte */ sourceLength++; ch = source[sourceIndex]; } return sourceLength; } int32_t xiu4_CharCnt(const UChar32 *source, const int32_t limit) { XIUA_Thread * curr_thread; int32_t sourceLength = 0; UChar32 ch; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = source[sourceLength]; while (ch && (limit < 0 || sourceLength < limit)) { sourceLength++; ch = source[sourceLength]; } return sourceLength; } int32_t xiu8_CharCnt(const UChar8 *source, const int32_t limit) { XIUA_Thread * curr_thread; int32_t sourceLength = 0; int32_t sourceIndex = 0; UChar8U ch; uint32_t inBytes; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = (UChar8U)source[sourceIndex]; while (ch && (limit < 0 || sourceIndex < limit)) { inBytes = xbytesFromUTF8[ch]; /* lookup current sequence length */ if (inBytes < 1) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return sourceLength; } sourceLength++; sourceIndex += inBytes; /* Next lead byte */ ch = (UChar8U)source[sourceIndex]; } return sourceLength; } int32_t xicp_CharCnt(const CpChar *source, const int32_t limit) { XIUA_Thread * curr_thread; int32_t sourceLength = 0; int32_t sourceIndex = 0; UChar8 ch; uint32_t inBytes; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = source[sourceIndex]; while (ch && (limit < 0 || sourceIndex < limit)) { inBytes = cpCharLen((CpCharU *)&source[sourceIndex], curr_thread); /* lookup current sequence length */ if (U_FAILURE(curr_thread->status)) break; sourceLength++; sourceIndex += inBytes; /* Next lead byte */ ch = source[sourceIndex]; } return sourceLength; } char * xiua_CharNext(const char *pointer) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)xiu2_CharNext((const UChar *)pointer); case XDFUTF32: return (char *)xiu4_CharNext((const UChar32 *)pointer); case XDFUTF8: return (char *)xiu8_CharNext((const UChar8 *)pointer); default: return (char *)xicp_CharNext((const CpChar *)pointer); } return NULL; } UChar * xiu2_CharNext(const UChar *pointer) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; if (UTF_IS_SURROGATE(*pointer)) return (UChar *)pointer+2; return (UChar *)pointer+1; } UChar32 * xiu4_CharNext(const UChar32 *pointer) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; return (UChar32 *)pointer+1; } UChar8 * xiu8_CharNext(const UChar8 *pointer) { XIUA_Thread * curr_thread; uint32_t inBytes; /* Total number of bytes in the current UTF8 sequence */ curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; inBytes = xbytesFromUTF8[(UChar8U)*pointer]; /* lookup current sequence length */ if (inBytes < 1) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return NULL; } return (UChar8 *)pointer+inBytes; } CpChar * xicp_CharNext(const CpChar *pointer) { XIUA_Thread * curr_thread; uint32_t inBytes; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; inBytes = cpCharLen((CpCharU *)pointer, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; return (CpChar *)pointer+inBytes; } char * xiua_CharPrev(const char *pointer, const char *source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)xiu2_CharPrev((const UChar *)pointer,(const UChar *)source); case XDFUTF32: return (char *)xiu4_CharPrev((const UChar32 *)pointer,(const UChar32 *)source); case XDFUTF8: return (char *)xiu8_CharPrev((const UChar8 *)pointer,(const UChar8 *)source); default: return (char *)xicp_CharPrev((const CpChar *)pointer,(const CpChar *)source); } return NULL; } UChar * xiu2_CharPrev(const UChar *pointer, const UChar *source) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; if (source >= pointer) return NULL; if (UTF_IS_SURROGATE(*pointer)) return (UChar *)pointer-2; return (UChar *)pointer-1; } UChar32 * xiu4_CharPrev(const UChar32 *pointer, const UChar32 *source) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; if (source >= pointer) return NULL; return (UChar32 *)pointer-1; } UChar8 * xiu8_CharPrev(const UChar8 *pointer, const UChar8 *source) { XIUA_Thread * curr_thread; UChar8U *myPointer = (UChar8U *)pointer; uint32_t inBytes = 0; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (pointer == NULL) return NULL; i = source - pointer; if (i <= 0) return NULL; if (i > 4) i = 4; while (i > 0) { myPointer--; inBytes = xbytesFromUTF8[*myPointer]; /* lookup current sequence length */ if (inBytes == (uint32_t)i) break; /* found new lead byte */ if (inBytes < 0) { /* Invalid trailing byte */ curr_thread->status = U_ILLEGAL_CHAR_FOUND; return NULL; } i--; } if (i < 1) { /* lead byte not found */ curr_thread->status = U_ILLEGAL_CHAR_FOUND; return NULL; } return (UChar8 *)myPointer; } CpChar * xicp_CharPrev(const CpChar *pointer, const CpChar *source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; CpChar *myPointer = (CpChar *)source; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (pointer == NULL) return NULL; if (source >= pointer) return NULL; if (curr_locale->codeset == XCP1BYTE) return (myPointer-1); i = 0; while (myPointer+i < pointer) { myPointer += i; i = cpCharLen((CpCharU *)pointer, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; } return myPointer; } U_CAPIX int32_t U_EXPORTX xiua_ValidateStr(const char *source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t rc; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: rc = xiu2_ValidateStr((const UChar *)source); if (rc > 0) return rc * 2; return rc; case XDFUTF32: rc = xiu4_ValidateStr((const UChar32 *)source); if (rc > 0) return rc * 4; return rc; case XDFUTF8: return xiu8_ValidateStr((const UChar8 *)source); default: return xicp_ValidateStr((const CpChar *)source); } return 1; } U_CAPIX int32_t U_EXPORTX xiu2_ValidateStr(const UChar *source) { XIUA_Thread * curr_thread; UChar *ch; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = (UChar *)source; while(*ch != 0) { if (UTF_IS_SURROGATE(*ch)) { if (UTF_IS_SECOND_SURROGATE(*ch)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - source; } ch++; if (!UTF_IS_SECOND_SURROGATE(*ch)) { ch--; curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - source; } } if (*ch == 0xFFFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - source; } ch++; } return -1; } U_CAPIX int32_t U_EXPORTX xiu4_ValidateStr(const UChar32 *source) { XIUA_Thread * curr_thread; UChar32 *ch; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = (UChar32 *)source; while(*ch) { if (!UTF_IS_UNICODE_CHAR(*ch)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - source; } ch++; } return -1; } U_CAPIX int32_t U_EXPORTX xiu8_ValidateStr(const UChar8 *source) { XIUA_Thread * curr_thread; UChar8U *ch; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = (UChar8U *)source; while(*ch) { i = xbytesFromUTF8[*ch]; switch (i) { case 1: break; case 2: if (*ch < 0xC2) /* must be shortest form */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } if (!UTF8_IS_TRAIL(ch[1])) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } break; case 3: if ((*ch == 0xE0) && (ch[1] >= 0xA0)) /* must be shortest form */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } else if ((*ch == 0xED) && (ch[1] >= 0xA0)) /* no surrogates */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } else if (*ch == 0xEF) { /* U+FDD0 to U+FDEF are invalid (User internal use area)*/ if ((ch[1] == 0xB7) && (ch[2] >= 0x90) && (ch[2] <= 0xAF)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } /* U+FFFE & U+FFFF are invalid */ if ((ch[1] == 0xBF) && (ch[2] >= 0xBE)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } } if ((!UTF8_IS_TRAIL(ch[1])) || (!UTF8_IS_TRAIL(ch[2]))) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } break; case 4: if ((*ch == 0xF0) && (ch[1] < 0x90)) /* must be shortest form */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } else if ((*ch == 0xF4) && (ch[1] > 0x80)) /* can not exceed U+10FFFF */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } if ((ch[1] & 0x0F) == 0x0F) /* U+nFFFE & U+nFFFF are invalid */ { if ((ch[2] == 0xBF) && (ch[3] >= 0xBE)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } } if ((!UTF8_IS_TRAIL(ch[1])) || (!UTF8_IS_TRAIL(ch[2])) || (!UTF8_IS_TRAIL(ch[3]))) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } break; default: curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } ch += i; } return -1; } U_CAPIX int32_t U_EXPORTX xicp_ValidateStr(const CpChar *source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; CpCharU *ch; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; ch = (CpCharU *)source; if (*ch == 0) return -1; switch(curr_locale->codeset) { case XCP1BYTE: return -1; case XCPSJIS: while (*ch) { if ((DBCStable[*ch] & 0x04)) { ch++; if (!(DBCStable[*ch] & 0x08)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return (ch - (CpCharU *)source) - 1; } } else if (!(DBCStable[*ch] & 0x03)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch++; } break; case XCPKSC: while (*ch) { if ((DBCStable[*ch] & 0x40)) { ch++; if (!(DBCStable[*ch] & 0x80)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return (ch - (CpCharU *)source) - 1; } } else if (!(DBCStable[*ch] & 0x01)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch++; } break; case XCPBIG5: while (*ch) { if ((DBCStable[*ch] & 0x10)) { ch++; if (!(DBCStable[*ch] & 0x20)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return (ch - (CpCharU *)source) - 1; } } else if (!(DBCStable[*ch] & 0x01)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch++; } break; case XCP936: while (*ch) { if ((DBCStable[*ch] & 0x10)) { ch++; if (!(DBCStable[*ch] & 0x10)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return (ch - (CpCharU *)source) - 1; } } else if (!(DBCStable[*ch] & 0x01)) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch++; } break; case XCPEUCJP: while (*ch) { i = ch[0]; if (i >= 0xA1 && i <= 0xFE) { i = ch[1]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 2; } else if (i == 0x8E) /* SS2 */ { i = ch[1]; if (i < 0xA1 || i > 0xDF) /* HANKATA */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 2; } else if (i == 0x8F) /* SS3 */ { i = ch[1]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } i = ch[2]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 3; } else if (i == 0x7F) { ch += 1; } else { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } } break; case XCPEUCTW: while (*ch) { i = ch[0]; if (i >= 0xA1 && i <= 0xFE) { i = ch[1]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 2; } else if (i == 0x8E) /* SS2 */ { i = ch[1]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } i = ch[2]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } i = ch[3]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 4; } else if (i == 0x7F) { ch += 1; } else { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } } break; case XCPEUCCN: case XCPEUCKR: while (*ch) { i = ch[0]; if (i >= 0xA1 && i <= 0xFE) { i = ch[1]; if (i < 0xA1 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 2; } else if (i == 0x7F) { ch += 1; } else { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } } break; case XCPGB18030: while (*ch) { i = ch[0]; if (i >= 0xFF) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } if (i >= 0x81) { i = ch[1]; if (i == 0x7F || i < 0x30 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } if (i >= 0x40) { ch += 2; } else { i = ch[2]; if (i < 0x81 || i > 0xFE) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } i = ch[3]; if (i < 0x30 || i > 0x39) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return ch - (CpCharU *)source; } ch += 4; } } else { ch += 1; } } break; case XCP2022: case XCP2022J: case XCP2022K: case XCP2022C: curr_thread->status = U_UNSUPPORTED_ERROR; default: return strlen((const char *)source); } return -1; } U_CAPIX int32_t U_EXPORTX xiua_FixStr(char *source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (2 * xiu2_FixStr((UChar *)source)); case XDFUTF32: return (4 * xiu4_FixStr((UChar32 *)source)); case XDFUTF8: return xiu8_FixStr((UChar8 *)source); default: return xicp_FixStr((CpChar *)source); } return 1; } U_CAPIX int32_t U_EXPORTX xiu2_FixStr(UChar *source) { XIUA_Thread * curr_thread; UChar *ch; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = source; while(*ch != 0) { if (UTF_IS_SURROGATE(*ch)) { if (!ch[1]) { *ch = 0; break; } ch++; } ch++; } return ch - source; } U_CAPIX int32_t U_EXPORTX xiu4_FixStr(UChar32 *source) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; return xiu4_strlen(source); } U_CAPIX int32_t U_EXPORTX xiu8_FixStr(UChar8 *source) { XIUA_Thread * curr_thread; UChar8U *ch; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ch = (UChar8U *)source; while(*ch) { i = xbytesFromUTF8[256]; if (i == 0) { i = 1; } else if (i > 1) { for(j=1;jstatus = U_ILLEGAL_CHAR_FOUND; return ch - (UChar8U *)source; } ch += i; } return ch - (UChar8U *)source; } U_CAPIX int32_t U_EXPORTX xicp_FixStr(CpChar *source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; CpCharU *ch; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; ch = (CpCharU *)source; if (*ch == 0) return 0; switch(curr_locale->codeset) { case XCP1BYTE: return strlen((const char *)source); case XCPSJIS: while (*ch) { if ((DBCStable[*ch] & 0x04)) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } ch++; } ch++; } break; case XCPKSC: while (*ch) { if ((DBCStable[*ch] & 0x40)) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } ch++; } ch++; } break; case XCPBIG5: case XCP936: while (*ch) { if ((DBCStable[*ch] & 0x10)) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } ch++; } ch++; } break; case XCPEUCJP: while (*ch) { i = ch[0]; if ((i >= 0xA1 && i <= 0xFE) || (i == 0x8E)) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } ch += 2; } else if (i == 0x8F) /* SS3 */ { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } if (!ch[2]) { *ch = 0; return ch - (CpCharU *)source; } ch += 3; } else { ch += 1; } } break; case XCPEUCTW: while (*ch) { i = ch[0]; if (i >= 0xA1 && i <= 0xFE) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } ch += 2; } else if (i <= 0x8E) /* SS2 */ { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } if (!ch[2]) { *ch = 0; return ch - (CpCharU *)source; } if (!ch[3]) { *ch = 0; return ch - (CpCharU *)source; } ch += 4; } else { ch += 1; } } break; case XCPEUCCN: case XCPEUCKR: while (*ch) { i = ch[0]; if (i >= 0xA1 && i <= 0xFE) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } ch += 2; } else { ch += 1; } } break; case XCPGB18030: while (*ch) { i = ch[0]; if (i >= 0x81 && i <= 0xFE) { if (!ch[1]) { *ch = 0; return ch - (CpCharU *)source; } if (ch[1] >= 0x40) { ch += 2; } else { if (!ch[2] || !ch[3]) { *ch = 0; return ch - (CpCharU *)source; } ch += 4; } } else { ch += 1; } } break; case XCP2022: case XCP2022J: case XCP2022K: case XCP2022C: curr_thread->status = U_UNSUPPORTED_ERROR; default: return strlen((const char *)source); } return ch - (CpCharU *)source; } int32_t xiua_MatchStr(const char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t indx; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) { indx = xiu2_MatchStr((const UChar *)str1,(const UChar *)str2,(length/2)); } else { indx = xiu2_MatchStr((const UChar *)str1,(const UChar *)str2,length); } if (indx < 0) return indx; return (indx*2); case XDFUTF32: if (length > 0) { indx = xiu4_MatchStr((const UChar32 *)str1,(const UChar32 *)str2,(length/4)); } else { indx = xiu4_MatchStr((const UChar32 *)str1,(const UChar32 *)str2,length); } if (indx < 0) return indx; return (indx*4); default: return xicp_MatchStr((const CpChar *)str1,(const CpChar *)str2,length); } return 0; } int32_t xiu2_MatchStr(const UChar *str1, const UChar * str2, const int32_t length) { int32_t i = 0; if (length < 0) { for(i=0;;i++) { if (str1[i] != str2[i]) return i; if (str1[i] == 0) return -1; } } for(i=0;iCurr_locale; switch (curr_locale->format) { case XDFUTF16: return xiu2_RomanDigitStr((UChar *)str); case XDFUTF32: return xiu4_RomanDigitStr((UChar32 *)str); case XDFUTF8: return xiu8_RomanDigitStr((UChar8 *)str); default: return xicp_RomanDigitStr((CpChar *)str); } return 0; } int32_t xiu2_RomanDigitStr(UChar *str) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar32 * UStr; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (u_strlen(str) + 1) * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr = (UChar32 *)&curr_thread->work_buff[0]; xiua_UTF16toUTF32 (UStr, (i / 4), str, -1); if (U_FAILURE(curr_thread->status)) return 0; xiu4_RomanDigitStr(UStr); return xiua_UTF32toUTF16 (str, (i / 4), UStr, -1); } U_CAPIX int32_t U_EXPORTX xiu4_RomanDigitStr(UChar32 *str) { UChar32 uch = 1; int i = 0; while (uch) { uch = str[i]; if (uch == 0x2217 || uch == 0x066D || uch == 0x2731) { uch = 0x002A; /* '*' -> ASCII '*' */ } else if (uch == 0x201A || uch == 0x060C || uch == 0x3001) { uch = 0x002C; /* ',' -> ASCII ',' */ } else if (uch == 0x2212 || (uch >= 0x2010 && uch <= 0x2012)) { uch = 0x002D; /* '-' -> ASCII '-' */ } else if (uch == 0x06D4 || uch == 0x3002) { uch = 0x002E; /* '.' -> ASCII '.' */ } else if (uch == 0x2215 || uch == 0x2044) { uch = 0x002F; /* '/' -> ASCII '/' */ } else if (uch >= 0xFF01 && uch <= 0xFF5E) { uch -= 0xFEE0; /* full width character -> ASCII Unicode char */ } else if (u_isdigit(uch)) { uch = (UChar32)u_charDigitValue(uch) + 0x0030; } str[i] = uch; i++; } return i-1; } int32_t xiu8_RomanDigitStr(UChar8 *str) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar32 * UStr; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str) + 1) * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr = (UChar32 *)&curr_thread->work_buff[0]; xiua_UTF8toUTF32 (UStr, (i / 4), (char *)str, -1); if (U_FAILURE(curr_thread->status)) return 0; xiu4_RomanDigitStr(UStr); return xiua_UTF32toUTF8 ((char *)str, (i / 4), UStr, -1); } int32_t xicp_RomanDigitStr(CpChar *str) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar32 * UStr; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str) + 1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr = (UChar32 *)&curr_thread->work_buff[i]; xiua_ChartoUTF32 (UStr, (i / 4), (char *)str, -1); if (U_FAILURE(curr_thread->status)) return 0; xiu4_RomanDigitStr(UStr); return xiua_UTF32toChar((char *)str, (i / 4), UStr, -1); } int32_t xiua_Collate(const char *str1, const char * option, const char * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return xiu2_Collate((const UChar *)str1, option,(const UChar *)str2); case XDFUTF32: return xiu4_Collate((const UChar32 *)str1, option,(const UChar32 *)str2); case XDFUTF8: return xiu8_Collate((const UChar8 *)str1, option,(const UChar8 *)str2); default: return xicp_Collate((const CpChar *)str1, option,(const CpChar *)str2); } return 0; } int32_t xiu2_Collate (const UChar *str1, const char * option, const UChar * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UBool if_lt = FALSE; UBool if_eq = FALSE; UBool if_gt = FALSE; UCollationStrength coll_str = UCOL_TERTIARY; UCollationResult coll_res = UCOL_EQUAL; int i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; /* set while parseing options */ i = strlen(option); if (i < 1) return -1; while (i > 0) { i--; switch (option[i]) { case '=': if_eq = TRUE; break; case '<': if_lt = TRUE; break; case '>': if_gt = TRUE; break; case '!': if_lt = (UBool)(!if_lt); if_eq = (UBool)(!if_eq); if_gt = (UBool)(!if_gt); break; case '?': coll_str = UCOL_PRIMARY; break; case ':': coll_str = UCOL_SECONDARY; break; case '#': coll_str = UCOL_IDENTICAL; break; case ' ': break; default: return -1; } } if (!(if_lt || if_eq || if_gt)) return -1; if (if_lt && if_eq && if_gt) return -1; curr_thread->status = U_ZERO_ERROR; coll_res = xiu2_strcollEx(str1, str2, (XIUA_CollStrength) coll_str); if (U_FAILURE(curr_thread->status)) return -1; if (coll_res == UCOL_EQUAL) { if (if_eq) return 1; /* eq test was true */ } else { if (coll_res == UCOL_GREATER) { if (if_gt) return 1; /* gt test was true */ } else { if (if_lt) return 1; /* lt test was true */ } } return 0; /* Return false */ } int32_t xiu4_Collate(const UChar32 *str1, const char * option, const UChar32 * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; int j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (xiu4_strlen(str1) + 1) * 4; j = (xiu4_strlen(str2) + 1) * 4; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF32toUTF16 (UStr1, (i / 2), str1, -1); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF32toUTF16 (UStr2, (j / 2), str2, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_Collate(UStr1,option,UStr2); } int32_t xiu8_Collate(const UChar8 *str1, const char * option, const UChar8 * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; int j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str1) + 1) * 2; j = (strlen((const char *)str2) + 1) * 2; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF8toUTF16(UStr1, (i / 2), (char *)str1, -1); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF8toUTF16(UStr2, (j / 2), (char *)str2, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_Collate(UStr1,option,UStr2); } int32_t xicp_Collate(const CpChar *str1, const char * option, const CpChar * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; int j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str1) + 1) * 2; j = (strlen((const char *)str2) + 1) * 2; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_ChartoUTF16(UStr1, (i / 2), (char *)str1, -1); if (U_FAILURE(curr_thread->status)) return 0; xiua_ChartoUTF16(UStr2, (j / 2), (char *)str2, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_Collate(UStr1,option,UStr2); } int32_t xiua_strcollEx(const char *str1, const char * str2, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return xiu2_strcollEx((UChar *)str1, (UChar *)str2, strength); case XDFUTF32: return xiu4_strcollEx((UChar32 *)str1, (UChar32 *)str2, strength); case XDFUTF8: return xiu8_strcollEx((UChar8 *)str1, (UChar8 *)str2, strength); default: return xicp_strcollEx((CpChar *)str1, (CpChar *)str2, strength); } return 0; } int32_t xiu2_strcollEx(const UChar *str1, const UChar * str2, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UCollator* str_cmp; UCollationStrength coll_str; UCollationResult coll_res = UCOL_EQUAL; UColAttributeValue attr_case = UCOL_ON; UColAttributeValue attr_hand = UCOL_NON_IGNORABLE; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; str_cmp = ucol_open(curr_locale->locale, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; coll_str = (UCollationStrength)strength; if (coll_str == UCOL_PRIMARY) attr_hand = UCOL_SHIFTED; ucol_setAttribute(str_cmp, UCOL_ALTERNATE_HANDLING, attr_hand, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; ucol_setStrength(str_cmp,coll_str); if (coll_str <= UCOL_SECONDARY) attr_case = UCOL_OFF; ucol_setAttribute(str_cmp, UCOL_CASE_LEVEL, attr_case, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; coll_res = ucol_strcoll(str_cmp,str1,u_strlen(str1),str2,u_strlen(str2)); ucol_close(str_cmp); return (int32_t)coll_res; } int32_t xiu4_strcollEx(const UChar32 *str1, const UChar32 * str2, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; int j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (xiu4_strlen(str1) + 1) * 4; j = (xiu4_strlen(str2) + 1) * 4; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF32toUTF16 (UStr1, (i / 2), str1, -1); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF32toUTF16 (UStr2, (j / 2), str2, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strcollEx(UStr1,UStr2,strength); } int32_t xiu8_strcollEx(const UChar8 *str1, const UChar8* str2, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; int j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str1) + 1) * 2; j = (strlen((const char *)str2) + 1) * 2; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF8toUTF16 (UStr1, (i / 2), (char *)str1, -1); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF8toUTF16 (UStr2, (j / 2), (char *)str2, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strcollEx(UStr1,UStr2,strength); } int32_t xicp_strcollEx(const CpChar *str1, const CpChar *str2, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; int j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str1) + 1) * 2; j = (strlen((const char *)str2) + 1) * 2; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_ChartoUTF16 (UStr1, (i / 2), (char *)str1, -1); if (U_FAILURE(curr_thread->status)) return 0; xiua_ChartoUTF16 (UStr2, (j / 2), (char *)str2, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strcollEx(UStr1,UStr2,strength); } int32_t xiua_strncollEx(const char *str1, const char * str2, const int32_t length, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return xiu2_strncollEx((const UChar *)str1, (const UChar *)str2, (length/2), strength); case XDFUTF32: return xiu4_strncollEx((const UChar32 *)str1, (const UChar32 *)str2, (length/4), strength); case XDFUTF8: return xiu8_strncollEx((const UChar8 *)str1, (const UChar8 *)str2, length, strength); default: return xicp_strncollEx((const CpChar *)str1, (const CpChar *)str2, length, strength); } return 0; } int32_t xiu2_strncollEx(const UChar *str1, const UChar * str2, const int32_t length, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t str1len; int32_t str2len; UCollator* str_cmp; UCollationStrength coll_str; UCollationResult coll_res = UCOL_EQUAL; UColAttributeValue attr_case = UCOL_ON; UColAttributeValue attr_hand = UCOL_NON_IGNORABLE; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; str1len = u_strlen(str1); if (str1len > length) str1len = length; if (str1len > 0 && UTF_IS_SECOND_SURROGATE(str1[str1len-1])) str1len--; str2len = u_strlen(str2); if (str2len > length) str2len = length; if (str2len > 0 && UTF_IS_SECOND_SURROGATE(str2[str2len-1])) str2len--; str_cmp = ucol_open(curr_locale->locale, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; coll_str = (UCollationStrength)strength; if (coll_str == UCOL_PRIMARY) attr_hand = UCOL_SHIFTED; ucol_setAttribute(str_cmp, UCOL_ALTERNATE_HANDLING, attr_hand, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; ucol_setStrength(str_cmp,coll_str); if (coll_str <= UCOL_SECONDARY) attr_case = UCOL_OFF; ucol_setAttribute(str_cmp, UCOL_CASE_LEVEL, attr_case, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; coll_res = ucol_strcoll(str_cmp,str1,str1len,str2,str2len); ucol_close(str_cmp); return (int32_t)coll_res; } int32_t xiu4_strncollEx(const UChar32 *str1, const UChar32 * str2, const int32_t length, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (length+1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF32toUTF16 (UStr1, length+1, str1,length); UStr1[length] = 0; if (U_FAILURE(curr_thread->status)) { if (curr_thread->status != U_BUFFER_OVERFLOW_ERROR) return 0; } xiua_UTF32toUTF16 (UStr2, length+1, str2,length); UStr2[length] = 0; if (U_FAILURE(curr_thread->status)) { if (curr_thread->status != U_BUFFER_OVERFLOW_ERROR) return 0; } if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strncollEx(UStr1,UStr2,length,strength); } int32_t xiu8_strncollEx(const UChar8 *str1, const UChar8* str2, const int32_t length, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (length+1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF8toUTF16 (UStr1, length+1, (char *)str1,length); UStr1[length] = 0; if (U_FAILURE(curr_thread->status)) { if (curr_thread->status != U_BUFFER_OVERFLOW_ERROR) return 0; } xiua_UTF8toUTF16 (UStr2, length+1, (char *)str2,length); UStr2[length] = 0; if (U_FAILURE(curr_thread->status)) { if (curr_thread->status != U_BUFFER_OVERFLOW_ERROR) return 0; } return xiu2_strncollEx(UStr1,UStr2,length,strength); } int32_t xicp_strncollEx(const CpChar *str1, const CpChar *str2, const int32_t length, const XIUA_CollStrength strength) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (length+1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_ChartoUTF16 (UStr1, length+1, (char *)str1,length); UStr1[length] = 0; if (U_FAILURE(curr_thread->status)) { if (curr_thread->status != U_BUFFER_OVERFLOW_ERROR) return 0; } xiua_ChartoUTF16 (UStr2, length+1, (char *)str2,length); UStr1[length] = 0; if (U_FAILURE(curr_thread->status)) { if (curr_thread->status != U_BUFFER_OVERFLOW_ERROR) return 0; } return xiu2_strncollEx(UStr1,UStr2,length,strength); } int32_t xiua_strcmp(const char *str1, const char * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return u_strcmpCodePointOrder((UChar *)str1,(UChar *)str2); case XDFUTF32: return xiu4_strcmp((UChar32 *)str1, (UChar32 *)str2); case XDFUTF8: return strcmp(str1,str2); default: return strcmp(str1,str2); } return 0; } int32_t xiu2_strcmp(const UChar *str1, const UChar * str2) { return u_strcmpCodePointOrder(str1,str2); } int32_t xiu4_strcmp(const UChar32 *str1, const UChar32 * str2) { int32_t rc; for(;;) { rc = (int32_t)*str1 - (int32_t)*str2; if(rc != 0 || *str1 == 0) { return rc; } ++str1; ++str2; } } int32_t xiu8_strcmp(const UChar8 *str1, const UChar8 * str2) { return strcmp((const char *)str1,(const char *)str2); } int32_t xicp_strcmp(const CpChar *str1, const CpChar * str2) { return strcmp((const char *)str1,(const char *)str2); } int32_t xiua_strncmp(const char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) i = (length/2); else i = length; return xiu2_strncmp((const UChar *)str1,(const UChar *)str2,i); case XDFUTF32: if (length > 0) i = (length/4); else i = length; return xiu4_strncmp((const UChar32 *)str1,(const UChar32 *)str2, i); case XDFUTF8: return strncmp(str1,str2,length); default: return strncmp(str1,str2,length); } return 0; } int32_t xiu2_strncmp(const UChar *str1, const UChar * str2, const int32_t length) { int32_t c1, c2; int32_t diff; int32_t leng = length; if(leng > 0) { /* rotate each code unit's value so that surrogates get the highest values */ for(;;) { c1=*str1; c1+=utf16Fixup[c1>>11]; /* additional "fix-up" line */ c2=*str2; c2+=utf16Fixup[c2>>11]; /* additional "fix-up" line */ /* now c1 and c2 are in UTF-32-compatible order */ diff=c1-c2; if(diff!=0 || c1==0 || --leng == 0) { return diff; } ++str1; ++str2; } } else { return 0; } } int32_t xiu4_strncmp(const UChar32 *str1, const UChar32 * str2, const int32_t length) { int32_t rc; int32_t leng = length; if(leng > 0) { for(;;) { rc = (int32_t)*str1 - (int32_t)*str2; if(rc != 0 || *str1 == 0 || --leng == 0) { return rc; } ++str1; ++str2; } } else { return 0; } } int32_t xiu8_strncmp(const UChar8 *str1, const UChar8 * str2, const int32_t length) { return strncmp((const char *)str1,(const char *)str2,length); } int32_t xicp_strncmp(const CpChar *str1, const CpChar * str2, const int32_t length) { return strncmp((const char *)str1,(const char *)str2,length); } int32_t xiua_stricmp(const char *str1, const char * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return xiu2_stricmp((const UChar *)str1,(const UChar *)str2); case XDFUTF32: return xiu4_stricmp((const UChar32 *)str1,(const UChar32 *)str2); case XDFUTF8: return xiu8_stricmp((const UChar8 *)str1,(const UChar8 *)str2); default: return xicp_stricmp((const CpChar *)str1,(const CpChar *)str2); } return 0; } int32_t xiu2_stricmp(const UChar *str1, const UChar * str2) { return u_strcasecmp(str1,str2,U_FOLD_CASE_DEFAULT); } int32_t xiu4_stricmp(const UChar32 *str1, const UChar32 * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (xiu4_strlen(str1)+1) * 4; j = (xiu4_strlen(str2)+1) * 4; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF32toUTF16 (UStr1, (i/2), str1,-1); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF32toUTF16 (UStr2, (j/2), str2,-1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_stricmp(UStr1,UStr2); } int32_t xiu8_stricmp(const UChar8 *str1, const UChar8 *str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str1)+1) * 4; j = (strlen((const char *)str2)+1) * 4; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF8toUTF16 (UStr1, (i/2), (char *)str1,-1); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF8toUTF16 (UStr2, (j/2), (char *)str2,-1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_stricmp(UStr1,UStr2); } int32_t xicp_stricmp(const CpChar *str1, const CpChar *str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (strlen((const char *)str1)+1) * 4; j = (strlen((const char *)str2)+1) * 4; if (!chkWorkSize(i+j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_ChartoUTF16 (UStr1, (i/2), (char *)str1,-1); if (U_FAILURE(curr_thread->status)) return 0; xiua_ChartoUTF16 (UStr2, (j/2), (char *)str2,-1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_stricmp(UStr1,UStr2); } int32_t xiua_strnicmp(const char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) i = (length/2); else i = length; return xiu2_strnicmp((const UChar *)str1,(const UChar *)str2,i); case XDFUTF32: if (length > 0) i = (length/4); else i = length; return xiu4_strnicmp((const UChar32 *)str1,(const UChar32 *)str2, i); case XDFUTF8: return xiu8_strnicmp((const UChar8 *)str1,(const UChar8 *)str2,length); default: return xicp_strnicmp((const CpChar *)str1,(const CpChar *)str2,length); } return 0; } int32_t xiu2_strnicmp(const UChar *str1, const UChar * str2, const int32_t length) { return u_strncasecmp(str1,str2,length,U_FOLD_CASE_DEFAULT); } int32_t xiu4_strnicmp(const UChar32 *str1, const UChar32 * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (length+1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF32toUTF16 (UStr1, length+1, str1,length); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF32toUTF16 (UStr2, length+1, str2,length); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strnicmp(UStr1,UStr2,length); } int32_t xiu8_strnicmp(const UChar8 *str1, const UChar8* str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (length+1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_UTF8toUTF16 (UStr1, length+1, (char *)str1,length); if (U_FAILURE(curr_thread->status)) return 0; xiua_UTF8toUTF16 (UStr2, length+1, (char *)str2,length); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strnicmp(UStr1,UStr2,length); } int32_t xicp_strnicmp(const CpChar *str1, const CpChar* str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar * UStr1; UChar * UStr2; int i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = (length+1) * 4; if (!chkWorkSize(i*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } UStr1 = (UChar *)&curr_thread->work_buff[0]; UStr2 = (UChar *)&curr_thread->work_buff[i]; xiua_ChartoUTF16 (UStr1, length+1, (char *)str1,length); if (U_FAILURE(curr_thread->status)) return 0; xiua_ChartoUTF16 (UStr2, length+1, (char *)str2,length); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_strnicmp(UStr1,UStr2,length); } char * xiua_strcpy(char *str1, const char * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)u_strcpy((UChar *)str1,(const UChar *)str2); case XDFUTF32: xiu4_strncpyEx((UChar32 *)str1, (const UChar32 *)str2, -1); return str1; case XDFUTF8: return strcpy(str1,str2); default: return strcpy(str1,str2); } return 0; } char * xiua_strncpy(char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) i = (length/2); else i = length; return (char *)u_strncpy((UChar *)str1,(const UChar *)str2,i); case XDFUTF32: if (length > 0) i = (length/4); else i = length; xiu4_strncpyEx((UChar32 *)str1,(const UChar32 *)str2, i); return str1; default: return strncpy(str1,str2,length); } return 0; } int32_t xiua_strncpyEx(char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) i = (length/2); else i = length; return (2 * xiu2_strncpyEx((UChar *)str1,(const UChar *)str2,i)); case XDFUTF32: if (length > 0) i = (length/4); else i = length; return (2 * xiu4_strncpyEx((UChar32 *)str1,(const UChar32 *)str2, i)); case XDFUTF8: return xiu8_strncpyEx((UChar8 *)str1,(const UChar8 *)str2,length); default: return xicp_strncpyEx((CpChar *)str1,(const CpChar *)str2,length); } return 0; } int32_t xiu2_strncpyEx(UChar *str1, const UChar * str2, const int32_t length) { if (length > 0) { u_strncpy(str1,str2,length); str1[length-1] = 0; } else if (length < 0) { u_strcpy(str1,str2); } else { str1[0] = 0; } return xiu2_FixStr(str1); } int32_t xiu4_strncpyEx(UChar32 *str1, const UChar32 * str2, const int32_t length) { XIUA_Thread * curr_thread; int32_t i; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (length > 0) { for (i=0;i= length) i--; } else if (length < 0) { i = 0; while(str2[i] != 0) { str1[i] = str2[i]; i++; } } else { i = 0; } str1[i] = 0; return i; } int32_t xiu8_strncpyEx(UChar8 *str1, const UChar8 * str2, const int32_t length) { if (length > 0) { strncpy((char *)str1,(const char *)str2,length); str1[length-1] = 0; } else if (length < 0) { strcpy((char *)str1,(const char *)str2); } else { str1[0] = 0; } return xiu8_FixStr(str1); } int32_t xicp_strncpyEx(CpChar *str1, const CpChar * str2, const int32_t length) { if (length > 0) { strncpy((char *)str1,(const char *)str2,length); str1[length-1] = 0; } else if (length < 0) { strcpy((char *)str1,(const char *)str2); } else { str1[0] = 0; } return xicp_FixStr(str1); } char * xiua_strcat(char *str1, const char * str2) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)u_strcat((UChar *)str1,(const UChar *)str2); case XDFUTF32: xiu4_strncatEx((UChar32 *)str1, (const UChar32 *)str2, -1); return str1; default: return strcat(str1,str2); } return 0; } char * xiua_strncat(char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) i = (length/2); else i = length; return (char *)u_strncat((UChar *)str1,(const UChar *)str2,i); case XDFUTF32: if (length > 0) i = (length/4); else i = length; xiu4_strncatEx((UChar32 *)str1,(const UChar32 *)str2, i); return str1; default: return strncat(str1,str2,length); } return 0; } int32_t xiua_strncatEx(char *str1, const char * str2, const int32_t length) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int32_t i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (length > 0) i = (length/2); else i = length; return (2 * xiu2_strncatEx((UChar *)str1,(const UChar *)str2,i)); case XDFUTF32: if (length > 0) i = (length/4); else i = length; return (2 * xiu4_strncatEx((UChar32 *)str1,(const UChar32 *)str2, i)); case XDFUTF8: return xiu8_strncatEx((UChar8 *)str1,(const UChar8 *)str2,length); default: return xicp_strncatEx((C