/* ******************************************************************************* * * 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((CpChar *)str1,(const CpChar *)str2,length); } return 0; } int32_t xiu2_strncatEx(UChar *str1, const UChar * str2, const int32_t length) { if (length > 0) { u_strncat(str1,str2,length); str1[length-1] = 0; } else if (length < 0) { u_strcat(str1,str2); } else { str1[0] = 0; } return xiu2_FixStr(str1); } int32_t xiu4_strncatEx(UChar32 *str1, const UChar32 * str2, const int32_t length) { XIUA_Thread * curr_thread; int32_t i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; i = 0; while (str1[i]) i++; if (length > 0) { for (j=0;j 0) { strncat((char *)str1,(const char *)str2,length); str1[length-1] = 0; } else if (length < 0) { strcat((char *)str1,(const char *)str2); } else { str1[0] = 0; } return xiu8_FixStr(str1); } int32_t xicp_strncatEx(CpChar *str1, const CpChar * str2, const int32_t length) { if (length > 0) { strncat((char *)str1,(const char *)str2,length); str1[length-1] = 0; } else if (length < 0) { strcat((char *)str1,(const char *)str2); } else { str1[0] = 0; } return xicp_FixStr(str1); } int32_t xiua_strlen(const char *string) { 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 * u_strlen((const UChar *)string)); case XDFUTF32: return (4 * xiu4_strlen((const UChar32 *)string)); default: return strlen(string); } return 0; } int32_t xiu2_strlen(const UChar *string) { return u_strlen(string); } int32_t xiu4_strlen(const UChar32 *string) { const UChar32 *t = string; while(*t != 0) { ++t; } return t - string; } int32_t xiu8_strlen(const UChar8 *string) { return strlen((const char *)string); } int32_t xicp_strlen(const CpChar *string) { return strlen((const char *)string); } char * xiua_strchrEx(const char *string, const char * charptr) { 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_strchrEx((const UChar *)string,(const UChar *) charptr); case XDFUTF32: return (char *)xiu4_strchrEx((const UChar32 *)string,(const UChar32 *) charptr); case XDFUTF8: return (char *)xiu8_strchrEx((const UChar8 *)string,(const UChar8 *)charptr); default: return (char *)xicp_strchrEx((const CpChar *)string,(const CpChar *)charptr); } return 0; } UChar * xiu2_strchrEx(const UChar *string, const UChar * charptr) { UChar32 uch; UTF16_GET_CHAR_UNSAFE(charptr, 0, uch) return u_strchr32(string, uch); } UChar32 * xiu4_strchrEx(const UChar32 *string, const UChar32 * charptr) { UChar32 * ptr1; ptr1 = (UChar32 *)string; while (*ptr1) { if (*ptr1 == *charptr) return ptr1; ptr1++; } return(NULL); } UChar8 * xiu8_strchrEx(const UChar8 *string, const UChar8 * charptr) { XIUA_Thread * curr_thread; UChar8U * ptr1; UChar8U * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ptr1 = (UChar8U *)string; ptr2 = (UChar8U *)charptr; i = xbytesFromUTF8[*ptr2]; if (i < 1) return NULL; while (*ptr1) { j=0; while (jstatus = U_INVALID_CHAR_FOUND; return NULL; } ptr1 += j; } return(NULL); } CpChar * xicp_strchrEx(const CpChar *string, const CpChar * charptr) { XIUA_Thread * curr_thread; CpCharU * ptr1; CpCharU * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (CpCharU *)string; ptr2 = (CpCharU *)charptr; i = cpCharLen((CpCharU *)charptr, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; if (i < 1) return NULL; while (*ptr1) { j=0; while (jCurr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)u_strstr((const UChar *)string,(const UChar *) substring); case XDFUTF32: return (char *)xiu4_strstr((const UChar32 *)string,(const UChar32 *) substring); case XDFUTF8: return (char *)xiu8_strstr((const UChar8 *)string,(const UChar8 *)substring); default: return (char *)xicp_strstr((const CpChar *)string,(const CpChar *)substring); } return 0; } UChar * xiu2_strstr(const UChar *string, const UChar * substring) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; return u_strstr(string, substring); } UChar32 * xiu4_strstr(const UChar32 *string, const UChar32 * substring) { XIUA_Thread * curr_thread; const UChar32 * ptr1; const UChar32 * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ptr1 = string; j = xiu4_strlen(substring); while (*ptr1) { ptr2 = (UChar32 *)substring; for (i=0;istatus = U_ZERO_ERROR; ptr1 = (UChar8U *)string; j = strlen((const char *)substring); while (*ptr1) { ptr2 = (UChar8U *)substring; for (i=0;istatus = U_INVALID_CHAR_FOUND; return NULL; } ptr1 += i; } return(NULL); } CpChar * xicp_strstr(const CpChar *string, const CpChar * substring) { XIUA_Thread * curr_thread; CpCharU * ptr1; CpCharU * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (CpCharU *)string; j = strlen((const char *)substring); cpCharLen(ptr1, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; while (*ptr1) { ptr2 = (CpCharU *)substring; for (i=0;iCurr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)u_strpbrk((const UChar *)string,(const UChar *) charlst); case XDFUTF32: return (char *)xiu4_strpbrk((const UChar32 *)string,(const UChar32 *) charlst); case XDFUTF8: return (char *)xiu8_strpbrk((const UChar8 *)string,(const UChar8 *)charlst); default: return (char *)xicp_strpbrk((const CpChar *)string,(const CpChar *)charlst); } return 0; } UChar * xiu2_strpbrk(const UChar *string, const UChar * charlst) { return u_strpbrk(string, charlst); } UChar32 * xiu4_strpbrk(const UChar32 *string, const UChar32 * charlst) { UChar32 * ptr1; UChar32 * ptr2; ptr1 = (UChar32 *)string; while (*ptr1) { ptr2 = (UChar32 *)charlst; while (*ptr2) { if (*ptr1 == *ptr2) return ptr1; ptr2++; } ptr1++; } return(NULL); } UChar8 * xiu8_strpbrk(const UChar8 *string, const UChar8 * charlst) { XIUA_Thread * curr_thread; UChar8U * ptr1; UChar8U * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (UChar8U *)string; while (*ptr1) { ptr2 = (UChar8U *)charlst; while (*ptr2) { i = xbytesFromUTF8[*ptr2]; if (i < 1) { curr_thread->status = U_INVALID_CHAR_FOUND; return (UChar8 *)ptr1; } for (j=0;jstatus = U_INVALID_CHAR_FOUND; return (UChar8 *)ptr1; } ptr1 += i; } return(NULL); } CpChar * xicp_strpbrk(const CpChar *string, const CpChar * charlst) { XIUA_Thread * curr_thread; CpCharU * ptr1; CpCharU * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (CpCharU *)string; cpCharLen(ptr1, curr_thread); if (U_FAILURE(curr_thread->status)) return NULL; while (*ptr1) { ptr2 = (CpCharU *)charlst; while (*ptr2) { i = cpCharLen(ptr2, curr_thread); for (j=0;jCurr_locale; switch (curr_locale->format) { case XDFUTF16: return (2 * u_strspn((const UChar *)string,(const UChar *) charlst)); case XDFUTF32: return (4 * xiu4_strspn((const UChar32 *)string,(const UChar32 *) charlst)); case XDFUTF8: return xiu8_strspn((const UChar8 *)string,(const UChar8 *)charlst); default: return xicp_strspn((const CpChar *)string,(const CpChar *)charlst); } return 0; } int32_t xiu2_strspn(const UChar *string, const UChar * charlst) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; return u_strspn(string, charlst); } int32_t xiu4_strspn(const UChar32 *string, const UChar32 * charlst) { XIUA_Thread * curr_thread; UChar32 * ptr1; UChar32 * ptr2; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ptr1 = (UChar32 *)string; while (*ptr1) { ptr2 = (UChar32 *)charlst; while (*ptr2) { if (*ptr1 == *ptr2) break; ptr2++; } if (!*ptr2) return ptr1-string; ptr1++; } return 0; } int32_t xiu8_strspn(const UChar8 *string, const UChar8 * charlst) { XIUA_Thread * curr_thread; UChar8U * ptr1; UChar8U * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; ptr1 = (UChar8U *)string; while (*ptr1) { ptr2 = (UChar8U *)charlst; while (*ptr2) { i = xbytesFromUTF8[*ptr2]; if (i < 1) { curr_thread->status = U_INVALID_CHAR_FOUND; return 0; } for (j=0;jstatus = U_INVALID_CHAR_FOUND; return 0; } ptr1 += i; } return 0; } int32_t xicp_strspn(const CpChar *string, const CpChar * charlst) { XIUA_Thread * curr_thread; CpCharU * ptr1; CpCharU * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (CpCharU *)string; cpCharLen(ptr1, curr_thread); if (U_FAILURE(curr_thread->status)) return 0; while (*ptr1) { ptr2 = (CpCharU *)charlst; while (*ptr2) { i = cpCharLen(ptr2, curr_thread); for (j=0;jCurr_locale; switch (curr_locale->format) { case XDFUTF16: return (2 * u_strcspn((const UChar *)string,(const UChar *) charlst)); case XDFUTF32: return (4 * xiu4_strcspn((const UChar32 *)string,(const UChar32 *) charlst)); case XDFUTF8: return xiu8_strcspn((const UChar8 *)string,(const UChar8 *)charlst); default: return xicp_strcspn((const CpChar *)string,(const CpChar *)charlst); } return 0; } int32_t xiu2_strcspn(const UChar *string, const UChar * charlst) { return u_strspn(string, charlst); } int32_t xiu4_strcspn(const UChar32 *string, const UChar32 * charlst) { UChar32 * ptr1; UChar32 * ptr2; ptr1 = (UChar32 *)string; while (*ptr1) { ptr2 = (UChar32 *)charlst; while (*ptr2) { if (*ptr1 == *ptr2) break; ptr2++; } if (*ptr2) return ptr1-string; ptr1++; } return 0; } int32_t xiu8_strcspn(const UChar8 *string, const UChar8 * charlst) { XIUA_Thread * curr_thread; UChar8U * ptr1; UChar8U * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (UChar8U *)string; while (*ptr1) { ptr2 = (UChar8U *)charlst; while (*ptr2) { i = xbytesFromUTF8[*ptr2]; if (i < 1) { curr_thread->status = U_INVALID_CHAR_FOUND; return 0; } for (j=0;jstatus = U_INVALID_CHAR_FOUND; return 0; } ptr1 += i; } return 0; } int32_t xicp_strcspn(const CpChar *string, const CpChar * charlst) { XIUA_Thread * curr_thread; CpCharU * ptr1; CpCharU * ptr2; int i, j; curr_thread = xiux_getCurrentThread(); ptr1 = (CpCharU *)string; cpCharLen(ptr1, curr_thread); if (U_FAILURE(curr_thread->status)) return 0; while (*ptr1) { ptr2 = (CpCharU *)charlst; while (*ptr2) { i = cpCharLen(ptr2, curr_thread); for (j=0;jCurr_locale; switch (curr_locale->format) { case XDFUTF16: return (char *)xiu2_strtok((UChar *)string,(const UChar *) charlst); case XDFUTF32: return (char *)xiu4_strtok((UChar32 *)string,(const UChar32 *) charlst); case XDFUTF8: return (char *)xiu8_strtok((UChar8 *)string,(const UChar8 *)charlst); default: return (char *)xicp_strtok((CpChar *)string,(const CpChar *)charlst); } return 0; } UChar * xiu2_strtok(UChar *string, const UChar * charlst) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); return xiu2_strtok_r(string, charlst, (UChar **)&curr_thread->last_str); } UChar32 * xiu4_strtok(UChar32 *string, const UChar32 * charlst) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); return xiu4_strtok_r(string, charlst, (UChar32 **)&curr_thread->last_str); } UChar8 * xiu8_strtok(UChar8 *string, const UChar8 * charlst) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); return xiu8_strtok_r(string, charlst, (UChar8 **)&curr_thread->last_str); } CpChar * xicp_strtok(CpChar *string, const CpChar * charlst) { XIUA_Thread * curr_thread; curr_thread = xiux_getCurrentThread(); return xicp_strtok_r(string, charlst, (CpChar **)&curr_thread->last_str); } char * xiua_strtok_r(char *string, const char * charlst, 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_strtok_r((UChar *)string, (const UChar *)charlst,(UChar **)pointer); case XDFUTF32: return (char *)xiu4_strtok_r((UChar32 *)string, (const UChar32 *)charlst,(UChar32 **)pointer); case XDFUTF8: return (char *)xiu8_strtok_r((UChar8 *)string, (const UChar8 *)charlst,(UChar8 **)pointer); default: return (char *)xicp_strtok_r((CpChar *)string, (const CpChar *)charlst,(CpChar **)pointer); } return 0; } UChar * xiu2_strtok_r(UChar *string, const UChar * charlst, UChar ** pointer) { /* return u_strtok_r(string, charlst, pointer); */ /* Interum ICU 1.8.1 replacement code- To be fixed in 2.0 */ UChar * ptr1; UChar * ptr2; if (!pointer) return NULL; if (string != NULL) { ptr1 = string; } else if (*pointer) { ptr1 = *pointer; } else { return NULL; } ptr1 += xiu2_strspn(ptr1, charlst); if (string != NULL) { *pointer = ptr1; } ptr2 = xiu2_strpbrk(ptr1, charlst); if (ptr2 != NULL) { *(ptr2++) = 0; *pointer = ptr2; return ptr1; } *pointer = NULL; if (*ptr1) return ptr1; return NULL; } UChar32 * xiu4_strtok_r(UChar32 *string, const UChar32 * charlst, UChar32 ** pointer) { UChar32 * ptr1; UChar32 * ptr2; if (!pointer) return NULL; if (string != NULL) { ptr1 = string; } else if (*pointer) { ptr1 = *pointer; } else { return NULL; } ptr1 += xiu4_strspn(ptr1, charlst); if (string != NULL) { *pointer = ptr1; } ptr2 = xiu4_strpbrk(ptr1, charlst); if (ptr2 != NULL) { *(ptr2++) = 0; *pointer = ptr2; return ptr1; } *pointer = NULL; if (*ptr1) return ptr1; return NULL; } UChar8 * xiu8_strtok_r(UChar8 *string, const UChar8 * charlst, UChar8 ** pointer) { XIUA_Thread * curr_thread; UChar8 * ptr1; UChar8 * ptr2; uint32_t i; curr_thread = xiux_getCurrentThread(); if (!pointer) return NULL; if (string != NULL) { ptr1 = string; } else if (*pointer) { ptr1 = *pointer; } else { return NULL; } ptr1 += xiu8_strspn(ptr1, charlst); if (string != NULL) { *pointer = ptr1; } ptr2 = xiu8_strpbrk(ptr1, charlst); if (ptr2 != NULL) { i = xbytesFromUTF8[(UChar8U)*ptr2]; if (i < 1) { curr_thread->status = U_INVALID_CHAR_FOUND; return NULL; } *ptr2 = 0; ptr2 += i; *pointer = ptr2; return ptr1; } *pointer = NULL; if (*ptr1) return ptr1; return NULL; } CpChar * xicp_strtok_r(CpChar *string, const CpChar * charlst, CpChar ** pointer) { XIUA_Thread * curr_thread; CpChar * ptr1; CpChar * ptr2; uint32_t i; curr_thread = xiux_getCurrentThread(); if (!pointer) return NULL; if (string != NULL) { ptr1 = string; } else if (*pointer) { ptr1 = *pointer; } else { return NULL; } ptr1 += xicp_strspn(ptr1, charlst); if (U_FAILURE(curr_thread->status)) return NULL; if (string != NULL) { *pointer = ptr1; } ptr2 = xicp_strpbrk(ptr1, charlst); if (ptr2 != NULL) { i = cpCharLen((CpCharU *)ptr2, curr_thread); *ptr2 = 0; ptr2 += i; *pointer = ptr2; return ptr1; } *pointer = NULL; if (*ptr1) return ptr1; return NULL; } int32_t xiua_strtoupperInplace(char *string) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar32 * U4Str; int i, j; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: U4Str = (UChar32 *)&curr_thread->work_buff[0]; i = (u_strlen((UChar *)string) + 1); if (i < 2) return 0; if (!chkWorkSize(i * 4)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF16toUTF32 (U4Str, i, (UChar *)string,-1); break; case XDFUTF32: U4Str = (UChar32 *)string; i = (xiu4_strlen(U4Str) + 1); if (i < 2) return 0; break; case XDFUTF8: U4Str = (UChar32 *)&curr_thread->work_buff[0]; i = (strlen(string) + 1); if (i < 2) return 0; if (!chkWorkSize(i * 4)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF8toUTF32 (U4Str, i, string,-1); break; default: i = (strlen(string) + 1); if (i < 2) return 0; j = i * 4; if (j > MAXCNVBUFFSIZE) j = MAXCNVBUFFSIZE; if (!chkWorkSize((i * 4) + j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } U4Str = (UChar32 *)&curr_thread->work_buff[j]; xiua_ChartoUTF32 (U4Str, i, string,-1); break; } i--; for (j=0;jformat) { case XDFUTF16: return xiua_UTF32toUTF16 ((UChar *)string, i+1, U4Str,-1); case XDFUTF8: return xiua_UTF32toUTF8 (string, i+1, U4Str,-1); default: return xiua_UTF32toChar (string, i+1, U4Str,-1); } return i; } int32_t xiua_strtoupper(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { 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 (sourceLen > 0) return xiu2_strtoupper((UChar *)target,(targetLen/2), (const UChar *)source, (sourceLen/2)); return xiu2_strtoupper((UChar *)target,(targetLen/2), (const UChar *)source, sourceLen); case XDFUTF32: if (sourceLen > 0) return xiu4_strtoupper((UChar32 *)target,(targetLen/4), (const UChar32 *)source, (sourceLen/4)); return xiu4_strtoupper((UChar32 *)target,(targetLen/4), (const UChar32 *)source, sourceLen); case XDFUTF8: return xiu8_strtoupper((UChar8 *)target,targetLen, (const UChar8 *)source, sourceLen); default: return xicp_strtoupper((CpChar *)target,targetLen, (const CpChar *)source, sourceLen); } return 0; } int32_t xiu2_strtoupper(UChar *target, const int32_t targetLen, const UChar * source, const int32_t sourceLen) { 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 u_strToUpper(target, targetLen, source, sourceLen, curr_locale->locale ,&curr_thread->status); } int32_t xiu4_strtoupper(UChar32 *target, const int32_t targetLen, const UChar32 * source, const int32_t sourceLen) { 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 = targetLen * 4; if (sourceLen == 0) return 0; if (sourceLen < 0) { j = ((xiu4_strlen(source)+1) * 4); } else { j = sourceLen * 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 (UStr2, j/2, source,sourceLen); if (U_FAILURE(curr_thread->status)) return 0; u_strToUpper(UStr1, i/2, UStr2, -1, curr_locale->locale ,&curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, UStr1, -1); } int32_t xiu8_strtoupper(UChar8 *target, const int32_t targetLen, const UChar8 * source, const int32_t sourceLen) { 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 = targetLen * 4; if (sourceLen == 0) return 0; if (sourceLen < 0) { j = ((strlen((const char *)source)+1) * 4); } else { j = sourceLen * 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 (UStr2, j/2, (char *)source,sourceLen); if (U_FAILURE(curr_thread->status)) return 0; u_strToUpper(UStr1, i/2, UStr2, -1, curr_locale->locale ,&curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, UStr1, -1); } int32_t xicp_strtoupper(CpChar *target, const int32_t targetLen, const CpChar * source, const int32_t sourceLen) { 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 = targetLen * 4; if (sourceLen == 0) return 0; if (sourceLen < 0) { j = ((strlen((const char *)source)+1) * 4); } else { j = sourceLen * 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 (UStr2, j/2, (char *)source,sourceLen); if (U_FAILURE(curr_thread->status)) return 0; u_strToUpper(UStr1, i/2, UStr2, -1, curr_locale->locale ,&curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, UStr1, -1); } int32_t xiua_strtolowerInplace(char *string) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar32 * U4Str; int i, j; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: U4Str = (UChar32 *)&curr_thread->work_buff[0]; i = (u_strlen((UChar *)string) + 1); if (i < 2) return 0; if (!chkWorkSize(i * 4)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF16toUTF32 (U4Str, i, (UChar *)string,-1); break; case XDFUTF32: U4Str = (UChar32 *)string; i = (xiu4_strlen(U4Str) + 1); if (i < 2) return 0; break; case XDFUTF8: U4Str = (UChar32 *)&curr_thread->work_buff[0]; i = (strlen(string) + 1); if (i < 2) return 0; if (!chkWorkSize(i * 4)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF8toUTF32 (U4Str, i, string,-1); break; default: i = (strlen(string) + 1); if (i < 2) return 0; j = i * 4; if (j > MAXCNVBUFFSIZE) j = MAXCNVBUFFSIZE; if (!chkWorkSize((i * 4) + j)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } U4Str = (UChar32 *)&curr_thread->work_buff[0]; xiua_ChartoUTF32 (U4Str, i, string,-1); break; } i--; for (j=0;jformat) { case XDFUTF16: return xiua_UTF32toUTF16 ((UChar *)string, i+1, U4Str,-1); case XDFUTF8: return xiua_UTF32toUTF8 (string, i+1, U4Str,-1); default: return xiua_UTF32toChar (string, i+1, U4Str,-1); } return i; } int32_t xiua_strtolower(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { 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 (sourceLen > 0) return xiu2_strtolower((UChar *)target,(targetLen/2), (const UChar *)source, (sourceLen/2)); return xiu2_strtolower((UChar *)target,(targetLen/2), (const UChar *)source, sourceLen); case XDFUTF32: if (sourceLen > 0) return xiu4_strtolower((UChar32 *)target,(targetLen/4), (const UChar32 *)source, (sourceLen/4)); return xiu4_strtolower((UChar32 *)target,(targetLen/4), (const UChar32 *)source, sourceLen); case XDFUTF8: return xiu8_strtolower((UChar8 *)target,targetLen, (const UChar8 *)source, sourceLen); default: return xicp_strtolower((CpChar *)target,targetLen, (const CpChar *)source, sourceLen); } return 0; } int32_t xiu2_strtolower(UChar *target, const int32_t targetLen, const UChar * source, const int32_t sourceLen) { 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 u_strToLower(target, targetLen, source, sourceLen, curr_locale->locale ,&curr_thread->status); } int32_t xiu4_strtolower(UChar32 *target, const int32_t targetLen, const UChar32 * source, const int32_t sourceLen) { 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 = targetLen * 4; j = sourceLen * 4; if (sourceLen == 0) return 0; if (sourceLen < 0) j = ((xiu4_strlen(source)+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 (UStr2, j/2, source,sourceLen); if (U_FAILURE(curr_thread->status)) return 0; u_strToLower(UStr1, i/2, UStr2, -1, curr_locale->locale ,&curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, UStr1, -1); } int32_t xiu8_strtolower(UChar8 *target, const int32_t targetLen, const UChar8 * source, const int32_t sourceLen) { 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 = targetLen * 2; j = sourceLen * 2; if (sourceLen == 0) return 0; if (sourceLen < 0) j = ((strlen((const char *)source)+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 (UStr2, j/2, (char *)source,sourceLen); if (U_FAILURE(curr_thread->status)) return 0; u_strToLower(UStr1, i/2, UStr2, -1, curr_locale->locale ,&curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, UStr1, -1); } int32_t xicp_strtolower(CpChar *target, const int32_t targetLen, const CpChar * source, const int32_t sourceLen) { 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 = targetLen * 2; j = sourceLen * 2; if (sourceLen == 0) return 0; if (sourceLen < 0) j = ((strlen((const char *)source)+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 (UStr2, j/2, (char *)source,sourceLen); if (U_FAILURE(curr_thread->status)) return 0; u_strToLower(UStr1, i/2, UStr2, -1, curr_locale->locale ,&curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, UStr1, -1); } int32_t xiua_BuildDateFormat(UChar *target, const int32_t targetLen, const char * source) { return u_unescape(source,target,targetLen); } int32_t xiua_ConvStrftimeFormat(UChar *target, const int32_t targetLen, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const char * source) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UResourceBundle * dateres; UResourceBundle * datearray; const UChar * date_format; int32_t date_format_len; int len = targetLen - 9; int j = 0; int i = 0; int k, l; UBool qtext = FALSE; UBool strfmt = FALSE; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; dateres = ures_open (NULL,curr_locale->locale, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; datearray = ures_getByKey(dateres, "DateTimePatterns", NULL, &curr_thread->status); if (U_FAILURE(curr_thread->status)) { ures_close(dateres); return 0; } while (source[i] && j < len) { if (source[i] == '%') { strfmt = TRUE; if (qtext) { target[j] = '\''; j++; qtext = FALSE; } i++; if (source[i] == 'E' || source[i] == 'O') i++; switch (source[i]) { case '\\': j++; break; case '%': target[j] = '%'; j++; break; case 'a': xiux_strToUChars(&target[j],"EEE"); j += 3; break; case 'A': xiux_strToUChars(&target[j],"EEEE"); j += 4; break; case 'h': case 'b': xiux_strToUChars(&target[j],"MMM"); j += 3; break; case 'B': xiux_strToUChars(&target[j],"MMMM"); j += 4; break; case 'c': case 'C': date_format = ures_getStringByIndex(datearray,8,&date_format_len, &curr_thread->status); if (U_FAILURE(curr_thread->status)) break; if (date_format[1] == 0x0031) { k = (int)date_fmt + 4; l = (int)time_fmt; } else { l = (int)date_fmt + 4; k = (int)time_fmt; } u_strcpy(&target[j],date_format = ures_getStringByIndex(datearray,k,&date_format_len, &curr_thread->status)); if (U_FAILURE(curr_thread->status)) break; j += date_format_len; target[j] = 0x0020; j++; u_strcpy(&target[j],date_format = ures_getStringByIndex(datearray,l,&date_format_len, &curr_thread->status)); if (U_FAILURE(curr_thread->status)) break; j += date_format_len; break; case 'd': xiux_strToUChars(&target[j],"dd"); j += 2; break; case 'D': xiux_strToUChars(&target[j],"MM/dd/yy"); j += 8; break; case 'e': target[j] = 'd'; j++; break; case 'g': xiux_strToUChars(&target[j],"YY"); j += 2; break; case 'G': xiux_strToUChars(&target[j],"YYYY"); j += 4; break; case 'H': xiux_strToUChars(&target[j],"HH"); j += 2; break; case 'I': xiux_strToUChars(&target[j],"hh"); j += 2; break; case 'j': xiux_strToUChars(&target[j],"DD"); j += 2; break; case 'k': target[j] = 'H'; j++; break; case 'l': target[j] = 'h'; j++; break; case 'm': xiux_strToUChars(&target[j],"MM"); j += 2; break; case 'M': xiux_strToUChars(&target[j],"mm"); j += 2; break; case 'n': target[j] = '\n'; j++; break; case 'p': target[j] = 'a'; j++; break; case 'R': xiux_strToUChars(&target[j],"HH:mm"); j += 5; break; case 'S': xiux_strToUChars(&target[j],"ss"); j += 2; break; case 't': target[j] = '\t'; j++; break; case 'T': xiux_strToUChars(&target[j],"HH:mm:ss"); j += 8; break; case 'u': target[j] = 'e'; j++; break; case 'U': target[j] = 'w'; j++; break; case 'x': k = (int)date_fmt + 4; u_strcpy(&target[j],date_format = ures_getStringByIndex(datearray,k,&date_format_len, &curr_thread->status)); if (U_FAILURE(curr_thread->status)) break; j += date_format_len; break; case 'r': case 'X': k = (int)time_fmt; u_strcpy(&target[j],date_format = ures_getStringByIndex(datearray,k,&date_format_len, &curr_thread->status)); if (U_FAILURE(curr_thread->status)) break; j += date_format_len; break; case 'y': xiux_strToUChars(&target[j],"yy"); j += 2; break; case 'Y': xiux_strToUChars(&target[j],"yyyy"); j += 4; break; case 'Z': target[j] = 'z'; j++; break; default: target[j] = '\''; j++; qtext = TRUE; target[j] = '%'; j++; target[j] = source[i]; j++; break; } } else if (source[i] == '\'') { xiux_strToUChars(&target[j],"\'\'"); j += 2; } else if (strfmt && u_isalpha(source[i])) { if (!qtext) { target[j] = '\''; j++; qtext = TRUE; } target[j] = source[i]; j++; } else { target[j] = source[i]; j++; } i++; } target[j] = 0; ures_close(datearray); ures_close(dateres); return j; } int32_t xiua_DateFormat (char *target, const int32_t targetLen, const time_t time, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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_DateFormat((UChar *)target, (targetLen / 2),time,date_fmt,time_fmt,format)); case XDFUTF32: return (4 * xiu4_DateFormat((UChar32 *)target, (targetLen / 4),time,date_fmt,time_fmt,format)); case XDFUTF8: return xiu8_DateFormat((UChar8 *)target, targetLen,time,date_fmt,time_fmt,format); default: return xicp_DateFormat((CpChar *)target, targetLen,time,date_fmt,time_fmt,format); } return 0; } int32_t xiu2_DateFormat (UChar *target, const int32_t targetLen, const time_t time, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UDateFormat *dfmt; UDateFormatStyle TimeFmt = UDAT_DEFAULT; UDateFormatStyle DateFmt = UDAT_DEFAULT; UDate DateTime; UChar TZone[XIUA_MAXTIMEZONESIZE]; int32_t myTargetSize; int32_t numDChar = 0; int32_t TZoneLen = 0; #if (XIUA_ICU_LEVEL == 0) int32_t UFmtLen = 0; #endif curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (time_fmt < XDTANY) { TimeFmt = (UDateFormatStyle)time_fmt; } if (date_fmt < XDTANY) { DateFmt = (UDateFormatStyle)date_fmt; } myTargetSize = targetLen; if (time == 0) { DateTime = ucal_getNow(); } else { DateTime = (double)time * U_MILLIS_PER_SECOND; } if (curr_locale->tzone) { TZoneLen = xiux_strToUChars(TZone,(char *)curr_locale->tzone); } #if (XIUA_ICU_LEVEL == 0) dfmt = udat_open(TimeFmt, DateFmt, curr_locale->locale, TZone, TZoneLen, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; if (format) { UFmtLen = u_strlen(format); udat_applyPattern(dfmt,FALSE,format,UFmtLen); } #else if (format) { dfmt = udat_open(UDAT_IGNORE, UDAT_IGNORE, curr_locale->locale, TZone, TZoneLen, format, -1, &curr_thread->status); } else { dfmt = udat_open(TimeFmt, DateFmt, curr_locale->locale, TZone, TZoneLen, NULL, 0, &curr_thread->status); } if (U_FAILURE(curr_thread->status)) return 0; #endif /* Format the date */ numDChar = udat_format(dfmt, DateTime, target, targetLen, 0, &curr_thread->status); udat_close(dfmt); if (U_FAILURE(curr_thread->status)) return 0; return numDChar; } int32_t xiu4_DateFormat (UChar32 *target, const int32_t targetLen, const time_t time, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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_DateFormat((UChar *)curr_thread->work_buff, (i / 2),time,date_fmt,time_fmt,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiu8_DateFormat (UChar8 *target, const int32_t targetLen, const time_t time, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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_DateFormat((UChar *)curr_thread->work_buff, (i / 2),time,date_fmt,time_fmt,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xicp_DateFormat (CpChar *target, const int32_t targetLen, const time_t time, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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_DateFormat((UChar *)curr_thread->work_buff, (i / 2),time,date_fmt,time_fmt,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } time_t xiua_DateParse (const char *source, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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_DateParse((const UChar *)source, date_fmt,time_fmt,format); case XDFUTF32: return xiu4_DateParse((const UChar32 *)source, date_fmt,time_fmt,format); case XDFUTF8: return xiu8_DateParse((const UChar8 *)source, date_fmt,time_fmt,format); default: return xicp_DateParse((const CpChar *)source, date_fmt,time_fmt,format); } return 0; } time_t xiu2_DateParse (const UChar *source, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UDateFormat *dfmt; UDateFormatStyle TimeFmt = UDAT_FULL; UDateFormatStyle DateFmt = UDAT_FULL; UDate DateTime; UChar TZone[XIUA_MAXTIMEZONESIZE]; int32_t mySourceSize; int32_t TZoneLen = 0; #if (XIUA_ICU_LEVEL == 0) int32_t UFmtLen = 0; #endif int32_t offset = 0; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; if (time_fmt < XDTANY) { TimeFmt = (UDateFormatStyle)time_fmt; } if (date_fmt < XDTANY) { DateFmt = (UDateFormatStyle)date_fmt; } if (curr_locale->tzone) { TZoneLen = xiux_strToUChars(TZone,(char *)curr_locale->tzone); } mySourceSize = u_strlen(source); #if (XIUA_ICU_LEVEL == 0) dfmt = udat_open(TimeFmt, DateFmt, curr_locale->locale, TZone, TZoneLen, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return 0; if (format) { UFmtLen = u_strlen(format); udat_applyPattern(dfmt,FALSE,format,UFmtLen); } #else if (format) { dfmt = udat_open(UDAT_IGNORE, UDAT_IGNORE, curr_locale->locale, TZone, TZoneLen, format, -1, &curr_thread->status); } else { dfmt = udat_open(TimeFmt, DateFmt, curr_locale->locale, TZone, TZoneLen, NULL, 0, &curr_thread->status); } if (U_FAILURE(curr_thread->status)) return 0; #endif /* parse the date */ offset = 0; DateTime = udat_parse(dfmt, source, mySourceSize, &offset, &curr_thread->status); udat_close(dfmt); if(curr_thread->status == U_PARSE_ERROR) { if(time_fmt == XDTANY) TimeFmt++; else if(date_fmt == XDTANY) DateFmt++; else return 0; } while (curr_thread->status == U_PARSE_ERROR) { if (TimeFmt == UDAT_NONE || (time_fmt != XDTANY)) { if(DateFmt == UDAT_NONE || (date_fmt != XDTANY)) return 0; if(DateFmt < UDAT_SHORT) { DateFmt++; } else { DateFmt = UDAT_NONE; } if (time_fmt == XDTANY) TimeFmt = UDAT_FULL; } else { if (time_fmt == XDTANY) { if(TimeFmt < UDAT_SHORT) { TimeFmt++; } else { TimeFmt = UDAT_NONE; } } } curr_thread->status = U_ZERO_ERROR; #if (XIUA_ICU_LEVEL == 0) dfmt = udat_open(TimeFmt, DateFmt, curr_locale->locale, TZone, TZoneLen, &curr_thread->status); #else dfmt = udat_open(TimeFmt, DateFmt, curr_locale->locale, TZone, TZoneLen, NULL, 0, &curr_thread->status); #endif offset = 0; DateTime = udat_parse(dfmt, source, mySourceSize, &offset, &curr_thread->status); udat_close(dfmt); } if (U_FAILURE(curr_thread->status)) return 0; return (time_t)(DateTime/U_MILLIS_PER_SECOND); } time_t xiu4_DateParse (const UChar32 *source, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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 = (xiu4_strlen(source) + 1) * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF32toUTF16 ((UChar *)curr_thread->work_buff, (i / 2), source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_DateParse((UChar *)curr_thread->work_buff, date_fmt,time_fmt,format); } time_t xiu8_DateParse (const UChar8 *source, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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 = (strlen((const char *)source) + 1) * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF8toUTF16 ((UChar *)curr_thread->work_buff, (i / 2), (char *)source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_DateParse((UChar *)curr_thread->work_buff, date_fmt,time_fmt,format); } time_t xicp_DateParse (const CpChar *source, const XIUA_DateFormat date_fmt, const XIUA_DateFormat time_fmt, const UChar * format) { 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 = (strlen((const char *)source) + 1) * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_ChartoUTF16 ((UChar *)curr_thread->work_buff, (i / 2), (char *)source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_DateParse((UChar *)curr_thread->work_buff, date_fmt,time_fmt,format); } int32_t xiua_IntFormat (char *target, const int32_t targetLen, const int32_t source, const XIUA_NumFormat format) { 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_IntFormat((UChar *)target, (targetLen / 2),source,format)); case XDFUTF32: return (4 * xiu4_IntFormat((UChar32 *)target, (targetLen / 4),source,format)); case XDFUTF8: return xiu8_IntFormat((UChar8 *)target, targetLen,source,format); default: return xicp_IntFormat((CpChar *)target, targetLen,source,format); } return 0; } int32_t xiu2_IntFormat (UChar *target, const int32_t targetLen, const int32_t source, const XIUA_NumFormat format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UNumberFormat *nfmt; UNumberFormatStyle num_fmt = UNUM_DEFAULT; int32_t numUChar; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; num_fmt = (UNumberFormatStyle)format; /* Open a number formatter */ #if (XIUA_ICU_LEVEL == 0) nfmt = unum_open(num_fmt, curr_locale->locale, &curr_thread->status); #else nfmt = unum_open(num_fmt, NULL, 0, curr_locale->locale, &curr_thread->ParseStatus, &curr_thread->status); #endif if (U_FAILURE(curr_thread->status)) return 0; /* Format the number */ numUChar = unum_format(nfmt, source, target, targetLen, 0, &curr_thread->status); unum_close(nfmt); if (U_FAILURE(curr_thread->status)) return 0; return numUChar; } int32_t xiu4_IntFormat (UChar32 *target, const int32_t targetLen, const int32_t source, const XIUA_NumFormat format) { 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_IntFormat((UChar *)curr_thread->work_buff, (i / 2),source,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiu8_IntFormat (UChar8 *target, const int32_t targetLen, const int32_t source, const XIUA_NumFormat format) { 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_IntFormat((UChar *)curr_thread->work_buff, (i / 2),source,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xicp_IntFormat (CpChar *target, const int32_t targetLen, const int32_t source, const XIUA_NumFormat format) { 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_IntFormat((UChar *)curr_thread->work_buff, (i / 2),source,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiua_FloatFormat (char *target, const int32_t targetLen, const double source, const XIUA_NumFormat format) { 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_FloatFormat((UChar *)target, (targetLen / 2),source,format)); case XDFUTF32: return (4 * xiu4_FloatFormat((UChar32 *)target, (targetLen / 4),source,format)); case XDFUTF8: return xiu8_FloatFormat((UChar8 *)target, targetLen,source,format); default: return xicp_FloatFormat((CpChar *)target, targetLen,source,format); } return 0; } int32_t xiu2_FloatFormat (UChar *target, const int32_t targetLen, const double source, const XIUA_NumFormat format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UNumberFormat *nfmt; UNumberFormatStyle num_fmt = UNUM_DEFAULT; int32_t numUChar; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; num_fmt = (UNumberFormatStyle)format; /* Open a number formatter */ #if (XIUA_ICU_LEVEL == 0) nfmt = unum_open(num_fmt, curr_locale->locale, &curr_thread->status); #else nfmt = unum_open(num_fmt, NULL, 0, curr_locale->locale, &curr_thread->ParseStatus, &curr_thread->status); #endif if (U_FAILURE(curr_thread->status)) return 0; /* Format the number */ numUChar = unum_formatDouble(nfmt, source, target, targetLen, 0, &curr_thread->status); unum_close(nfmt); if (U_FAILURE(curr_thread->status)) return 0; return numUChar; } int32_t xiu4_FloatFormat (UChar32 *target, const int32_t targetLen, const double source, const XIUA_NumFormat format) { 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_FloatFormat((UChar *)curr_thread->work_buff, (i / 2),source,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF32 (target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiu8_FloatFormat (UChar8 *target, const int32_t targetLen, const double source, const XIUA_NumFormat format) { 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_FloatFormat((UChar *)curr_thread->work_buff, (i / 2),source,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toUTF8 ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xicp_FloatFormat (CpChar *target, const int32_t targetLen, const double source, const XIUA_NumFormat format) { 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_FloatFormat((UChar *)curr_thread->work_buff, (i / 2),source,format); if (U_FAILURE(curr_thread->status)) return 0; return xiua_UTF16toChar ((char *)target, targetLen, (UChar *)curr_thread->work_buff, -1); } int32_t xiua_IntParse (const char *source, const XIUA_NumFormat format) { 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_IntParse((const UChar *)source,format); case XDFUTF32: return xiu4_IntParse((const UChar32 *)source,format); case XDFUTF8: return xiu8_IntParse((const UChar8 *)source,format); default: return xicp_IntParse((const CpChar *)source,format); } return 0; } int32_t xiu2_IntParse (const UChar *source, const XIUA_NumFormat format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UNumberFormat *nfmt; UNumberFormatStyle num_fmt = UNUM_DEFAULT; int32_t numResult = 0; int32_t offset = 0; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (format != XNFANY) { curr_thread->status = U_ZERO_ERROR; num_fmt = (UNumberFormatStyle)format; /* Open a number formatter */ #if (XIUA_ICU_LEVEL == 0) nfmt = unum_open(num_fmt, curr_locale->locale, &curr_thread->status); #else nfmt = unum_open(num_fmt, NULL, 0, curr_locale->locale, &curr_thread->ParseStatus, &curr_thread->status); #endif if (U_FAILURE(curr_thread->status)) return 0; /* Parse the number */ offset = 0; numResult = unum_parse(nfmt, source, u_strlen(source), &offset, &curr_thread->status); unum_close(nfmt); } else { num_fmt = UNUM_PERCENT; curr_thread->status = U_PARSE_ERROR; while(curr_thread->status == U_PARSE_ERROR && num_fmt >= UNUM_DECIMAL) { curr_thread->status = U_ZERO_ERROR; /* Open a number formatter */ #if (XIUA_ICU_LEVEL == 0) nfmt = unum_open(num_fmt, curr_locale->locale, &curr_thread->status); #else nfmt = unum_open(num_fmt, NULL, 0, curr_locale->locale, &curr_thread->ParseStatus, &curr_thread->status); #endif if (U_FAILURE(curr_thread->status)) return 0; /* Parse the number */ offset = 0; numResult = unum_parse(nfmt, source, u_strlen(source), &offset, &curr_thread->status); unum_close(nfmt); num_fmt--; } } if (U_FAILURE(curr_thread->status)) return 0; return numResult; } int32_t xiu4_IntParse (const UChar32 *source, const XIUA_NumFormat format) { 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 = (xiu4_strlen(source) + 1) * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF32toUTF16 ((UChar *)curr_thread->work_buff, (i / 2), source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_IntParse((UChar *)curr_thread->work_buff,format); } int32_t xiu8_IntParse (const UChar8 *source, const XIUA_NumFormat format) { 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 = (strlen((const char *)source) + 1) * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF8toUTF16 ((UChar *)curr_thread->work_buff, (i / 2), (char *)source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_IntParse((UChar *)curr_thread->work_buff,format); } int32_t xicp_IntParse (const CpChar *source, const XIUA_NumFormat format) { 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 = (strlen((const char *)source) + 1) * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_ChartoUTF16 ((UChar *)curr_thread->work_buff, (i / 2), (char *)source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_IntParse((UChar *)curr_thread->work_buff,format); } double xiua_FloatParse (const char *source, const XIUA_NumFormat format) { 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_FloatParse((const UChar *)source,format); case XDFUTF32: return xiu4_FloatParse((const UChar32 *)source,format); case XDFUTF8: return xiu8_FloatParse((const UChar8 *)source,format); default: return xicp_FloatParse((const CpChar *)source,format); } return 0; } double xiu2_FloatParse (const UChar *source, const XIUA_NumFormat format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UNumberFormat *nfmt; UNumberFormatStyle num_fmt = UNUM_DEFAULT; double numResult = 0; int32_t offset = 0; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (format != XNFANY) { curr_thread->status = U_ZERO_ERROR; num_fmt = (UNumberFormatStyle)format; /* Open a number formatter */ #if (XIUA_ICU_LEVEL == 0) nfmt = unum_open(num_fmt, curr_locale->locale, &curr_thread->status); #else nfmt = unum_open(num_fmt, NULL, 0, curr_locale->locale, &curr_thread->ParseStatus, &curr_thread->status); #endif if (U_FAILURE(curr_thread->status)) return 0; /* Parse the number */ offset = 0; numResult = unum_parseDouble(nfmt, source, u_strlen(source), &offset, &curr_thread->status); unum_close(nfmt); } else { num_fmt = UNUM_PERCENT; curr_thread->status = U_PARSE_ERROR; while(curr_thread->status == U_PARSE_ERROR && num_fmt >= UNUM_DECIMAL) { curr_thread->status = U_ZERO_ERROR; /* Open a number formatter */ #if (XIUA_ICU_LEVEL == 0) nfmt = unum_open(num_fmt, curr_locale->locale, &curr_thread->status); #else nfmt = unum_open(num_fmt, NULL, 0, curr_locale->locale, &curr_thread->ParseStatus, &curr_thread->status); #endif if (U_FAILURE(curr_thread->status)) return 0; /* Parse the number */ offset = 0; numResult = unum_parseDouble(nfmt, source, u_strlen(source), &offset, &curr_thread->status); unum_close(nfmt); num_fmt--; } } if (U_FAILURE(curr_thread->status)) return 0; return numResult; } double xiu4_FloatParse (const UChar32 *source, const XIUA_NumFormat format) { 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 = (xiu4_strlen(source) + 1) * 4; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF32toUTF16 ((UChar *)curr_thread->work_buff, (i / 2), source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_FloatParse((UChar *)curr_thread->work_buff,format); } double xiu8_FloatParse (const UChar8 *source, const XIUA_NumFormat format) { 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 = (strlen((const char *)source) + 1) * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_UTF8toUTF16 ((UChar *)curr_thread->work_buff, (i / 2), (char *)source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_FloatParse((UChar *)curr_thread->work_buff,format); } double xicp_FloatParse (const CpChar *source, const XIUA_NumFormat format) { 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 = (strlen((const char *)source) + 1) * 2; if (!chkWorkSize(i)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } xiua_ChartoUTF16 ((UChar *)curr_thread->work_buff, (i / 2), (char *)source, -1); if (U_FAILURE(curr_thread->status)) return 0; return xiu2_FloatParse((UChar *)curr_thread->work_buff,format); } int32_t xiua_LocaletoLocale(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen, const XIUA_Locale * fromLocale, const XIUA_Locale * toLocale) { XIUA_Thread * curr_thread; UChar32 ** mySource32 = (UChar32 **)&source; UChar16 ** mySource16 = (UChar16 **)&source; char ** mySource8 = (char **)&source; UChar32 *myTarget32 = (UChar32 *)target; UChar16 *myTarget16 = (UChar16 *)target; char *myTarget8 = (char *)target; UChar *myWork; UChar **myWorkAddr; int32_t mySourceSize; int32_t myTargetSize; int32_t myWorkSize; int32_t numConvChar = 0; int32_t numUChar = 0; int32_t CharLen; UConverter* fromConv = fromLocale->conv; UConverter* toConv = toLocale->conv; curr_thread = xiux_getCurrentThread(); switch (fromLocale->format) { case XDFUTF16: if (sourceLen > 0) { mySourceSize = (sourceLen/2); } else mySourceSize = sourceLen; switch (toLocale->format) { case XDFUTF16: myTargetSize = (targetLen/2); if (mySourceSize > myTargetSize) mySourceSize = myTargetSize; return (2*(xiu2_strncpyEx(myTarget16, *mySource16,mySourceSize))); case XDFUTF32: myTargetSize = (targetLen/4); return (4*(UTF16toUTF32Chunk(myTarget32,targetLen, mySource16,mySourceSize,curr_thread))); case XDFUTF8: myTargetSize = targetLen; return UTF16toUTF8Chunk(myTarget8,targetLen, mySource16,mySourceSize,curr_thread); default: myTargetSize = targetLen; ucnv_reset (toConv); return UTF16toCharChunk(myTarget8,targetLen, mySource16,mySourceSize,curr_thread,toConv); } break; case XDFUTF32: if (sourceLen > 0) { mySourceSize = (sourceLen/4); } else mySourceSize = sourceLen; switch (toLocale->format) { case XDFUTF16: myTargetSize = (targetLen/2); return (2*(UTF32toUTF16Chunk(myTarget16,targetLen, mySource32,mySourceSize,curr_thread))); case XDFUTF32: myTargetSize = (targetLen/4); if (mySourceSize > myTargetSize) mySourceSize = myTargetSize; return (4*(xiu4_strncpyEx(myTarget32, *mySource32,mySourceSize))); case XDFUTF8: myTargetSize = targetLen; return xiua_UTF32toUTF8(myTarget8,targetLen, *mySource32,mySourceSize); default: myTargetSize = targetLen; ucnv_reset (toConv); myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } while (*mySource32) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = UTF32toUTF16Chunk(myWork,myWorkSize, mySource32,sourceLen,curr_thread); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toCharChunk (myTarget8, myTargetSize, myWorkAddr, numUChar, curr_thread, toConv); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget8 += CharLen; myTargetSize -= CharLen; } break; } break; case XDFUTF8: mySourceSize = sourceLen; switch (toLocale->format) { case XDFUTF16: myTargetSize = (targetLen/2); return (2*(UTF8toUTF16Chunk(myTarget16,targetLen, mySource8,-1,mySourceSize,curr_thread))); case XDFUTF32: myTargetSize = (targetLen/4); return (4*(xiua_UTF8toUTF32Ex(myTarget32,targetLen, *mySource8,-1,mySourceSize))); case XDFUTF8: myTargetSize = targetLen; if (mySourceSize > myTargetSize) mySourceSize = myTargetSize; return xiu8_strncpyEx((UChar8 *)myTarget8,(UChar8 *)*mySource8,mySourceSize); default: myTargetSize = targetLen; ucnv_reset (toConv); myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } while (*mySource8) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = UTF8toUTF16Chunk(myWork,myWorkSize, mySource8,-1,sourceLen,curr_thread); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toCharChunk (myTarget8, myTargetSize, myWorkAddr, numUChar, curr_thread, toConv); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget8 += CharLen; myTargetSize -= CharLen; } break; } break; default: mySourceSize = sourceLen; ucnv_reset (fromConv); switch (toLocale->format) { case XDFUTF16: myTargetSize = (targetLen/2); return (2*(ChartoUTF16Chunk(myTarget16,targetLen, mySource8,mySourceSize,curr_thread,fromConv))); case XDFUTF32: myTargetSize = (targetLen/4); myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } while (*mySource8) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = ChartoUTF16Chunk(myWork,myWorkSize, mySource8,sourceLen,curr_thread,fromConv); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toUTF32Chunk (myTarget32, myTargetSize, myWorkAddr, numUChar, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget32 += CharLen; myTargetSize -= CharLen; } return numConvChar*4; case XDFUTF8: myTargetSize = targetLen; myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } while (*mySource8) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = ChartoUTF16Chunk(myWork,myWorkSize, mySource8,sourceLen,curr_thread,fromConv); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toUTF8Chunk (myTarget8, myTargetSize, myWorkAddr, numUChar, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget8 += CharLen; myTargetSize -= CharLen; } break; default: myTargetSize = targetLen; if (strcmp(fromLocale->charset_name,toLocale->charset_name) == 0) { if (mySourceSize > myTargetSize) mySourceSize = myTargetSize; return xicp_strncpyEx((CpChar *)myTarget8,(CpChar *)*mySource8,mySourceSize); } ucnv_reset (toConv); myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } while (*mySource8) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = ChartoUTF16Chunk(myWork,myWorkSize, mySource8,sourceLen,curr_thread,fromConv); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toCharChunk (myTarget8, myTargetSize, myWorkAddr, numUChar, curr_thread, toConv); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget8 += CharLen; myTargetSize -= CharLen; } break; } break; } return numConvChar; } int32_t xiua_LocaletoNative(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen, const XIUA_Locale * fromLocale) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; return xiua_LocaletoLocale(target,targetLen, source,sourceLen,fromLocale,curr_locale); } int32_t xiua_NativetoLocale(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen, const XIUA_Locale * toLocale) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; return xiua_LocaletoLocale(target,targetLen, source,sourceLen,curr_locale,toLocale); } int32_t xiua_NativetoUTF16(UChar *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (sourceLen > 0) { i = (sourceLen/2); if (i <= targetLen) return xiu2_strncpyEx(target,(UChar *)source,i); return xiu2_strncpyEx(target,(UChar *)source,targetLen); } else i = sourceLen; return xiu2_strncpyEx(target,(UChar *)source,targetLen); case XDFUTF32: if (sourceLen > 1) i = (sourceLen/4); else i = sourceLen; return xiua_UTF32toUTF16(target,targetLen, (UChar32 *)source, i); case XDFUTF8: return xiua_UTF8toUTF16(target,targetLen, source, sourceLen); default: return xiua_ChartoUTF16(target,targetLen, source, sourceLen); } return 0; } int32_t xiua_NativetoUTF32(UChar32 *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (sourceLen > 1) i = (sourceLen/2); else i = sourceLen; return xiua_UTF16toUTF32(target,targetLen, (UChar *)source, i); case XDFUTF32: if (sourceLen > 0) { i = (sourceLen/4); if (i <= targetLen) return xiu4_strncpyEx(target,(UChar32 *)source,i); return xiu4_strncpyEx(target,(UChar32 *)source,targetLen); } else i = sourceLen; return xiu4_strncpyEx(target,(UChar32 *)source,targetLen); case XDFUTF8: return xiua_UTF8toUTF32(target,targetLen, source, sourceLen); default: return xiua_ChartoUTF32(target,targetLen, source, sourceLen); } return 0; } int32_t xiua_NativetoUTF8(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (sourceLen > 1) i = (sourceLen/2); else i = sourceLen; return xiua_UTF16toUTF8(target,targetLen, (UChar *)source, i); case XDFUTF32: if (sourceLen > 1) i = (sourceLen/4); else i = sourceLen; return xiua_UTF32toUTF8(target,targetLen, (UChar32 *)source, i); case XDFUTF8: if (sourceLen >= 0 && sourceLen <= targetLen) return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,sourceLen); return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,targetLen); default: return xiua_ChartoUTF8(target,targetLen, source, sourceLen); } return 0; } int32_t xiua_NativetoChar(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; int i; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; switch (curr_locale->format) { case XDFUTF16: if (sourceLen > 1) i = (sourceLen/2); else i = sourceLen; return xiua_UTF16toChar(target,targetLen, (UChar *)source, i); case XDFUTF32: if (sourceLen > 1) i = (sourceLen/4); else i = sourceLen; return xiua_UTF32toChar(target,targetLen, (UChar32 *)source, i); case XDFUTF8: return xiua_UTF8toChar(target,targetLen, source, sourceLen); default: if (sourceLen >= 0 && sourceLen <= targetLen) return xicp_strncpyEx((CpChar *)target,(CpChar *)source,sourceLen); return xicp_strncpyEx((CpChar *)target,(CpChar *)source,targetLen); } return 0; } int32_t xiua_UTF16toNative(char *target, const int32_t targetLen, const UChar * source, const int32_t sourceLen) { 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 (sourceLen >= 0 && sourceLen <= (targetLen/2)) return xiu2_strncpyEx((UChar *)target,source,sourceLen); return xiu2_strncpyEx((UChar *)target,source,(targetLen/2)); case XDFUTF32: return xiua_UTF16toUTF32((UChar32 *)target,(targetLen/4), source, sourceLen); case XDFUTF8: return xiua_UTF16toUTF8(target,targetLen, source, sourceLen); default: return xiua_UTF16toChar(target,targetLen, source, sourceLen); } return 0; } int32_t xiua_UTF16toUTF32(UChar32 *target, const int32_t targetLen, const UChar * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; UChar ** mySource = (UChar **)&source; int32_t numConvChar = 0; curr_thread = xiux_getCurrentThread(); numConvChar = UTF16toUTF32Chunk(target,targetLen,mySource,sourceLen, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } return numConvChar; } int32_t xiua_UTF16toUTF8 (char *target, const int32_t targetLen, const UChar * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; UChar ** mySource = (UChar **)&source; int32_t numConvChar = 0; curr_thread = xiux_getCurrentThread(); numConvChar = UTF16toUTF8Chunk(target,targetLen,mySource,sourceLen, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } return numConvChar; } int32_t xiua_UTF16toChar (char *target, const int32_t targetLen, const UChar * source, const int32_t sourceLen) { XIUA_Locale * curr_locale; XIUA_Thread * curr_thread; UChar ** mySource = (UChar **)&source; int32_t numConvChar = 0; UConverter* myConv; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; myConv = (UConverter*)curr_locale->conv; ucnv_reset (myConv); numConvChar = UTF16toCharChunk(target,targetLen,mySource,sourceLen, curr_thread,myConv); if (U_FAILURE(curr_thread->status)) { return 0; } return numConvChar; } int32_t xiua_UTF32toNative(char *target, const int32_t targetLen, const UChar32 * source, const int32_t sourceLen) { 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 xiua_UTF32toUTF16((UChar *)target,(targetLen/2), source, sourceLen); case XDFUTF32: if (sourceLen >= 0 && sourceLen <= (targetLen/4)) return xiu4_strncpyEx((UChar32 *)target,source,sourceLen); return xiu4_strncpyEx((UChar32 *)target,source,(targetLen/4)); case XDFUTF8: return xiua_UTF32toUTF8(target,targetLen, source, sourceLen); default: return xiua_UTF32toChar(target,targetLen, source, sourceLen); } return 0; } int32_t xiua_UTF32toUTF16 (UChar * target, const int32_t targetLen, const UChar32 * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; UChar32 ** mySource = (UChar32 **)&source; int32_t numConvChar = 0; curr_thread = xiux_getCurrentThread(); numConvChar = UTF32toUTF16Chunk(target,targetLen,mySource,sourceLen, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } return numConvChar; } int32_t xiua_UTF32toUTF8 (char *target, const int32_t targetLen, const UChar32 * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; UChar32 *mySource = (UChar32 *)source; UChar8U *myTarget = (UChar8U *) target; int32_t mySourceIndex = 0; int32_t myTargetIndex = 0; int32_t targetLength = targetLen; int32_t sourceLength = sourceLen; int32_t numConvChar = 0; uint32_t ch; int32_t bytesToWrite = 0; curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (sourceLen < 0) { sourceLength = targetLen * 2; /* Optimistic limit */ } while (mySourceIndex < sourceLength) { if (myTargetIndex < targetLength) { bytesToWrite = 0; ch = mySource[mySourceIndex++]; if (ch < 0x80) /* Single byte */ { if ((sourceLen < 0) && (ch == 0x00)) break; /* End of Unicode string */ bytesToWrite = 1; myTarget[myTargetIndex++] = (UChar8U) ch; } else if (ch < 0x800) /* Double byte */ { if (myTargetIndex >= targetLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } bytesToWrite = 2; myTarget[myTargetIndex++] = (UChar8U) ((ch >> 6) | 0xc0); myTarget[myTargetIndex++] = (UChar8U) ((ch & 0x3f) | 0x80); } else if (ch < 0x10000) { if ((myTargetIndex + 1) >= targetLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } bytesToWrite = 3; myTarget[myTargetIndex++] = (UChar8U) ((ch >> 12) | 0xe0); myTarget[myTargetIndex++] = (UChar8U) (((ch >> 6) & 0x3f) | 0x80); myTarget[myTargetIndex++] = (UChar8U) ((ch & 0x3f) | 0x80); } else { if ((myTargetIndex + 2) >= targetLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } bytesToWrite = 4; myTarget[myTargetIndex++] = (UChar8U) ((ch >> 18) | 0xf0); myTarget[myTargetIndex++] = (UChar8U) (((ch >> 12) & 0x3f) | 0x80); myTarget[myTargetIndex++] = (UChar8U) (((ch >> 6) & 0x3f) | 0x80); myTarget[myTargetIndex++] = (UChar8U) ((ch & 0x3f) | 0x80); } } else { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } numConvChar += bytesToWrite; /* Increment actual converted character count */ } if (myTargetIndex < targetLength) { myTarget[myTargetIndex] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } return numConvChar; } int32_t xiua_UTF32toChar (char *target, const int32_t targetLen, const UChar32 * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; UChar32 ** mySource = (UChar32 **)&source; char *myTarget = target; UChar *myWork; UChar **myWorkAddr; int32_t myTargetSize = targetLen; int32_t myWorkSize; int32_t numConvChar = 0; int32_t numUChar = 0; int32_t CharLen; UConverter* myConv; curr_thread = xiux_getCurrentThread(); myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } curr_locale = curr_thread->Curr_locale; myConv = (UConverter*)curr_locale->conv; ucnv_reset (myConv); while (*mySource) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = UTF32toUTF16Chunk ((UChar *)myWork, myWorkSize, (UChar32 **) mySource, (int32_t) sourceLen, curr_thread); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toCharChunk(myTarget,myTargetSize,myWorkAddr,numUChar, curr_thread,myConv); numConvChar += CharLen; myTarget += CharLen; myTargetSize -= CharLen; } return numConvChar; } int32_t xiua_UTF8toNative(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { 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 xiua_UTF8toUTF16Ex((UChar *)target,(targetLen/2), source, sourceLen, -1); case XDFUTF32: return xiua_UTF8toUTF32Ex((UChar32 *)target,(targetLen/4), source, sourceLen, -1); case XDFUTF8: if (sourceLen >= 0 && sourceLen <= targetLen) return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,sourceLen); return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,targetLen); default: return xiua_UTF8toCharEx(target,targetLen, source, sourceLen, -1); } return 0; } int32_t xiua_UTF8toUTF16(UChar * target, const int32_t targetLen, const char * source, const int32_t sourceLen) { return xiua_UTF8toUTF16Ex (target, targetLen, source, -1, sourceLen); } int32_t xiua_UTF8toUTF16Ex(UChar * target, const int32_t targetLen, const char * source, const int32_t numChars, const int32_t numBytes) { XIUA_Thread * curr_thread; char ** mySource = (char **)&source; int32_t numConvChar = 0; curr_thread = xiux_getCurrentThread(); numConvChar = UTF8toUTF16Chunk(target,targetLen,mySource, numChars,numBytes,curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } return numConvChar; } int32_t xiua_UTF8toUTF32 (UChar32 * target, const int32_t targetLen, const char * source, const int32_t sourceLen) { return xiua_UTF8toUTF32Ex (target, targetLen, source, -1, sourceLen); } int32_t xiua_UTF8toUTF32Ex (UChar32 * target, const int32_t targetLen, const char * source, const int32_t numChars, const int32_t numBytes) { XIUA_Thread * curr_thread; UChar8U *mySource = (UChar8U *) source; UChar32 *myTarget = target; int32_t mySourceIndex = 0; int32_t myTargetIndex = 0; int32_t targetLength = targetLen; int32_t sourceLength = numBytes; int32_t numConvChar = 0; uint32_t ch = 0 , ch2 =0 , i =0; /* Index into the current # of bytes consumed in the current sequence */ uint32_t inBytes = 0; /* Total number of bytes in the current UTF8 sequence */ curr_thread = xiux_getCurrentThread(); curr_thread->status = U_ZERO_ERROR; if (numBytes < 0) { sourceLength = targetLen * 4; /* Optimistic limit */ } while (mySourceIndex < sourceLength) { if (myTargetIndex < targetLength) { ch = 0; ch = (uint32_t)mySource[mySourceIndex++]; if (ch < 0x80) /* Simple case */ { if ( (ch == 0x00) && (numChars < 0) && (numBytes < 0)) break; /* End of UTF-8 string */ myTarget[myTargetIndex++] = ch; } else { /* store the first char */ inBytes = xbytesFromUTF8[ch]; /* lookup current sequence length */ if (inBytes < 1) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; break; } i = 1; for (; i < inBytes; i++) { if (mySourceIndex >= sourceLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } ch2 = (uint32_t)mySource[mySourceIndex++]; if ((ch2 & 0xC0) != 0x80) /* Invalid trailing byte */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; break; } ch <<= 6; ch += ch2; } if (curr_thread->status != U_ZERO_ERROR) break; ch -= xoffsetsFromUTF8[inBytes]; myTarget[myTargetIndex++] = ch; } numConvChar++; /* Increment actual converted character count */ if (numChars > 0) { if (numConvChar >= numChars) break; /* Reached character limit */ } } else /* End of target buffer */ { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } } if (myTargetIndex < targetLength) { myTarget[myTargetIndex] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } return numConvChar; } int32_t xiua_UTF8toChar (char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { return xiua_UTF8toCharEx (target, targetLen, source, -1, sourceLen); } int32_t xiua_UTF8toCharEx (char *target, const int32_t targetLen, const char * source, const int32_t numChars, const int32_t numBytes) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; char ** mySource = (char **)&source; char *myTarget = target; UChar *myWork; UChar **myWorkAddr; int32_t myTargetSize = targetLen; int32_t myWorkSize; int32_t numConvChar = 0; int32_t numUChar = 0; int32_t CharLen; UChar8U ch; UConverter* myConv; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (curr_locale->codeset == XCPUTF8 && curr_locale->format == XDFUTF8) { if (numChars >= 0) { ch = (UChar8U)source[numConvChar]; while (ch && numUChar < numChars) { CharLen = xbytesFromUTF8[ch]; if (CharLen < 1) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; return 0; } numConvChar += CharLen; numUChar++; ch = (UChar8U)source[numConvChar]; } } else { numConvChar = numBytes; } if (numConvChar >= 0 && numConvChar <= targetLen) return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,numConvChar); return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,targetLen); } myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } myConv = (UConverter*)curr_locale->conv; ucnv_reset (myConv); while (*mySource) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = UTF8toUTF16Chunk ((UChar *)myWork, myWorkSize, mySource, numChars,numBytes, curr_thread); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toCharChunk(myTarget,myTargetSize,myWorkAddr,numUChar, curr_thread,myConv); numConvChar += CharLen; myTarget += CharLen; myTargetSize -= CharLen; } return numConvChar; } int32_t xiua_ChartoNative(char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { 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 xiua_ChartoUTF16((UChar *)target,(targetLen/2), source, sourceLen); case XDFUTF32: return xiua_ChartoUTF32((UChar32 *)target,(targetLen/4), source, sourceLen); case XDFUTF8: return xiua_ChartoUTF8(target,targetLen, source, sourceLen); default: if (sourceLen >= 0 && sourceLen <= targetLen) return xicp_strncpyEx((CpChar *)target,(CpChar *)source,sourceLen); return xicp_strncpyEx((CpChar *)target,(CpChar *)source,targetLen); } return 0; } int32_t xiua_ChartoUTF16 (UChar *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Locale * curr_locale; XIUA_Thread * curr_thread; char ** mySource = (char **)&source; int32_t numConvChar = 0; UConverter* myConv; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; myConv = (UConverter*)curr_locale->conv; ucnv_reset (myConv); numConvChar = ChartoUTF16Chunk(target,targetLen,mySource,sourceLen, curr_thread,myConv); if (U_FAILURE(curr_thread->status)) { return 0; } return numConvChar; } int32_t xiua_ChartoUTF32 (UChar32 *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; char ** mySource = (char **)&source; UChar32 *myTarget = target; UChar *myWork; UChar **myWorkAddr; int32_t myTargetSize = targetLen; int32_t myWorkSize; int32_t numConvChar = 0; int32_t numUChar = 0; int32_t CharLen; UConverter* myConv; curr_thread = xiux_getCurrentThread(); myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } curr_locale = curr_thread->Curr_locale; myConv = (UConverter*)curr_locale->conv; ucnv_reset (myConv); while (*mySource) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = ChartoUTF16Chunk(myWork,myWorkSize,mySource,sourceLen, curr_thread,myConv); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toUTF32Chunk ((UChar32 *)myTarget, myTargetSize, myWorkAddr, numUChar, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget += CharLen; myTargetSize -= CharLen; } return numConvChar; } int32_t xiua_ChartoUTF8 (char *target, const int32_t targetLen, const char * source, const int32_t sourceLen) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; char ** mySource = (char **)&source; char *myTarget = target; UChar *myWork; UChar **myWorkAddr; int32_t myTargetSize = targetLen; int32_t myWorkSize; int32_t numConvChar = 0; int32_t numUChar = 0; int32_t CharLen; UConverter* myConv; curr_thread = xiux_getCurrentThread(); curr_locale = curr_thread->Curr_locale; if (curr_locale->codeset == XCPUTF8 && curr_locale->format == XDFUTF8) { if (sourceLen >= 0 && sourceLen <= targetLen) return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,sourceLen); return xiu8_strncpyEx((UChar8 *)target,(UChar8 *)source,targetLen); } myWorkSize = ((myTargetSize + 1) * 2); if (myWorkSize > MAXCNVBUFFSIZE) myWorkSize = MAXCNVBUFFSIZE/2; if (!chkWorkSize(myWorkSize*2)) { curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return 0; } myConv = (UConverter*)curr_locale->conv; ucnv_reset (myConv); while (*mySource) { myWork = (UChar *)curr_thread->work_buff; myWorkAddr = &myWork; numUChar = ChartoUTF16Chunk(myWork,myWorkSize,mySource,sourceLen, curr_thread,myConv); if (U_FAILURE(curr_thread->status) && curr_thread->status != U_BUFFER_OVERFLOW_ERROR) { return 0; } CharLen = UTF16toUTF8Chunk(myTarget, myTargetSize, myWorkAddr, numUChar, curr_thread); if (U_FAILURE(curr_thread->status)) { return 0; } numConvChar += CharLen; myTarget += CharLen; myTargetSize -= CharLen; } return numConvChar; } void xmtx_init( XMTX *mutex ) { #if (ICU_USE_THREADS == 1) if( mutex == NULL ) /* initialize the global mutex */ { mutex = &xGlobalMutex; } if(*mutex != NULL) /* someone already did it. */ return; #if defined(WIN32) *mutex = malloc(sizeof(CRITICAL_SECTION)); InitializeCriticalSection((CRITICAL_SECTION*)*mutex); #elif defined( POSIX ) *mutex = malloc(sizeof(pthread_mutex_t)); #if defined(HPUX_CMA) pthread_mutex_init((pthread_mutex_t*)*mutex, pthread_mutexattr_default); #else pthread_mutex_init((pthread_mutex_t*)*mutex,NULL); #endif #endif #endif /* ICU_USE_THREADS==1 */ } void xmtx_lock( XMTX *mutex ) { #if (ICU_USE_THREADS == 1) if( mutex == NULL ) { mutex = &xGlobalMutex; } if(*mutex == NULL) { xmtx_init(mutex); } #if defined(WIN32) EnterCriticalSection((CRITICAL_SECTION*) *mutex); #elif defined(POSIX) pthread_mutex_lock((pthread_mutex_t*) *mutex); #endif #endif /* ICU_USE_THREADS==1 */ } void xmtx_unlock( XMTX* mutex ) { #if (ICU_USE_THREADS==1) if( mutex == NULL ) { mutex = &xGlobalMutex; if(*mutex == NULL) { return; } } #if defined(WIN32) LeaveCriticalSection((CRITICAL_SECTION*)*mutex); #elif defined(POSIX) pthread_mutex_unlock((pthread_mutex_t*)*mutex); #endif #endif /* ICU_USE_THREADS == 1 */ } void xmtx_term( XMTX *mutex ) { #if (ICU_USE_THREADS == 1) if( mutex == NULL ) /* initialize the global mutex */ { mutex = &xGlobalMutex; } if(*mutex == NULL) /* someone already did it. */ return; #if defined(WIN32) DeleteCriticalSection((CRITICAL_SECTION*)*mutex); #elif defined( POSIX ) pthread_mutex_destroy((pthread_mutex_t*)*mutex); #endif free(*mutex); *mutex = NULL; #endif /* ICU_USE_THREADS==1 */ } static int32_t UTF16toUTF32Chunk (UChar32 *target, const int32_t targetLen, UChar ** source, const int32_t sourceLen, XIUA_Thread * curr_thread) { UChar *mySource = *source; UChar32 *myTarget = target; int32_t mySourceIndex = 0; int32_t myTargetIndex = 0; int32_t targetLength = targetLen; int32_t sourceLength = sourceLen; int32_t numConvChar = 0; uint32_t ch; uint32_t ch2; curr_thread->status = U_ZERO_ERROR; if (sourceLen < 0) { sourceLength = targetLen * 2; /* Optimistic limit */ } while (mySourceIndex < sourceLength) { *source = &mySource[mySourceIndex]; ch = mySource[mySourceIndex++]; if ((sourceLen < 0) && !ch) { break; } if (myTargetIndex < targetLength) { /* Check for surogates */ if ((ch >= xkSurrogateHighStart) && (ch <= xkSurrogateHighEnd)) { if (mySourceIndex < sourceLength) { ch2 = mySource[mySourceIndex]; if ((ch2 >= xkSurrogateLowStart) && (ch2 <= xkSurrogateLowEnd)) { ch = ((ch - xkSurrogateHighStart) << xhalfShift) + (ch2 - xkSurrogateLowStart) + xhalfBase; ++mySourceIndex; } } } myTarget[myTargetIndex++] = ch; } else { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } numConvChar++; /* Increment actual converted character count */ } if (U_SUCCESS(curr_thread->status)) { if (myTargetIndex < targetLength) { myTarget[myTargetIndex] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } *source = NULL; } return numConvChar; } static int32_t UTF16toUTF8Chunk (char *target, const int32_t targetLen, UChar ** source, const int32_t sourceLen, XIUA_Thread * curr_thread) { UChar *mySource = (UChar *)*source; UChar8U *myTarget = (UChar8U *) target; int32_t mySourceIndex = 0; int32_t myTargetIndex = 0; int32_t targetLength = targetLen; int32_t sourceLength = sourceLen; int32_t numConvChar = 0; uint32_t ch; int32_t bytesToWrite = 0; uint32_t ch2; curr_thread->status = U_ZERO_ERROR; if (sourceLen < 0) { sourceLength = targetLen * 3; /* Optimistic limit */ } while (mySourceIndex < sourceLength) { *source = &mySource[mySourceIndex]; if (myTargetIndex < targetLength) { bytesToWrite = 0; ch = mySource[mySourceIndex++]; if (ch < 0x80) /* Single byte */ { if ((sourceLen < 0) && (ch == 0x00)) break; /* End of Unicode string */ bytesToWrite = 1; myTarget[myTargetIndex++] = (UChar8U) ch; } else if (ch < 0x800) /* Double byte */ { if (myTargetIndex >= targetLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } bytesToWrite = 2; myTarget[myTargetIndex++] = (UChar8U) ((ch >> 6) | 0xc0); myTarget[myTargetIndex++] = (UChar8U) ((ch & 0x3f) | 0x80); } else /* Check for surogates */ { if ((ch >= xkSurrogateHighStart) && (ch <= xkSurrogateHighEnd)) { if (mySourceIndex < sourceLength) { ch2 = mySource[mySourceIndex]; if ((ch2 >= xkSurrogateLowStart) && (ch2 <= xkSurrogateLowEnd)) { ch = ((ch - xkSurrogateHighStart) << xhalfShift) + (ch2 - xkSurrogateLowStart) + xhalfBase; ++mySourceIndex; } } } if (ch < 0x10000) { if ((myTargetIndex + 1) >= targetLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } bytesToWrite = 3; myTarget[myTargetIndex++] = (UChar8U) ((ch >> 12) | 0xe0); myTarget[myTargetIndex++] = (UChar8U) (((ch >> 6) & 0x3f) | 0x80); myTarget[myTargetIndex++] = (UChar8U) ((ch & 0x3f) | 0x80); } else { if ((myTargetIndex + 2) >= targetLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } bytesToWrite = 4; myTarget[myTargetIndex++] = (UChar8U) ((ch >> 18) | 0xf0); myTarget[myTargetIndex++] = (UChar8U) (((ch >> 12) & 0x3f) | 0x80); myTarget[myTargetIndex++] = (UChar8U) (((ch >> 6) & 0x3f) | 0x80); myTarget[myTargetIndex++] = (UChar8U) ((ch & 0x3f) | 0x80); } } } else { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } numConvChar += bytesToWrite; /* Increment actual converted character count */ } if (U_SUCCESS(curr_thread->status)) { if (myTargetIndex < targetLength) { myTarget[myTargetIndex] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } *source = NULL; } return numConvChar; } /* Fast UTF8 to Unicode converter. Output buffer should be twice the size of the Unicode character count to accomodate largest possible output. This converter is designed for short low overhead conversions. It does not require opening a converter object and caller must provide both input an output buffers. A zero character count indicates a string convert. */ static int32_t UTF16toCharChunk (char *target, const int32_t targetLen, UChar ** source, const int32_t sourceLen, XIUA_Thread * curr_thread, const void * conv) { const UChar *mySource = (UChar *) *source; const UChar *mySourceEnd; char *myTarget = (char *) target; char *myTargetEnd; int32_t myTargetSize; int32_t mySourceSize; int32_t ByteLen; UConverter* myConv; curr_thread->status = U_ZERO_ERROR; myTargetSize = targetLen; mySourceSize = sourceLen; myConv = (UConverter*)conv; if ((myConv == NULL) || (myTargetSize <= 0)) { curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return 0; } if (mySourceSize == 0) { target[0] = 0x0000; return 0; } if (sourceLen < 0) { mySourceSize = u_strlen(mySource); } myTargetEnd = target + (myTargetSize); mySourceEnd = mySource + (mySourceSize); if (mySourceSize > 0) { ucnv_fromUnicode(myConv, &myTarget, myTargetEnd, &mySource, mySourceEnd, NULL, FALSE, &curr_thread->status); ByteLen = myTarget - target; } else { ByteLen = 0; } *source = (UChar *)mySource; if (U_SUCCESS(curr_thread->status)) { *source = NULL; if (ByteLen < targetLen) { target[ByteLen] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } } return ByteLen; } static int32_t UTF32toUTF16Chunk (UChar * target, const int32_t targetLen, UChar32 ** source, const int32_t sourceLen, XIUA_Thread * curr_thread) { UChar32 *mySource = *source; UChar *myTarget = (uint16_t *)target; int32_t mySourceIndex = 0; int32_t myTargetIndex = 0; int32_t targetLength = targetLen; int32_t sourceLength = sourceLen; int32_t numConvChar = 0; uint32_t ch = 0; curr_thread->status = U_ZERO_ERROR; if (sourceLen == 0) { target[0] = 0x0000; return 0; } if (sourceLen < 0) { sourceLength = xiu4_strlen(mySource); } while (mySourceIndex < sourceLength) { *source = &mySource[mySourceIndex]; if (myTargetIndex < targetLength) { ch = mySource[mySourceIndex++]; if (ch <= xkMaximumUTF16) { if (ch <= xkMaximumUCS2) { myTarget[myTargetIndex++] = (UChar) ch; } else { ch -= xhalfBase; myTarget[myTargetIndex++] = (UChar) ((ch >> xhalfShift) + xkSurrogateHighStart); ch = (ch & xhalfMask) + xkSurrogateLowStart; if (myTargetIndex < targetLength) { myTarget[myTargetIndex++] = (UChar)ch; } else { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } numConvChar++; /* Increment actual converted character count */ } } else { curr_thread->status = U_ILLEGAL_CHAR_FOUND; break; } } else /* End of target buffer */ { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } numConvChar++; /* Increment actual converted character count */ } if (U_SUCCESS(curr_thread->status)) { if (myTargetIndex < targetLength) { myTarget[myTargetIndex] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } *source = NULL; } return numConvChar; } static int32_t UTF8toUTF16Chunk(UChar * target, const int32_t targetLen, char ** source, const int32_t numChars, const int32_t numBytes, XIUA_Thread * curr_thread) { UChar8U *mySource = (UChar8U *)*source; UChar *myTarget = (uint16_t *)target; int32_t mySourceIndex = 0; int32_t myTargetIndex = 0; int32_t targetLength = targetLen; int32_t sourceLength = numBytes; int32_t numConvChar = 0; uint32_t ch = 0 , ch2 =0 , i =0; /* Index into the current # of bytes consumed in the current sequence */ uint32_t inBytes = 0; /* Total number of bytes in the current UTF8 sequence */ curr_thread->status = U_ZERO_ERROR; if (numBytes < 0) { sourceLength = targetLen * 3; /* Optimistic limit */ } while (mySourceIndex < sourceLength) { *source = (char *)&mySource[mySourceIndex]; if (myTargetIndex < targetLength) { ch = 0; ch = (uint32_t)mySource[mySourceIndex++]; if (ch < 0x80) /* Simple case */ { if ( (ch == 0x00) && (numChars < 0) && (numBytes < 0)) break; /* End of UTF-8 string */ myTarget[myTargetIndex++] = (UChar) ch; } else { /* store the first char */ inBytes = xbytesFromUTF8[ch]; /* lookup current sequence length */ if (inBytes < 1) { curr_thread->status = U_ILLEGAL_CHAR_FOUND; break; } i = 1; for (; i < inBytes; i++) { if (mySourceIndex >= sourceLength) { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } ch2 = (uint32_t)mySource[mySourceIndex++]; if ((ch2 & 0xC0) != 0x80) /* Invalid trailing byte */ { curr_thread->status = U_ILLEGAL_CHAR_FOUND; break; } ch <<= 6; ch += ch2; } if (curr_thread->status != U_ZERO_ERROR) break; ch -= xoffsetsFromUTF8[inBytes]; if (i == inBytes && ch <= xkMaximumUTF16) { if (ch <= xkMaximumUCS2) { myTarget[myTargetIndex++] = (UChar) ch; } else { ch -= xhalfBase; myTarget[myTargetIndex++] = (UChar) ((ch >> xhalfShift) + xkSurrogateHighStart); ch = (ch & xhalfMask) + xkSurrogateLowStart; if (myTargetIndex < targetLength) { myTarget[myTargetIndex++] = (UChar)ch; } else { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } } } else { curr_thread->status = U_ILLEGAL_CHAR_FOUND; break; } } } else /* End of target buffer */ { curr_thread->status = U_BUFFER_OVERFLOW_ERROR; break; } numConvChar++; /* Increment actual converted character count */ if (numChars > 0) { if (numConvChar >= numChars) break; /* Reached character limit */ } } if (U_SUCCESS(curr_thread->status)) { if (myTargetIndex < targetLength) { myTarget[myTargetIndex] = 0; /* add a null terminator */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } *source = NULL; } return numConvChar; } static int32_t ChartoUTF16Chunk (UChar *target, const int32_t targetLen, char ** source, const int32_t sourceLen, XIUA_Thread * curr_thread, const void * conv) { const char *mySource = (char *) *source; const char *mySourceEnd; UChar *myTarget = (UChar *) target; UChar *myTargetEnd; int32_t myTargetSize; int32_t mySourceSize; int32_t numUChar = 0; UConverter* myConv; curr_thread->status = U_ZERO_ERROR; myTargetSize = targetLen; mySourceSize = sourceLen; myConv = (UConverter*)conv; if (sourceLen <= 0) { mySourceSize = strlen(mySource); } myTargetEnd = target + (myTargetSize); mySourceEnd = mySource + (mySourceSize); if (mySourceSize > 0) { ucnv_toUnicode(myConv, &myTarget, myTargetEnd, &mySource, mySourceEnd, NULL, TRUE, &curr_thread->status); numUChar = myTarget - target; } else { numUChar = myTarget - target; } *source = (char *)mySource; if (U_SUCCESS(curr_thread->status)) { if (myTarget < myTargetEnd) { *myTarget = 0; /* add null */ } else { curr_thread->status = U_STRING_NOT_TERMINATED_WARNING; } *source = NULL; } return numUChar; } int32_t xiux_strToUChars(UChar *us, const char *ccs) { int32_t i = 0; char *cs = (char*)ccs; while(*cs) { i++; if (0x80 > (uint8_t)*cs) { #if U_CHARSET_FAMILY==U_ASCII_FAMILY *us++=(UChar)(uint8_t)(*cs++); #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY *us++=(UChar)asciiFromEbcdic[(uint8_t)(*cs++)]; #else # error U_CHARSET_FAMILY is not valid #endif } else { *us++ = 0x0020; cs++; } } *us = 0; return i; } #if 0 int32_t xiux_UCharsTostr(char *cs,const UChar *cus) { int32_t i = 0; UChar *us = (UChar *)cus; while(*us) { i++; if (*us <= 0x007f) { #if U_CHARSET_FAMILY==U_ASCII_FAMILY *cs++=(char)(*us++); #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY *cs++=(char)ebcdicFromAscii[(uint8_t)(*us++)]; #else # error U_CHARSET_FAMILY is not valid #endif } else { *cs++ = 0x20; us++; } } *cs = 0; return i; } #endif int32_t xiux_strToNUChars(UChar *us, const char *ccs, int32_t size) { int32_t i = 0; char * cs = (char *)ccs; while(*cs) { i++; if (i >= size) break; if (0x80 > (uint8_t)*cs) { #if U_CHARSET_FAMILY==U_ASCII_FAMILY *us++=(UChar)(uint8_t)(*cs++); #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY *us++=(UChar)asciiFromEbcdic[(uint8_t)(*cs++)]; #else # error U_CHARSET_FAMILY is not valid #endif } else { *us++ = 0x0020; cs++; } } *us = 0; return i; } int32_t xiux_UCharsToNstr(char *cs, const UChar *cus, int32_t size) { int32_t i = 0; UChar *us = (UChar *)cus; while(*us) { i++; if (i >= size) break; if (*us <= 0x007f) { #if U_CHARSET_FAMILY==U_ASCII_FAMILY *cs++=(char)(*us++); #elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY *cs++=(char)ebcdicFromAscii[(uint8_t)(*us++)]; #else # error U_CHARSET_FAMILY is not valid #endif } else { *cs++ = 0x20; us++; } } *cs = 0; return i; } void * xiux_malloc(size_t s) { return uprv_malloc(s); } void * xiux_realloc(void * buffer, size_t size) { return uprv_realloc(buffer, size); } void xiux_free(void *buffer) { uprv_free(buffer); return; } XIUA_Thread * xiux_getCurrentThread(void) { XIUA_Thread * curr_thread; /* do initialization if haven't done so */ xiua_Init(); curr_thread = xiua_get_tls_pointer(xiua_tls_key); if (curr_thread == NULL) xiua_InitThread(); if (curr_thread->Curr_locale == NULL) xiua_OpenLocale(NULL,XDFCODEPAGE); return curr_thread; } static XIUA_Thread * getCurrentThreadEx(void) { XIUA_Thread * curr_thread; /* do initialization if haven't done so */ xiua_Init(); curr_thread = xiua_get_tls_pointer(xiua_tls_key); if (curr_thread == NULL) xiua_InitThread(); return curr_thread; } static UBool chkWorkSize(int wrkSize) { XIUA_Thread * curr_thread; int new_size; char * new_buff; curr_thread = xiux_getCurrentThread(); if (curr_thread->work_size >= wrkSize) { if (curr_thread->save_size == 0) return TRUE; if (curr_thread->save_size >= wrkSize) { free(curr_thread->work_buff); curr_thread->work_size = curr_thread->save_size; curr_thread->save_size = 0; curr_thread->work_buff = curr_thread->save_buff; curr_thread->save_buff = NULL; } return TRUE; } new_size = (((wrkSize >> 8) + 1) << 8); new_buff = malloc(new_size); if (new_buff) { if ((new_size > MAXWRKBUFFSIZE) && (curr_thread->save_size == 0)) { curr_thread->save_size = curr_thread->work_size; curr_thread->save_buff = curr_thread->work_buff; curr_thread->work_size = new_size; curr_thread->work_buff = new_buff; return TRUE; } free(curr_thread->work_buff); curr_thread->work_size = new_size; curr_thread->work_buff = new_buff; return TRUE; } curr_thread->status = U_MEMORY_ALLOCATION_ERROR; return FALSE; } /* Get default locale in POSIX Format */ static void GetPOSIXDefaultLocale (char * locale) { UErrorCode err; char LocName[XIUA_MAXPOSIXLOCALESIZE]; char WrkName[XIUA_MAXLOCALESIZE]; char WrkCset[XIUA_MAXCHARSETSIZE]; char * Charset; char *v; /* Format: (no spaces) ll [ _CC ] [ . MM ] [ @ VV] l = lang, C = ctry, M = charmap, V = variant */ err = U_ZERO_ERROR; strcpy(WrkName,uloc_getDefault()); v = &WrkName[0]; if((v = strchr(v, '_')) != NULL) { v++; if((v = strchr(v, '_')) != NULL) { *v++ = 0; } } strcpy(LocName,WrkName); strcat(LocName,"."); strcpy(WrkCset,ucnv_getDefaultName()); err = U_ZERO_ERROR; Charset = (char *)ucnv_getStandardName(WrkCset, "MIME", &err); if (Charset == NULL) { err = U_ZERO_ERROR; Charset = (char *)ucnv_getStandardName(WrkCset, "IANA", &err); } if (Charset == NULL) Charset = (char *)&WrkCset[0]; strcat(LocName,Charset); if (v) { strcat(LocName,"@"); strcat(LocName,v); } strncpy(locale,LocName,XIUA_MAXPOSIXLOCALESIZE); locale[XIUA_MAXPOSIXLOCALESIZE-1] = 0; return; } static const char * defaultCodePageForLocale(const char *locale) { int i; int locale_len; long curr_time; if (locale == NULL) { return NULL; } locale_len = strlen(locale); if(locale_len < 2) { return NULL; /* non existent. Not a complete check, but it will * make sure that 'c' doesn't match catalan, etc. **/ } for(i=0; _localeToDefaultCharmapTableX[i].loc; i++) { if(strncmp(locale, _localeToDefaultCharmapTableX[i].loc, Min(locale_len, (int)strlen(_localeToDefaultCharmapTableX[i].loc))) == 0) { return _localeToDefaultCharmapTableX[i].charmap; } } curr_time = getUTCtime(); if (curr_time >= 1009843200) { return "iso-8859-15"; } else { return "iso-8859-1"; } } static void extractLocale(char* LocaleID,const char* POSIXLocale, XIUA_Thread * curr_thread) { char fullPOSIXLocale[XIUA_MAXFULLLOCALESIZE]; char *l; char *c; char *m; char *v; unsigned int i; if (U_FAILURE(curr_thread->status)) return; curr_thread->status = U_ZERO_ERROR; /* Format: (no spaces) ll [ _CC ] [ . MM ] [ @ VV] l = lang, C = ctry, M = charmap, V = variant */ strncpy((char *)fullPOSIXLocale,POSIXLocale,XIUA_MAXFULLLOCALESIZE-1); fullPOSIXLocale[XIUA_MAXFULLLOCALESIZE-1] = 0; v = (char *)fullPOSIXLocale; l = v; if((c = strchr(v, '_')) != NULL) { *c++ = 0; v = c; } if((m = strchr(v, '.')) != NULL) { *m++ = 0; v = m; } if((v = strchr(v, '@')) != NULL) { *v++ = 0; } strcpy(LocaleID,l); if (c) { strcat(LocaleID,"_"); strcat(LocaleID,c); } else { if (v) strcat(LocaleID,"_"); } if (v) { strcat(LocaleID,"_"); i = XIUA_MAXLOCALESIZE - strlen(LocaleID); i--; /* decrement for null at end of string */ strncat(LocaleID,v,i); if (strlen(v) > i) { LocaleID[XIUA_MAXLOCALESIZE-1] = 0; /* add null */ curr_thread->status = U_BUFFER_OVERFLOW_ERROR; /* error message */ } } return; } static void extractCharset(char* Charset,const char* POSIXLocale, XIUA_Thread * curr_thread) { char fullPOSIXLocale[XIUA_MAXFULLLOCALESIZE]; char *l; char *c; char *m; char *v; if (U_FAILURE(curr_thread->status)) return; /* Format: (no spaces) ll [ _CC ] [ . MM ] [ @ VV] l = lang, C = ctry, M = charmap, V = variant */ strncpy((char *)fullPOSIXLocale,POSIXLocale,XIUA_MAXFULLLOCALESIZE-1); fullPOSIXLocale[XIUA_MAXFULLLOCALESIZE-1] = 0; v = (char *)fullPOSIXLocale; l = v; if((c = strchr(v, '_')) != NULL) { *c++ = 0; v = c; } if((m = strchr(v, '.')) != NULL) { *m++ = 0; v = m; } if((v = strchr(v, '@')) != NULL) { *v++ = 0; } if (m) { strncpy(Charset,m,XIUA_MAXCHARSETSIZE-1); Charset[XIUA_MAXCHARSETSIZE-1] = 0; curr_thread->status = U_ZERO_ERROR; } else { Charset[0] = 0; curr_thread->status = U_MISSING_RESOURCE_ERROR; } return; } static XIUA_Locale * FindLocale(char * source, XIUA_DataFormat format) { XIUA_Thread * curr_thread; XIUA_Locale * curr_locale; curr_thread = getCurrentThreadEx(); curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->First_locale; if (!curr_locale) return NULL; if (format == XDFANY) { while (curr_locale) { if (strcmp(curr_locale->locale, source) == 0) return curr_locale; curr_locale = (XIUA_Locale *)curr_locale->next; } } else { while (curr_locale) { if ((strcmp(curr_locale->locale, source) == 0) && (curr_locale->open_format == format)) return curr_locale; curr_locale = (XIUA_Locale *)curr_locale->next; } } return NULL; } /** * API: validate locale, standardize locale name using * locale definition from resource file. * * NOTE!! locale must point to an array of char at least * XIUA_MAXLOCALESIZE long because the locale string is replaced * with a new standardized locale name which may be a * different size. */ static UBool chkLocale(const char * path, const char * locale, XIUA_LocIterate iterate, XIUA_Thread * curr_thread) { UResourceBundle * resB; const char *NewName; char LocName[XIUA_MAXLOCALESIZE]; char FixName[XIUA_MAXLOCALESIZE]; size_t loc_len, loc_len2; int i, j; int32_t l_len = 0; int32_t c_len = 0; int32_t v_len = 0; char *Loc_c = NULL; char *Loc_v = NULL; char *Fix_c = NULL; char *Fix_v = NULL; unsigned char *LocNamex = (unsigned char *)LocName; UErrorCode int_err = U_ZERO_ERROR; if (!locale || !*locale) { curr_thread->status = U_ILLEGAL_ARGUMENT_ERROR; return FALSE; } curr_thread->status = U_ZERO_ERROR; memset(LocName,0,XIUA_MAXLOCALESIZE); strncpy(LocName,locale,XIUA_MAXLOCALESIZE-1); loc_len = strlen(LocName); if (loc_len < 2) return FALSE; if (LocName[0] == '_' || LocName[0] == '-') return FALSE; if (LocName[1] == '_') LocName[1] = '-'; LocName[0] = (char)tolower(LocName[0]); if (LocName[1] == '-' && LocName[0] != 'i' && LocName[0] != 'x') return FALSE; for (i=2;i<(int)loc_len;i++) { if (LocName[i] == '-') LocName[i] = '_'; } Loc_c = strchr(LocName,'_'); if (Loc_c) { loc_len2 = strlen(Loc_c); if (loc_len2 > 1) { Loc_v = strchr(Loc_c+1,'_'); } } else { loc_len2 = 0; } i = j = loc_len - loc_len2; while (i) { i--; LocNamex[i] = (unsigned char)(tolower((int)LocName[i]) & 0xFF); } i = loc_len; while (i > j) { i--; LocNamex[i] = (unsigned char)(toupper((int)LocName[i]) & 0xFF); } /* rebuild locale name using standard language & country names */ memset(FixName,0,XIUA_MAXLOCALESIZE); l_len = uloc_getLanguage(LocName, FixName, XIUA_MAXLOCALESIZE, &curr_thread->status); #if (XIUA_ICU_LEVEL > 0) l_len++; #endif if (U_FAILURE(curr_thread->status)) return FALSE; if (Loc_c) { strcat(FixName, "_"); Fix_c = FixName + l_len -1; c_len = uloc_getCountry(LocName, Fix_c + 1, XIUA_MAXLOCALESIZE - l_len, &curr_thread->status); #if (XIUA_ICU_LEVEL > 0) c_len++; #endif if (U_FAILURE(curr_thread->status)) return FALSE; if (Loc_v) { v_len = strlen(Loc_v); Fix_v = Fix_c + c_len; strncpy(Fix_v,Loc_v,XIUA_MAXLOCALESIZE - l_len - c_len); } } resB = ures_open(path, FixName, &curr_thread->status); while (curr_thread->status != U_ZERO_ERROR) { if (U_SUCCESS(curr_thread->status)) ures_close(resB); if (iterate == XLOC_MATCH_EXACT) return FALSE; if (Loc_c) { /* use original contry code as varient an variant if any as a country code */ if (Loc_v) { Fix_v = Fix_c + v_len; strncpy(Fix_c,Loc_v,XIUA_MAXLOCALESIZE - l_len - c_len); } else { *Fix_c = '_'; Fix_v = Fix_c + 1; } uloc_getCountry(LocName, Fix_v + 1, XIUA_MAXLOCALESIZE - l_len - v_len, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return FALSE; int_err = U_ZERO_ERROR; resB = ures_open(path, FixName, &int_err); if (int_err == U_ZERO_ERROR) { curr_thread->status = U_USING_FALLBACK_WARNING; break; } if (U_SUCCESS(curr_thread->status)) ures_close(resB); } if (iterate == XLOC_MATCH_VARIANT) return FALSE; if (Loc_c && Loc_v) { /* country and variant */ /* remove variant and try again */ uloc_getCountry(LocName, Fix_c + 1, XIUA_MAXLOCALESIZE - l_len, &curr_thread->status); if (U_FAILURE(curr_thread->status)) return FALSE; int_err = U_ZERO_ERROR; resB = ures_open(path, FixName, &int_err); if (int_err == U_ZERO_ERROR) { curr_thread->status = U_USING_FALLBACK_WARNING; break; } if (U_SUCCESS(curr_thread->status)) ures_close(resB); } if (iterate == XLOC_MATCH_SUBLANG) return FALSE; if (Loc_c) { /* country */ /* remove country and try again */ *Fix_c = 0; int_err = U_ZERO_ERROR; resB = ures_open(path, FixName, &int_err); if (int_err == U_ZERO_ERROR) { curr_thread->status = U_USING_FALLBACK_WARNING; break; } if (U_SUCCESS(curr_thread->status)) ures_close(resB); } return FALSE; } int_err = U_ZERO_ERROR; NewName = ures_getLocale(resB, &int_err); strcpy((char *)locale, NewName); ures_close(resB); return TRUE; } static UBool chkCharset(const char * charset, const char * locale, int32_t * index) { char WrkCharset[XIUA_MAXCHARSETSIZE]; char *CharPtr; int i; int locale_len; strncpy(WrkCharset,charset,XIUA_MAXCHARSETSIZE-1); WrkCharset[XIUA_MAXCHARSETSIZE-1] = 0; CharPtr = WrkCharset; while (*CharPtr) { *CharPtr = (char)tolower(*CharPtr); CharPtr++; } if (strcmp(WrkCharset,"utf-8") == 0 || strcmp(WrkCharset,"utf8") == 0) return TRUE; locale_len = strlen(locale); if (*index < 0) { for(i=0; _localeToDefaultCharmapTableX[i].loc; i++) { if(strncmp(locale, _localeToDefaultCharmapTableX[i].loc, Min(locale_len, (int)strlen(_localeToDefaultCharmapTableX[i].loc))) == 0) break; } *index = i; } i = *index; if (_localeToDefaultCharmapTableX[i].loc == NULL) { if (strcmp(WrkCharset,"iso-8859-1") == 0 || strcmp(WrkCharset,"windows-1252") == 0 || strcmp(WrkCharset,"cp-1252") == 0 || strcmp(WrkCharset,"iso-8859-15") == 0) return TRUE; return FALSE; } while(_localeToDefaultCharmapTableX[i].loc) { if(strncmp(locale, _localeToDefaultCharmapTableX[i].loc, Min(locale_len, (int)strlen(_localeToDefaultCharmapTableX[i].loc))) != 0) return FALSE; if(strcmp(WrkCharset, _localeToDefaultCharmapTableX[i].charmap) == 0) return TRUE; i++; } return FALSE; } static int32_t cpCharLen(const CpCharU *str, XIUA_Thread * curr_thread) { XIUA_Locale * curr_locale; int i, j; curr_thread->status = U_ZERO_ERROR; curr_locale = curr_thread->Curr_locale; i = str[0]; if (!i) return 0; switch(curr_locale->codeset) { case XCP1BYTE: return 1; case XCPSJIS: if ((DBCStable[i] & 0x04)) return 2; return 1; case XCPBIG5: case XCP936: if ((DBCStable[i] & 0x10)) return 2; return 1; case XCPKSC: if ((DBCStable[i] & 0x40)) return 2; return 1; case XCPEUCJP: if (i == 0x8E) return 2; /* SS2 */ if (i == 0x8F) return 3; /* SS3 */ case XCPEUCCN: case XCPEUCKR: if (i >= 0xA1 && i <= 0xFE) return 2; return 1; case XCPEUCTW: if (i >= 0xA1 && i <= 0xFE) return 2; if (i == 0x8E) return 4; /* SS2 */ return 1; case XCPGB18030: if (i >= 0x81 && i <= 0xFE) { j = str[1]; if (j >= 0x30 && j <= 0x39) return 4; return 2; } return 1; case XCP2022: case XCP2022J: case XCP2022K: case XCP2022C: curr_thread->status = U_UNSUPPORTED_ERROR; return 1; case XCPUTF8: j = xbytesFromUTF8[i]; if (j > 0) return j; return 1; default: break; } curr_thread->status = U_INVALID_FORMAT_ERROR; return 1; } /* Get UTC (GMT) time measured in seconds since 0:00 on 1/1/70.*/ static int32_t getUTCtime() { #ifdef XP_MAC time_t t, t1, t2; struct tm tmrec; memset( &tmrec, 0, sizeof(tmrec) ); tmrec.tm_year = 70; tmrec.tm_mon = 0; tmrec.tm_mday = 1; t1 = mktime(&tmrec); /* seconds of 1/1/1970*/ time(&t); memcpy( &tmrec, gmtime(&t), sizeof(tmrec) ); t2 = mktime(&tmrec); /* seconds of current GMT*/ return t2 - t1; /* GMT (or UTC) in seconds since 1970*/ #else time_t epochtime; time(&epochtime); return epochtime; #endif } #if (XIUA_ICU_LEVEL == 0) /*-------------------------------------------------------------- * Routine to convert an unsigned integer into a Unicode * character string. * Will left truncate or zero fill *-------------------------------------------------------------*/ static int32_t itou(UChar *target, uint32_t source, int32_t targetBase, int32_t targetLen) { UChar hextab[] = {0x0030, 0x0031, 0x0032,0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046}; int32_t Len; int32_t Base; uint32_t ch; uint32_t Unum; Len = targetLen; Base = targetBase; Unum = source; if (Base > 16) Base = 16; if (Base < 2) Base = 2; Len--; while (Len >= 0) { ch = Unum%Base; target[Len] = hextab[ch]; Unum = Unum/Base; Len--; } return targetLen; } /*Fixed version of UCNV_FROM_U_CALLBACK_ESCAPE */ #define VALUE_STRING_LENGTH 32 /*Magic # 32 = 4(number of char in value string) * 8(max number of bytes per char for any converter) */ #define UNICODE_PERCENT_SIGN_CODEPOINT 0x0025 #define UNICODE_U_CODEPOINT 0x0055 #define UNICODE_X_CODEPOINT 0x0058 #define UNICODE_RS_CODEPOINT 0x005C #define UNICODE_U_LOW_CODEPOINT 0x0075 #define UNICODE_X_LOW_CODEPOINT 0x0078 #define UNICODE_AMP_CODEPOINT 0x0026 #define UNICODE_HASH_CODEPOINT 0x0023 #define UNICODE_SEMICOLON_CODEPOINT 0x003B #define UCNV_PRV_ESCAPE_ICU 0 #define UCNV_PRV_ESCAPE_C 'C' #define UCNV_PRV_ESCAPE_XML_DEC 'D' #define UCNV_PRV_ESCAPE_XML_HEX 'X' #define UCNV_PRV_ESCAPE_JAVA 'J' static void XIUA_FROM_U_CALLBACK_ESCAPE ( void *context, UConverterFromUnicodeArgs *fromArgs, const UChar *codeUnits, int32_t length, UChar32 codePoint, UConverterCallbackReason reason, UErrorCode * err) { UChar valueString[VALUE_STRING_LENGTH]; int32_t valueStringLength = 0; int32_t i = 0; UChar32 temp = codePoint; const UChar *myValueSource = NULL; UErrorCode err2 = U_ZERO_ERROR; UConverterFromUCallback original = NULL; void *originalContext; UConverterFromUCallback ignoredCallback = NULL; void *ignoredContext; if (reason > UCNV_IRREGULAR) { return; } ucnv_setFromUCallBack (fromArgs->converter, (UConverterFromUCallback) UCNV_FROM_U_CALLBACK_SUBSTITUTE, NULL, /* To Do for HSYS: context is null? */ &original, &originalContext, &err2); if (U_FAILURE (err2)) { *err = err2; return; } if(context==NULL) { while (i < length) { valueString[valueStringLength++] = (UChar) UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */ valueString[valueStringLength++] = (UChar) UNICODE_U_CODEPOINT; /* adding U */ itou(valueString + valueStringLength, codeUnits[i++], 16, 4); valueStringLength += 4; } } else { switch(*((char*)context)) { case UCNV_PRV_ESCAPE_JAVA: while (i < length) { valueString[valueStringLength++] = (UChar) UNICODE_RS_CODEPOINT; /* adding \ */ valueString[valueStringLength++] = (UChar) UNICODE_U_LOW_CODEPOINT; /* adding u */ itou(valueString + valueStringLength, codeUnits[i++], 16, 4); valueStringLength += 4; } break; case UCNV_PRV_ESCAPE_C: valueString[valueStringLength++] = (UChar) UNICODE_RS_CODEPOINT; /* adding \ */ if(length==2){ temp = UTF16_GET_PAIR_VALUE(codeUnits[0],codeUnits[1]); valueString[valueStringLength++] = (UChar) UNICODE_U_CODEPOINT; /* adding U *CWB*/ valueStringLength += itou(valueString + valueStringLength, temp, 16, 8); } else{ valueString[valueStringLength++] = (UChar) UNICODE_U_LOW_CODEPOINT; /* adding u *CWB*/ valueStringLength += itou(valueString + valueStringLength, codeUnits[0], 16, 4); } break; case UCNV_PRV_ESCAPE_XML_DEC: valueString[valueStringLength++] = (UChar) UNICODE_AMP_CODEPOINT; /* adding & */ valueString[valueStringLength++] = (UChar) UNICODE_HASH_CODEPOINT; /* adding # */ if(length==2){ UChar32 temp = UTF16_GET_PAIR_VALUE(codeUnits[0],codeUnits[1]); valueStringLength += itou(valueString + valueStringLength, temp, 10, 0); } else{ valueStringLength += itou(valueString + valueStringLength, codeUnits[0], 10, 4); } valueString[valueStringLength++] = (UChar) UNICODE_SEMICOLON_CODEPOINT; /* adding ; *CWB*/ break; case UCNV_PRV_ESCAPE_XML_HEX: valueString[valueStringLength++] = (UChar) UNICODE_AMP_CODEPOINT; /* adding & */ valueString[valueStringLength++] = (UChar) UNICODE_HASH_CODEPOINT; /* adding # */ valueString[valueStringLength++] = (UChar) UNICODE_X_LOW_CODEPOINT; /* adding x */ if(length==2){ UChar32 temp = UTF16_GET_PAIR_VALUE(codeUnits[0],codeUnits[1]); valueStringLength += itou(valueString + valueStringLength, temp, 16, 0); } else{ valueStringLength += itou(valueString + valueStringLength, codeUnits[0], 16, 4); } valueString[valueStringLength++] = (UChar) UNICODE_SEMICOLON_CODEPOINT; /* adding ; *CWB*/ break; default: while (i < length) { valueString[valueStringLength++] = (UChar) UNICODE_PERCENT_SIGN_CODEPOINT; /* adding % */ valueString[valueStringLength++] = (UChar) UNICODE_U_CODEPOINT; /* adding U */ itou(valueString + valueStringLength, codeUnits[i++], 16, 4); valueStringLength += 4; } } } myValueSource = valueString; /* reset the error */ *err = U_ZERO_ERROR; ucnv_cbFromUWriteUChars(fromArgs, &myValueSource, myValueSource+valueStringLength, 0, err); ucnv_setFromUCallBack (fromArgs->converter, original, originalContext, &ignoredCallback, &ignoredContext, &err2); if (U_FAILURE (err2)) { *err = err2; return; } return; } #endif #ifdef APACHE_SERVER /* Apache only code */ static void *xiua_create_dir(pool *p, char *dir) { xiua_dir_conf *conf = (xiua_dir_conf *) ap_palloc(p, sizeof(xiua_dir_conf)); conf->locale = ap_pstrdup(p, "en_US"); conf->charset = ap_pstrdup(p, "iso-8859-1"); conf->dirlevel = 0; conf->XIUA_types = ap_make_table(p, 4); return conf; } static void *xiua_merge_dir(pool *p, void *basev, void *addv) { xiua_dir_conf *base = (xiua_dir_conf *) basev; xiua_dir_conf *add = (xiua_dir_conf *) addv; xiua_dir_conf *conf = (xiua_dir_conf *) ap_palloc(p, sizeof(xiua_dir_conf)); memcpy(conf,base, sizeof(xiua_dir_conf)); conf->locale = add->locale; conf->charset = add->charset; conf->dirlevel = add->dirlevel; conf->XIUA_types = ap_copy_table(p, base->XIUA_types); return conf; } static const char *add_XIUAtype(cmd_parms *cmd, xiua_dir_conf *dc, char *ct, char *ext) { if (*ext == '.') ++ext; ap_str_tolower(ct); ap_table_setn(dc->XIUA_types, ext, ct); return NULL; } static const command_rec xiua_cmds[] = { {"AddXIUAType", add_XIUAtype, NULL, OR_FILEINFO, ITERATE2, "a mime type for XIUA to track followed by one or more file extensions"}, /* cwb */ {NULL} }; static int xiua_info(request_rec *r) { /* Test message */ r->content_type = "text/html"; ap_soft_timeout("send xiua test header call trace", r); ap_send_http_header(r); if (r->header_only) { ap_kill_timeout(r); return OK; } ap_rputs(DOCTYPE_HTML_3_2, r); ap_rputs("\n", r); ap_rputs(" \n", r); ap_rputs(" xIUA Test page\n", r); ap_rputs(" \n", r); ap_rputs(" \n", r); ap_rputs(" \n", r); ap_rputs("

xIUA X.Net, Inc. Internationalization and Unicode Adaptor\n", r); ap_rputs("

\n", r); ap_rputs("

\n", r); ap_rprintf(r, " Apache HTTP Server version: \"%s\"\n", ap_get_server_version()); ap_rputs("
\n", r); ap_rprintf(r, " Server built: \"%s\"\n", ap_get_server_built()); ap_rputs("

\n", r); ap_rputs(" \n", r); ap_rputs("\n", r); ap_kill_timeout(r); return OK; } static const handler_rec xiua_handlers[] = { {"xiua-info", xiua_info}, {NULL} }; static int set_charset(request_rec *r, xiua_dir_conf *conf) { char **new_lang; char *curr_lang; int lang_len; if (conf->locale) { curr_lang = ap_pstrdup(r->pool, conf->locale); lang_len = strlen(curr_lang); if (lang_len > 4) curr_lang[4] = tolower(curr_lang[4]); if (lang_len > 3) curr_lang[3] = tolower(curr_lang[3]); if (lang_len > 2) curr_lang[2] = '-'; r->content_language = curr_lang; /* back compat. only */ if (!r->content_languages) r->content_languages = ap_make_array(r->pool, 2, sizeof(char *)); new_lang = (char **) ap_push_array(r->content_languages); *new_lang = curr_lang; } return 0; } /* * This routine is the first called for a new request from a user and it * it is used to check the URI to see it it is a request that XIUA should * handle. If so is sets the language for the application. * * This is called after mod_mime has set its own values at type check time. * because mod_xiua is loaded after mod_mime. */ static int xiua_fixups(request_rec *r) { xiua_dir_conf *conf; xiua_dir_conf temp; UErrorCode icu_err; char Locale[12]; char Charset[20]; const char *uri_ext; char *ext; const char *ext_type; if (r->uri == NULL) return DECLINED; uri_ext = strrchr(r->uri, '/'); if (uri_ext == NULL) return DECLINED; /* grab configuration settings */ conf = ap_get_module_config(r->per_dir_config, &xiua_module); /* Parse uri extensions, which can be in any order */ while ((ext = ap_getword(r->pool, &uri_ext, '.')) && *ext) { /* Check for Content-Type if ext matches, don't care what is returned */ if (ext_type = ap_table_get(conf->XIUA_types, ext)) { Locale[0] = 0; if (conf->locale) strncpy((char *)Locale,conf->locale,11); Charset[0] = 0; if (conf->charset) strncpy((char *)Charset,conf->charset,19); icu_err = U_ZERO_ERROR; xiua_Init(); conf = &temp; conf->locale = &Locale[0]; conf->charset = &Charset[0]; conf->dirlevel = xiua_scanDir(Locale, r->uri, &icu_err); if (U_SUCCESS(icu_err)) { xiua_setLocale(Locale, &icu_err); } set_charset(r,conf); /* ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, r->server, "xiua_type_check uri=%s lang=%s",r->uri,r->content_language); xiuaInit((void *)0); */ } } return OK; } /* * Define Apache module block */ module MODULE_VAR_EXPORT xiua_module = { STANDARD_MODULE_STUFF, NULL, /* initializer */ xiua_create_dir, /* dir config creater */ xiua_merge_dir, /* dir merger --- default is to override */ NULL, /* server config */ NULL, /* merge server config */ xiua_cmds, /* command table */ xiua_handlers, /* [9] handlers */ NULL, /* [2] URI filename translation */ NULL, /* [5] check_user_id */ NULL, /* [6] check auth */ NULL, /* [4] check access */ NULL, /* [7] type_checker */ xiua_fixups, /* [8] fixups */ NULL, /* [10] logger */ NULL, /* [3] header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* [1] post read-request */ }; #endif