1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius* Copyright (C) 1996-2012, International Business Machines 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* file name: ucol_res.cpp 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* encoding: US-ASCII 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* tab size: 8 (not used) 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* indentation:4 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Description: 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* This file contains dependencies that the collation run-time doesn't normally 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* need. This mainly contains resource bundle usage and collation meta information 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification history 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Comments 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 1996-1999 various members of ICU team maintained C API for collation framework 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/16/2001 synwee Added internal method getPrevSpecialCE 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/01/2001 synwee Added maxexpansion functionality. 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/16/2001 weiv Collation framework is rewritten in C and made UCA compliant 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 12/08/2004 grhoten Split part of ucol.cpp into ucol_res.cpp 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uloc.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/coll.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tblcoll.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/caniter.h" 3127f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/uscript.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_bld.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_imp.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_tok.h" 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_elm.h" 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h" 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustr_imp.h" 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 42c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "ucln_in.h" 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ustrenum.h" 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h" 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "utracimp.h" 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "uenumimp.h" 48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "ulist.h" 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_USE 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5227f654740f2a26ad62a5c155af9199af9e69b889clairehostatic void ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UErrorCode *status); 5327f654740f2a26ad62a5c155af9199af9e69b889claireho 54c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// static UCA. There is only one. Collators don't use it. 55c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// It is referenced only in ucol_initUCA and ucol_cleanup 56c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic UCollator* _staticUCA = NULL; 57c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// static pointer to udata memory. Inited in ucol_initUCA 58c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru// used for cleanup in ucol_cleanup 59c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic UDataMemory* UCA_DATA_MEM = NULL; 60c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 62c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic UBool U_CALLCONV 63c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_res_cleanup(void) 64c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 65c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (UCA_DATA_MEM) { 66c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru udata_close(UCA_DATA_MEM); 67c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UCA_DATA_MEM = NULL; 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 69c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (_staticUCA) { 70c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucol_close(_staticUCA); 71c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru _staticUCA = NULL; 72c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 73c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return TRUE; 74c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 75c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 76c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic UBool U_CALLCONV 77c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruisAcceptableUCA(void * /*context*/, 78c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const char * /*type*/, const char * /*name*/, 79c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru const UDataInfo *pInfo){ 80c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* context, type & name are intentionally not used */ 81c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if( pInfo->size>=20 && 82c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pInfo->isBigEndian==U_IS_BIG_ENDIAN && 83c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pInfo->charsetFamily==U_CHARSET_FAMILY && 84c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pInfo->dataFormat[0]==UCA_DATA_FORMAT_0 && /* dataFormat="UCol" */ 85c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pInfo->dataFormat[1]==UCA_DATA_FORMAT_1 && 86c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pInfo->dataFormat[2]==UCA_DATA_FORMAT_2 && 87c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru pInfo->dataFormat[3]==UCA_DATA_FORMAT_3 && 88b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pInfo->formatVersion[0]==UCA_FORMAT_VERSION_0 89b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if UCA_FORMAT_VERSION_1!=0 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && pInfo->formatVersion[1]>=UCA_FORMAT_VERSION_1 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif 92c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru //pInfo->formatVersion[1]==UCA_FORMAT_VERSION_1 && 93c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru //pInfo->formatVersion[2]==UCA_FORMAT_VERSION_2 && // Too harsh 94c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru //pInfo->formatVersion[3]==UCA_FORMAT_VERSION_3 && // Too harsh 95c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ) { 96c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UVersionInfo UCDVersion; 97c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru u_getUnicodeVersion(UCDVersion); 98c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (UBool)(pInfo->dataVersion[0]==UCDVersion[0] 99c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru && pInfo->dataVersion[1]==UCDVersion[1]); 100c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru //&& pInfo->dataVersion[2]==ucaDataInfo.dataVersion[2] 101c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru //&& pInfo->dataVersion[3]==ucaDataInfo.dataVersion[3]); 102c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } else { 103c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return FALSE; 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 108c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru/* do not close UCA returned by ucol_initUCA! */ 109c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUCollator * 110c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_initUCA(UErrorCode *status) { 111c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(U_FAILURE(*status)) { 112c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return NULL; 113c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 114c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UBool needsInit; 115c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UMTX_CHECK(NULL, (_staticUCA == NULL), needsInit); 116c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 117c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(needsInit) { 118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UDataMemory *result = udata_openChoice(U_ICUDATA_COLL, UCA_DATA_TYPE, UCA_DATA_NAME, isAcceptableUCA, NULL, status); 119c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 120c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(U_SUCCESS(*status)){ 121c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UCollator *newUCA = ucol_initCollator((const UCATableHeader *)udata_getMemory(result), NULL, NULL, status); 122c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(U_SUCCESS(*status)){ 123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru // Initalize variables for implicit generation 124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_uca_initImplicitConstants(status); 125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 126c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru umtx_lock(NULL); 127c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(_staticUCA == NULL) { 128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UCA_DATA_MEM = result; 129c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru _staticUCA = newUCA; 130c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru newUCA = NULL; 131c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result = NULL; 132c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 133c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru umtx_unlock(NULL); 134c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 135c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucln_i18n_registerCleanup(UCLN_I18N_UCOL_RES, ucol_res_cleanup); 136c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(newUCA != NULL) { 137c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucol_close(newUCA); 138c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru udata_close(result); 139c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 140c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru }else{ 141c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucol_close(newUCA); 142c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru udata_close(result); 143c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 144c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 145c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru else { 146c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru udata_close(result); 147c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 148c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 149c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return _staticUCA; 150c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 151c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 152c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI void U_EXPORT2 153c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_forgetUCA(void) 154c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 155c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru _staticUCA = NULL; 156c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UCA_DATA_MEM = NULL; 157c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 158c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/****************************************************************************/ 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Following are the open/close functions */ 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* */ 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/****************************************************************************/ 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UCollator* 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerutryOpeningFromRules(UResourceBundle *collElem, UErrorCode *status) { 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rulesLen = 0; 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *rules = ures_getStringByKey(collElem, "Sequence", &rulesLen, status); 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ucol_openRules(rules, rulesLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, status); 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// API in ucol_imp.h 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC UCollator* 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_open_internal(const char *loc, 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 177c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode intStatus = U_ZERO_ERROR; 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UCollator* UCA = ucol_initUCA(status); 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* New version */ 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) return 0; 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCollator *result = NULL; 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *b = ures_open(U_ICUDATA_COLL, loc, status); 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* we try to find stuff from keyword */ 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status); 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *collElem = NULL; 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keyBuffer[256]; 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if there is a keyword, we pick it up and try to get elements 193b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(!uloc_getKeywordValue(loc, "collation", keyBuffer, 256, status) || 194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru !uprv_strcmp(keyBuffer,"default")) { /* Treat 'zz@collation=default' as 'zz'. */ 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no keyword. we try to find the default setting, which will give us the keyword value 196c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru intStatus = U_ZERO_ERROR; 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // finding default value does not affect collation fallback status 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, &intStatus); 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(intStatus)) { 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t defaultKeyLen = 0; 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, &intStatus); 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen); 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keyBuffer[defaultKeyLen] = 0; 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_INTERNAL_PROGRAM_ERROR; 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(defaultColl); 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 210c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru collElem = ures_getByKeyWithFallback(collations, keyBuffer, collations, status); 211c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru collations = NULL; // We just reused the collations object as collElem. 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *binary = NULL; 21427f654740f2a26ad62a5c155af9199af9e69b889claireho UResourceBundle *reorderRes = NULL; 21527f654740f2a26ad62a5c155af9199af9e69b889claireho 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*status == U_MISSING_RESOURCE_ERROR) { /* We didn't find the tailoring data, we fallback to the UCA */ 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_USING_DEFAULT_WARNING; 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ucol_initCollator(UCA->image, result, UCA, status); 219c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (U_FAILURE(*status)) { 220c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru goto clean; 221c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if we use UCA, real locale is root 223c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ures_close(b); 224c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru b = ures_open(U_ICUDATA_COLL, "", status); 225c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ures_close(collElem); 226c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru collElem = ures_open(U_ICUDATA_COLL, "", status); 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->hasRealData = FALSE; 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(U_SUCCESS(*status)) { 232c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru intStatus = U_ZERO_ERROR; 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 234c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru binary = ures_getByKey(collElem, "%%CollationBin", NULL, &intStatus); 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 236c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(intStatus == U_MISSING_RESOURCE_ERROR) { /* we didn't find the binary image, we should use the rules */ 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru binary = NULL; 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = tryOpeningFromRules(collElem, status); 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(U_SUCCESS(intStatus)) { /* otherwise, we'll pick a collation data that exists */ 243c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t len = 0; 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const uint8_t *inData = ures_getBinary(binary, &len, status); 245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*status)) { 246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru goto clean; 247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCATableHeader *colData = (UCATableHeader *)inData; 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_memcmp(colData->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)) != 0 || 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcmp(colData->UCDVersion, UCA->image->UCDVersion, sizeof(UVersionInfo)) != 0 || 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru colData->version[0] != UCOL_BUILDER_VERSION) 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_DIFFERENT_UCA_VERSION; 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = tryOpeningFromRules(collElem, status); 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((uint32_t)len > (paddedsize(sizeof(UCATableHeader)) + paddedsize(sizeof(UColOptionSet)))) { 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ucol_initCollator((const UCATableHeader *)inData, result, UCA, status); 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->hasRealData = TRUE; 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ucol_initCollator(UCA->image, result, UCA, status); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_setOptionsFromHeader(result, (UColOptionSet *)(inData+((const UCATableHeader *)inData)->options), status); 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->hasRealData = FALSE; 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->freeImageOnClose = FALSE; 27427f654740f2a26ad62a5c155af9199af9e69b889claireho 27527f654740f2a26ad62a5c155af9199af9e69b889claireho reorderRes = ures_getByKey(collElem, "%%ReorderCodes", NULL, &intStatus); 27627f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_SUCCESS(intStatus)) { 27727f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t reorderCodesLen = 0; 27827f654740f2a26ad62a5c155af9199af9e69b889claireho const int32_t* reorderCodes = ures_getIntVector(reorderRes, &reorderCodesLen, status); 279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (reorderCodesLen > 0) { 280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ucol_setReorderCodes(result, reorderCodes, reorderCodesLen, status); 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // copy the reorder codes into the default reorder codes 282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result->defaultReorderCodesLength = result->reorderCodesLength; 283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result->defaultReorderCodes = (int32_t*) uprv_malloc(result->defaultReorderCodesLength * sizeof(int32_t)); 284b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(result->defaultReorderCodes, result->reorderCodes, result->defaultReorderCodesLength * sizeof(int32_t)); 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result->freeDefaultReorderCodesOnClose = TRUE; 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 28727f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*status)) { 28827f654740f2a26ad62a5c155af9199af9e69b889claireho goto clean; 28927f654740f2a26ad62a5c155af9199af9e69b889claireho } 29027f654740f2a26ad62a5c155af9199af9e69b889claireho } 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 29227f654740f2a26ad62a5c155af9199af9e69b889claireho 293b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { // !U_SUCCESS(binaryStatus) 294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_SUCCESS(*status)) { 295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *status = intStatus; // propagate underlying error 296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru goto clean; 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 299c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru intStatus = U_ZERO_ERROR; 300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->rules = ures_getStringByKey(collElem, "Sequence", &result->rulesLength, &intStatus); 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->freeRulesOnClose = FALSE; 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { /* There is another error, and we're just gonna clean up */ 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 306c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru intStatus = U_ZERO_ERROR; 307c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->ucaRules = ures_getStringByKey(b,"UCARules",NULL,&intStatus); 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(loc == NULL) { 310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru loc = ures_getLocaleByType(b, ULOC_ACTUAL_LOCALE, status); 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 312c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->requestedLocale = uprv_strdup(loc); 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* test for NULL */ 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result->requestedLocale == NULL) { 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto clean; 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru loc = ures_getLocaleByType(collElem, ULOC_ACTUAL_LOCALE, status); 319c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->actualLocale = uprv_strdup(loc); 320c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* test for NULL */ 321c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (result->actualLocale == NULL) { 322c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 323c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru goto clean; 324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 325b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru loc = ures_getLocaleByType(b, ULOC_ACTUAL_LOCALE, status); 326c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->validLocale = uprv_strdup(loc); 327c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru /* test for NULL */ 328c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (result->validLocale == NULL) { 329c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 330c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru goto clean; 331c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 333c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ures_close(b); 334c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ures_close(collElem); 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(binary); 33627f654740f2a26ad62a5c155af9199af9e69b889claireho ures_close(reorderRes); 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclean: 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(b); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(collElem); 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(binary); 34327f654740f2a26ad62a5c155af9199af9e69b889claireho ures_close(reorderRes); 344c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucol_close(result); 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UCollator* 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_open(const char *loc, 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN); 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_DATA1(UTRACE_INFO, "locale = \"%s\"", loc); 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCollator *result = NULL; 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = Collator::createUCollator(loc, status); 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (result == NULL) 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ucol_open_internal(loc, status); 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_EXIT_PTR_STATUS(result, *status); 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 36927f654740f2a26ad62a5c155af9199af9e69b889claireho 37027f654740f2a26ad62a5c155af9199af9e69b889clairehoUCollator* 37127f654740f2a26ad62a5c155af9199af9e69b889clairehoucol_openRulesForImport( const UChar *rules, 37227f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t rulesLength, 37327f654740f2a26ad62a5c155af9199af9e69b889claireho UColAttributeValue normalizationMode, 37427f654740f2a26ad62a5c155af9199af9e69b889claireho UCollationStrength strength, 37527f654740f2a26ad62a5c155af9199af9e69b889claireho UParseError *parseError, 37627f654740f2a26ad62a5c155af9199af9e69b889claireho GetCollationRulesFunction importFunc, 37727f654740f2a26ad62a5c155af9199af9e69b889claireho void* context, 37827f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *status) 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UColTokenParser src; 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UColAttributeValue norm; 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError tErr; 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)){ 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rules == NULL || rulesLength < -1) { 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rulesLength == -1) { 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru rulesLength = u_strlen(rules); 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(parseError == NULL){ 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru parseError = &tErr; 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(normalizationMode) { 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCOL_OFF: 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCOL_ON: 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCOL_DEFAULT: 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru norm = normalizationMode; 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 412c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UCollator *result = NULL; 413c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UCATableHeader *table = NULL; 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCollator *UCA = ucol_initUCA(status); 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)){ 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 42027f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_tok_initTokenList(&src, rules, rulesLength, UCA, importFunc, context, status); 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_tok_assembleTokenList(&src,parseError, status); 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) { 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if status is U_ILLEGAL_ARGUMENT_ERROR, src->current points at the offending option */ 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* if status is U_INVALID_FORMAT_ERROR, src->current points after the problematic part of the rules */ 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* so something might be done here... or on lower level */ 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef UCOL_DEBUG 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(*status == U_ILLEGAL_ARGUMENT_ERROR) { 42927f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "bad option starting at offset %i\n", (int)(src.current-src.source)); 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 43127f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "invalid rule just before offset %i\n", (int)(src.current-src.source)); 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 434c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru goto cleanup; 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius /* if we have a set of rules, let's make something of it */ 438103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(src.resultLen > 0 || src.removeSet != NULL) { 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* also, if we wanted to remove some contractions, we should make a tailoring */ 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru table = ucol_assembleTailoringTable(&src, status); 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(*status)) { 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // builder version 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru table->version[0] = UCOL_BUILDER_VERSION; 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no tailoring information on this level 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru table->version[1] = table->version[2] = table->version[3] = 0; 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set UCD version 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_getUnicodeVersion(table->UCDVersion); 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set UCA version 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(table->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)); 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ucol_initCollator(table, 0, UCA, status); 451c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (U_FAILURE(*status)) { 452c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru goto cleanup; 453c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->hasRealData = TRUE; 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->freeImageOnClose = TRUE; 45654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else { 45754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius goto cleanup; 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { /* no rules, but no error either */ 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // must be only options 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We will init the collator from UCA 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = ucol_initCollator(UCA->image, 0, UCA, status); 463c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check for null result 464c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (U_FAILURE(*status)) { 465c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru goto cleanup; 466c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // And set only the options 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UColOptionSet *opts = (UColOptionSet *)uprv_malloc(sizeof(UColOptionSet)); 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* test for NULL */ 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (opts == NULL) { 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanup; 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(opts, src.opts, sizeof(UColOptionSet)); 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_setOptionsFromHeader(result, opts, status); 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->freeOptionsOnClose = TRUE; 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->hasRealData = FALSE; 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->freeImageOnClose = FALSE; 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 481c8af25d6feb025f9d7a5bb88a1d7187c7e98b10aclaireho ucol_setReorderCodesFromParser(result, &src, status); 482c8af25d6feb025f9d7a5bb88a1d7187c7e98b10aclaireho 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(*status)) { 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *newRules; 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->dataVersion[0] = UCOL_BUILDER_VERSION; 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(rulesLength > 0) { 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newRules = (UChar *)uprv_malloc((rulesLength+1)*U_SIZEOF_UCHAR); 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* test for NULL */ 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newRules == NULL) { 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanup; 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_memcpy(newRules, rules, rulesLength*U_SIZEOF_UCHAR); 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newRules[rulesLength]=0; 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->rules = newRules; 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->rulesLength = rulesLength; 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->freeRulesOnClose = TRUE; 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->ucaRules = NULL; 500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result->actualLocale = NULL; 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->validLocale = NULL; 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result->requestedLocale = NULL; 50327f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_buildPermutationTable(result, status); 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_setAttribute(result, UCOL_STRENGTH, strength, status); 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_setAttribute(result, UCOL_NORMALIZATION_MODE, norm, status); 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querucleanup: 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != NULL) { 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_close(result); 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(table != NULL) { 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(table); 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = NULL; 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_tok_closeTokenList(&src); 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 52327f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI UCollator* U_EXPORT2 52427f654740f2a26ad62a5c155af9199af9e69b889clairehoucol_openRules( const UChar *rules, 52527f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t rulesLength, 52627f654740f2a26ad62a5c155af9199af9e69b889claireho UColAttributeValue normalizationMode, 52727f654740f2a26ad62a5c155af9199af9e69b889claireho UCollationStrength strength, 52827f654740f2a26ad62a5c155af9199af9e69b889claireho UParseError *parseError, 52927f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *status) 53027f654740f2a26ad62a5c155af9199af9e69b889claireho{ 53127f654740f2a26ad62a5c155af9199af9e69b889claireho return ucol_openRulesForImport(rules, 53227f654740f2a26ad62a5c155af9199af9e69b889claireho rulesLength, 53327f654740f2a26ad62a5c155af9199af9e69b889claireho normalizationMode, 53427f654740f2a26ad62a5c155af9199af9e69b889claireho strength, 53527f654740f2a26ad62a5c155af9199af9e69b889claireho parseError, 53627f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_tok_getRulesFromBundle, 53727f654740f2a26ad62a5c155af9199af9e69b889claireho NULL, 53827f654740f2a26ad62a5c155af9199af9e69b889claireho status); 53927f654740f2a26ad62a5c155af9199af9e69b889claireho} 54027f654740f2a26ad62a5c155af9199af9e69b889claireho 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getRulesEx(const UCollator *coll, UColRuleOption delta, UChar *buffer, int32_t bufferLen) { 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len = 0; 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t UCAlen = 0; 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar* ucaRules = 0; 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *rules = ucol_getRules(coll, &len); 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(delta == UCOL_FULL_RULES) { 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* take the UCA rules and append real rules at the end */ 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* UCA rules will be probably coming from the root RB */ 551c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucaRules = coll->ucaRules; 552c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (ucaRules) { 553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UCAlen = u_strlen(ucaRules); 554c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 556c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru ucaRules = ures_getStringByKey(coll->rb,"UCARules",&UCAlen,&status); 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle* cresb = ures_getByKeyWithFallback(coll->rb, "collations", NULL, &status); 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle* uca = ures_getByKeyWithFallback(cresb, "UCA", NULL, &status); 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucaRules = ures_getStringByKey(uca,"Sequence",&UCAlen,&status); 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(uca); 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(cresb); 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(buffer!=0 && bufferLen>0){ 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *buffer=0; 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(UCAlen > 0) { 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_memcpy(buffer, ucaRules, uprv_min(UCAlen, bufferLen)); 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len > 0 && bufferLen > UCAlen) { 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u_memcpy(buffer+UCAlen, rules, uprv_min(len, bufferLen-UCAlen)); 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return u_terminateUChars(buffer, bufferLen, len+UCAlen, &status); 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const UChar _NUL = 0; 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const UChar* U_EXPORT2 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getRules( const UCollator *coll, 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t *length) 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(coll->rules != NULL) { 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *length = coll->rulesLength; 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return coll->rules; 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *length = 0; 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return &_NUL; 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_equals(const UCollator *source, const UCollator *target) { 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if pointers are equal, collators are equal 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(source == target) { 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0, j = 0; 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if any of attributes are different, collators are not equal 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) { 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(ucol_getAttribute(source, (UColAttribute)i, &status) != ucol_getAttribute(target, (UColAttribute)i, &status) || U_FAILURE(status)) { 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 60927f654740f2a26ad62a5c155af9199af9e69b889claireho if (source->reorderCodesLength != target->reorderCodesLength){ 61027f654740f2a26ad62a5c155af9199af9e69b889claireho return FALSE; 61127f654740f2a26ad62a5c155af9199af9e69b889claireho } 61227f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < source->reorderCodesLength; i++) { 61327f654740f2a26ad62a5c155af9199af9e69b889claireho if(source->reorderCodes[i] != target->reorderCodes[i]) { 61427f654740f2a26ad62a5c155af9199af9e69b889claireho return FALSE; 61527f654740f2a26ad62a5c155af9199af9e69b889claireho } 61627f654740f2a26ad62a5c155af9199af9e69b889claireho } 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceRulesLen = 0, targetRulesLen = 0; 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *sourceRules = ucol_getRules(source, &sourceRulesLen); 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *targetRules = ucol_getRules(target, &targetRulesLen); 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceRulesLen == targetRulesLen && u_strncmp(sourceRules, targetRules, sourceRulesLen) == 0) { 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // all the attributes are equal and the rules are equal - collators are equal 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return(TRUE); 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // hard part, need to construct tree from rules and see if they yield the same tailoring 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool result = TRUE; 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError parseError; 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UColTokenParser sourceParser, targetParser; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceListLen = 0, targetListLen = 0; 63127f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_tok_initTokenList(&sourceParser, sourceRules, sourceRulesLen, source->UCA, ucol_tok_getRulesFromBundle, NULL, &status); 63227f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_tok_initTokenList(&targetParser, targetRules, targetRulesLen, target->UCA, ucol_tok_getRulesFromBundle, NULL, &status); 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceListLen = ucol_tok_assembleTokenList(&sourceParser, &parseError, &status); 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetListLen = ucol_tok_assembleTokenList(&targetParser, &parseError, &status); 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceListLen != targetListLen) { 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // different number of resets 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UColToken *sourceReset = NULL, *targetReset = NULL; 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *sourceResetString = NULL, *targetResetString = NULL; 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceStringLen = 0, targetStringLen = 0; 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < sourceListLen; i++) { 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceReset = sourceParser.lh[i].reset; 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceResetString = sourceParser.source+(sourceReset->source & 0xFFFFFF); 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceStringLen = sourceReset->source >> 24; 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j = 0; j < sourceListLen; j++) { 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetReset = targetParser.lh[j].reset; 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetResetString = targetParser.source+(targetReset->source & 0xFFFFFF); 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetStringLen = targetReset->source >> 24; 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceStringLen == targetStringLen && (u_strncmp(sourceResetString, targetResetString, sourceStringLen) == 0)) { 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceReset = sourceParser.lh[i].first; 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetReset = targetParser.lh[j].first; 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(sourceReset != NULL && targetReset != NULL) { 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceResetString = sourceParser.source+(sourceReset->source & 0xFFFFFF); 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceStringLen = sourceReset->source >> 24; 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetResetString = targetParser.source+(targetReset->source & 0xFFFFFF); 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetStringLen = targetReset->source >> 24; 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceStringLen != targetStringLen || (u_strncmp(sourceResetString, targetResetString, sourceStringLen) != 0)) { 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto returnResult; 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // probably also need to check the expansions 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceReset->expansion) { 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!targetReset->expansion) { 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto returnResult; 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compare expansions 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceResetString = sourceParser.source+(sourceReset->expansion& 0xFFFFFF); 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceStringLen = sourceReset->expansion >> 24; 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetResetString = targetParser.source+(targetReset->expansion & 0xFFFFFF); 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetStringLen = targetReset->expansion >> 24; 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceStringLen != targetStringLen || (u_strncmp(sourceResetString, targetResetString, sourceStringLen) != 0)) { 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto returnResult; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(targetReset->expansion) { 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto returnResult; 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sourceReset = sourceReset->next; 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetReset = targetReset->next; 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(sourceReset != targetReset) { // at least one is not NULL 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // there are more tailored elements in one list 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto returnResult; 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // couldn't find the reset anchor, so the collators are not equal 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(j == sourceListLen) { 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = FALSE; 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto returnResult; 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerureturnResult: 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_tok_closeTokenList(&sourceParser); 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_tok_closeTokenList(&targetParser); 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getDisplayName( const char *objLoc, 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *dispLoc, 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar *result, 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t resultLength, 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(*status)) return -1; 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString dst; 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!(result==NULL && resultLength==0)) { 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // NULL destination for pure preflighting: empty dummy string 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // otherwise, alias the destination buffer 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dst.setTo(result, 0, resultLength); 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Collator::getDisplayName(Locale(objLoc), Locale(dispLoc), dst); 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dst.extract(result, resultLength, *status); 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char* U_EXPORT2 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getAvailable(int32_t index) 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Locale *loc = Collator::getAvailableLocales(count); 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (loc != NULL && index < count) { 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return loc[index].getName(); 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_countAvailable() 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Collator::getAvailableLocales(count); 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return count; 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_openAvailableLocales(UErrorCode *status) { 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is a wrapper over Collator::getAvailableLocales() 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 761103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius StringEnumeration *s = icu::Collator::getAvailableLocales(); 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (s == NULL) { 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 766b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return uenum_openFromStringEnumeration(s, status); 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Note: KEYWORDS[0] != RESOURCE_NAME - alan 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 772c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const char RESOURCE_NAME[] = "collations"; 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 774c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustatic const char* const KEYWORDS[] = { "collation" }; 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define KEYWORD_COUNT (sizeof(KEYWORDS)/sizeof(KEYWORDS[0])) 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getKeywords(UErrorCode *status) { 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UEnumeration *result = NULL; 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(*status)) { 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uenum_openCharStringsEnumeration(KEYWORDS, KEYWORD_COUNT, status); 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getKeywordValues(const char *keyword, UErrorCode *status) { 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(*status)) { 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // hard-coded to accept exactly one collation keyword 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // modify if additional collation keyword is added later 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (keyword==NULL || uprv_strcmp(keyword, KEYWORDS[0])!=0) 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ures_getKeywordValues(U_ICUDATA_COLL, RESOURCE_NAME, status); 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 802b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic const UEnumeration defaultKeywordValues = { 803b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, 804b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru NULL, 805b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_close_keyword_values_iterator, 806b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_count_keyword_values, 807b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uenum_unextDefault, 808b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_next_keyword_value, 809b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_reset_keyword_values_iterator 810b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}; 811b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 81250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include <stdio.h> 81350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 814b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI UEnumeration* U_EXPORT2 815b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruucol_getKeywordValuesForLocale(const char* /*key*/, const char* locale, 816b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool /*commonlyUsed*/, UErrorCode* status) { 817b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Get the locale base name. */ 818b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char localeBuffer[ULOC_FULLNAME_CAPACITY] = ""; 819b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uloc_getBaseName(locale, localeBuffer, sizeof(localeBuffer), status); 820b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 821b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Create the 2 lists 822b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * -values is the temp location for the keyword values 823b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * -results hold the actual list used by the UEnumeration object 824b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 825b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UList *values = ulist_createEmptyList(status); 826b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UList *results = ulist_createEmptyList(status); 827b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); 828b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status) || en == NULL) { 829b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (en == NULL) { 830b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *status = U_MEMORY_ALLOCATION_ERROR; 831b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 832b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(en); 833b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 834b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(values); 835b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(results); 836b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 837b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 838b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 839b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); 840b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru en->context = results; 841b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 842b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Open the resource bundle for collation with the given locale. */ 843b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UResourceBundle bundle, collations, collres, defres; 844b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&bundle); 845b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&collations); 846b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&collres); 847b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_initStackObject(&defres); 848b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 849b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_openFillIn(&bundle, U_ICUDATA_COLL, localeBuffer, status); 850b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 851b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (U_SUCCESS(*status)) { 852b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getByKey(&bundle, RESOURCE_NAME, &collations, status); 853b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_resetIterator(&collations); 854b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while (U_SUCCESS(*status) && ures_hasNext(&collations)) { 855b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getNextResource(&collations, &collres, status); 856b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const char *key = ures_getKey(&collres); 857b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* If the key is default, get the string and store it in results list only 858b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * if results list is empty. 859b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 860b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (uprv_strcmp(key, "default") == 0) { 861b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (ulist_getListSize(results) == 0) { 862b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *defcoll = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY); 863b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t defcollLength = ULOC_KEYWORDS_CAPACITY; 864b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 865b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getNextResource(&collres, &defres, status); 86650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if U_CHARSET_FAMILY==U_ASCII_FAMILY 86750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho /* optimize - use the utf-8 string */ 868b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_getUTF8String(&defres, defcoll, &defcollLength, TRUE, status); 86950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#else 87050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho { 87150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar* defString = ures_getString(&defres, &defcollLength, status); 87250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(U_SUCCESS(*status)) { 87350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if(defcollLength+1 > ULOC_KEYWORDS_CAPACITY) { 87450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho *status = U_BUFFER_OVERFLOW_ERROR; 87550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 87650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho u_UCharsToChars(defString, defcoll, defcollLength+1); 87750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 87850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 87950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 88050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif 881b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 882b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_addItemBeginList(results, defcoll, TRUE, status); 883b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 884b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 885b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_addItemEndList(values, key, FALSE, status); 886b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 887b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 888b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 889b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* If the locale is "" this is root so exit. */ 890b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (uprv_strlen(localeBuffer) == 0) { 891b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 892b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 893b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Get the parent locale and open a new resource bundle. */ 894b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uloc_getParent(localeBuffer, localeBuffer, sizeof(localeBuffer), status); 895b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_openFillIn(&bundle, U_ICUDATA_COLL, localeBuffer, status); 896b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 897b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 898b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&defres); 899b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&collres); 900b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&collations); 901b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ures_close(&bundle); 902b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 903b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_SUCCESS(*status)) { 904b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru char *value = NULL; 905b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_resetList(values); 906b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while ((value = (char *)ulist_getNext(values)) != NULL) { 90750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!ulist_containsString(results, value, (int32_t)uprv_strlen(value))) { 908b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_addItemEndList(results, value, FALSE, status); 909b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)) { 910b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 911b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 912b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 913b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 914b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 915b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 916b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_deleteList(values); 917b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 918b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if (U_FAILURE(*status)){ 919b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uenum_close(en); 920b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru en = NULL; 921b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 922b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ulist_resetList(results); 923b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 924b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 925b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return en; 926b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 927b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getFunctionalEquivalent(char* result, int32_t resultCapacity, 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* keyword, const char* locale, 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool* isAvailable, UErrorCode* status) 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // N.B.: Resource name is "collations" but keyword is "collation" 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ures_getFunctionalEquivalent(result, resultCapacity, U_ICUDATA_COLL, 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "collations", keyword, locale, 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isAvailable, TRUE, status); 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* returns the locale name the collation data comes from */ 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getLocale(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) { 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ucol_getLocaleByType(coll, type, status); 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI const char * U_EXPORT2 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getLocaleByType(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) { 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *result = NULL; 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)) { 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_ENTRY(UTRACE_UCOL_GETLOCALE); 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_DATA1(UTRACE_INFO, "coll=%p", coll); 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 954103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if(coll->delegate!=NULL) { 955103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return ((const Collator*)coll->delegate)->getLocale(type, *status).getName(); 956103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(type) { 958c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru case ULOC_ACTUAL_LOCALE: 959c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result = coll->actualLocale; 960c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 961c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru case ULOC_VALID_LOCALE: 962c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result = coll->validLocale; 963c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 964c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru case ULOC_REQUESTED_LOCALE: 965c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru result = coll->requestedLocale; 966c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru break; 967c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru default: 968c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_DATA1(UTRACE_INFO, "result = %s", result); 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_EXIT_STATUS(*status); 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void U_EXPORT2 976c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_setReqValidLocales(UCollator *coll, char *requestedLocaleToAdopt, char *validLocaleToAdopt, char *actualLocaleToAdopt) 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (coll) { 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (coll->validLocale) { 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(coll->validLocale); 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru coll->validLocale = validLocaleToAdopt; 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (coll->requestedLocale) { // should always have 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(coll->requestedLocale); 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru coll->requestedLocale = requestedLocaleToAdopt; 987c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (coll->actualLocale) { 988c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uprv_free(coll->actualLocale); 989c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 990c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru coll->actualLocale = actualLocaleToAdopt; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI USet * U_EXPORT2 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getTailoredSet(const UCollator *coll, UErrorCode *status) 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_NAMESPACE_USE 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(status == NULL || U_FAILURE(*status)) { 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(coll == NULL || coll->UCA == NULL) { 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError parseError; 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UColTokenParser src; 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rulesLen = 0; 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *rules = ucol_getRules(coll, &rulesLen); 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool startOfRules = TRUE; 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we internally use the C++ class, for the following reasons: 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1. we need to utilize canonical iterator, which is a C++ only class 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 2. canonical iterator returns UnicodeStrings - USet cannot take them 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 3. USet is internally really UnicodeSet, C is just a wrapper 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeSet *tailored = new UnicodeSet(); 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString pattern; 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString empty; 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CanonicalIterator it(empty, *status); 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The idea is to tokenize the rule set. For each non-reset token, 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we add all the canonicaly equivalent FCD sequences 102327f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_tok_initTokenList(&src, rules, rulesLen, coll->UCA, ucol_tok_getRulesFromBundle, NULL, status); 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (ucol_tok_parseNextToken(&src, startOfRules, &parseError, status) != NULL) { 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startOfRules = FALSE; 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(src.parsedToken.strength != UCOL_TOK_RESET) { 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *stuff = src.source+(src.parsedToken.charsOffset); 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru it.setSource(UnicodeString(stuff, src.parsedToken.charsLen), *status); 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pattern = it.next(); 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(!pattern.isBogus()) { 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(Normalizer::quickCheck(pattern, UNORM_FCD, *status) != UNORM_NO) { 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tailored->add(pattern); 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pattern = it.next(); 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucol_tok_closeTokenList(&src); 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (USet *)tailored; 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104227f654740f2a26ad62a5c155af9199af9e69b889claireho/* 104327f654740f2a26ad62a5c155af9199af9e69b889claireho * Collation Reordering 104427f654740f2a26ad62a5c155af9199af9e69b889claireho */ 104527f654740f2a26ad62a5c155af9199af9e69b889claireho 1046b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UErrorCode *status) { 104727f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*status)) { 104827f654740f2a26ad62a5c155af9199af9e69b889claireho return; 104927f654740f2a26ad62a5c155af9199af9e69b889claireho } 105027f654740f2a26ad62a5c155af9199af9e69b889claireho 1051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (parser->reorderCodesLength == 0 || parser->reorderCodes == NULL) { 1052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 105527f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodesLength = 0; 1056b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->reorderCodes != NULL && coll->freeReorderCodesOnClose == TRUE) { 105727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(coll->reorderCodes); 105827f654740f2a26ad62a5c155af9199af9e69b889claireho } 105927f654740f2a26ad62a5c155af9199af9e69b889claireho 1060b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->defaultReorderCodes != NULL && coll->freeDefaultReorderCodesOnClose == TRUE) { 1061b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(coll->defaultReorderCodes); 1062b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1063b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->defaultReorderCodesLength = parser->reorderCodesLength; 1064b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->defaultReorderCodes = (int32_t*) uprv_malloc(coll->defaultReorderCodesLength * sizeof(int32_t)); 1065b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->defaultReorderCodes == NULL) { 1066b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = U_MEMORY_ALLOCATION_ERROR; 106727f654740f2a26ad62a5c155af9199af9e69b889claireho return; 106827f654740f2a26ad62a5c155af9199af9e69b889claireho } 1069b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(coll->defaultReorderCodes, parser->reorderCodes, coll->defaultReorderCodesLength * sizeof(int32_t)); 1070b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->freeDefaultReorderCodesOnClose = TRUE; 107127f654740f2a26ad62a5c155af9199af9e69b889claireho 107227f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodesLength = parser->reorderCodesLength; 107327f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodes = (int32_t*) uprv_malloc(coll->reorderCodesLength * sizeof(int32_t)); 1074b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->reorderCodes == NULL) { 1075b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = U_MEMORY_ALLOCATION_ERROR; 1076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 107827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memcpy(coll->reorderCodes, parser->reorderCodes, coll->reorderCodesLength * sizeof(int32_t)); 1079b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->freeReorderCodesOnClose = TRUE; 108027f654740f2a26ad62a5c155af9199af9e69b889claireho} 108127f654740f2a26ad62a5c155af9199af9e69b889claireho 1082b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 1083b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Data is stored in the reorder code to lead byte table as: 1084b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * index count - unsigned short (2 bytes) - number of index entries 1085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * data size - unsigned short (2 bytes) - number of unsigned short data elements 1086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * index[index count] - array of 2 unsigned shorts (4 bytes each entry) 1087b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - reorder code, offset 1088b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - index is sorted by reorder code 1089b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - if an offset has the high bit set then it is not an offset but a single data entry 1090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * once the high bit is stripped off 1091b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * data[data size] - array of unsigned short (2 bytes each entry) 1092b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - the data is an usigned short count followed by count number 1093b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * of lead bytes stored in an unsigned short 1094b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1095b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CFUNC int U_EXPORT2 1096b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoucol_getLeadBytesForReorderCode(const UCollator *uca, int reorderCode, uint16_t* returnLeadBytes, int returnCapacity) { 1097b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t reorderCodeIndexLength = *((uint16_t*) ((uint8_t *)uca->image + uca->image->scriptToLeadByte)); 1098b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t* reorderCodeIndex = (uint16_t*) ((uint8_t *)uca->image + uca->image->scriptToLeadByte + 2 *sizeof(uint16_t)); 109927f654740f2a26ad62a5c155af9199af9e69b889claireho 110027f654740f2a26ad62a5c155af9199af9e69b889claireho // reorder code index is 2 uint16_t's - reorder code + offset 110127f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < reorderCodeIndexLength; i++) { 110227f654740f2a26ad62a5c155af9199af9e69b889claireho if (reorderCode == reorderCodeIndex[i*2]) { 110327f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t dataOffset = reorderCodeIndex[(i*2) + 1]; 110427f654740f2a26ad62a5c155af9199af9e69b889claireho if ((dataOffset & 0x8000) == 0x8000) { 110527f654740f2a26ad62a5c155af9199af9e69b889claireho // offset isn't offset but instead is a single data element 110627f654740f2a26ad62a5c155af9199af9e69b889claireho if (returnCapacity >= 1) { 110727f654740f2a26ad62a5c155af9199af9e69b889claireho returnLeadBytes[0] = dataOffset & ~0x8000; 110827f654740f2a26ad62a5c155af9199af9e69b889claireho return 1; 110927f654740f2a26ad62a5c155af9199af9e69b889claireho } 111027f654740f2a26ad62a5c155af9199af9e69b889claireho return 0; 111127f654740f2a26ad62a5c155af9199af9e69b889claireho } 111227f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t* dataOffsetBase = (uint16_t*) ((uint8_t *)reorderCodeIndex + reorderCodeIndexLength * (2 * sizeof(uint16_t))); 111327f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t leadByteCount = *(dataOffsetBase + dataOffset); 111427f654740f2a26ad62a5c155af9199af9e69b889claireho leadByteCount = leadByteCount > returnCapacity ? returnCapacity : leadByteCount; 111527f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memcpy(returnLeadBytes, dataOffsetBase + dataOffset + 1, leadByteCount * sizeof(uint16_t)); 111627f654740f2a26ad62a5c155af9199af9e69b889claireho return leadByteCount; 111727f654740f2a26ad62a5c155af9199af9e69b889claireho } 111827f654740f2a26ad62a5c155af9199af9e69b889claireho } 111927f654740f2a26ad62a5c155af9199af9e69b889claireho return 0; 112027f654740f2a26ad62a5c155af9199af9e69b889claireho} 112127f654740f2a26ad62a5c155af9199af9e69b889claireho 1122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 1123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Data is stored in the lead byte to reorder code table as: 1124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * index count - unsigned short (2 bytes) - number of index entries 1125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * data size - unsigned short (2 bytes) - number of unsigned short data elements 1126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * index[index count] - array of unsigned short (2 bytes each entry) 1127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - index is sorted by lead byte 1128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - if an index has the high bit set then it is not an index but a single data entry 1129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * once the high bit is stripped off 1130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * data[data size] - array of unsigned short (2 bytes each entry) 1131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * - the data is an usigned short count followed by count number of reorder codes 1132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CFUNC int U_EXPORT2 1134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoucol_getReorderCodesForLeadByte(const UCollator *uca, int leadByte, int16_t* returnReorderCodes, int returnCapacity) { 1135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t* leadByteTable = ((uint16_t*) ((uint8_t *)uca->image + uca->image->leadByteToScript)); 1136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t leadByteIndexLength = *leadByteTable; 113727f654740f2a26ad62a5c155af9199af9e69b889claireho if (leadByte >= leadByteIndexLength) { 113827f654740f2a26ad62a5c155af9199af9e69b889claireho return 0; 113927f654740f2a26ad62a5c155af9199af9e69b889claireho } 1140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t leadByteIndex = *(leadByteTable + (2 + leadByte)); 1141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((leadByteIndex & 0x8000) == 0x8000) { 114327f654740f2a26ad62a5c155af9199af9e69b889claireho // offset isn't offset but instead is a single data element 114427f654740f2a26ad62a5c155af9199af9e69b889claireho if (returnCapacity >= 1) { 1145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho returnReorderCodes[0] = leadByteIndex & ~0x8000; 114627f654740f2a26ad62a5c155af9199af9e69b889claireho return 1; 114727f654740f2a26ad62a5c155af9199af9e69b889claireho } 114827f654740f2a26ad62a5c155af9199af9e69b889claireho return 0; 114927f654740f2a26ad62a5c155af9199af9e69b889claireho } 1150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho //uint16_t* dataOffsetBase = leadByteTable + (2 + leadByteIndexLength); 1151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t* reorderCodeData = leadByteTable + (2 + leadByteIndexLength) + leadByteIndex; 1152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t reorderCodeCount = *reorderCodeData > returnCapacity ? returnCapacity : *reorderCodeData; 1153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(returnReorderCodes, reorderCodeData + 1, reorderCodeCount * sizeof(uint16_t)); 115427f654740f2a26ad62a5c155af9199af9e69b889claireho return reorderCodeCount; 115527f654740f2a26ad62a5c155af9199af9e69b889claireho} 115627f654740f2a26ad62a5c155af9199af9e69b889claireho 115727f654740f2a26ad62a5c155af9199af9e69b889claireho// used to mark ignorable reorder code slots 115827f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const int32_t UCOL_REORDER_CODE_IGNORE = UCOL_REORDER_CODE_LIMIT + 1; 115927f654740f2a26ad62a5c155af9199af9e69b889claireho 1160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CFUNC void U_EXPORT2 1161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoucol_buildPermutationTable(UCollator *coll, UErrorCode *status) { 116227f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t leadBytesSize = 256; 116327f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t leadBytes[256]; 116427f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t internalReorderCodesLength = coll->reorderCodesLength + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST); 116527f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t* internalReorderCodes; 116627f654740f2a26ad62a5c155af9199af9e69b889claireho 116727f654740f2a26ad62a5c155af9199af9e69b889claireho // The lowest byte that hasn't been assigned a mapping 116827f654740f2a26ad62a5c155af9199af9e69b889claireho int toBottom = 0x03; 116927f654740f2a26ad62a5c155af9199af9e69b889claireho // The highest byte that hasn't been assigned a mapping - don't include the special or trailing 117027f654740f2a26ad62a5c155af9199af9e69b889claireho int toTop = 0xe4; 117127f654740f2a26ad62a5c155af9199af9e69b889claireho 117227f654740f2a26ad62a5c155af9199af9e69b889claireho // are we filling from the bottom? 117327f654740f2a26ad62a5c155af9199af9e69b889claireho bool fromTheBottom = true; 1174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t reorderCodesIndex = -1; 117527f654740f2a26ad62a5c155af9199af9e69b889claireho 117627f654740f2a26ad62a5c155af9199af9e69b889claireho // lead bytes that have alread been assigned to the permutation table 117727f654740f2a26ad62a5c155af9199af9e69b889claireho bool newLeadByteUsed[256]; 117827f654740f2a26ad62a5c155af9199af9e69b889claireho // permutation table slots that have already been filled 117927f654740f2a26ad62a5c155af9199af9e69b889claireho bool permutationSlotFilled[256]; 118027f654740f2a26ad62a5c155af9199af9e69b889claireho 118127f654740f2a26ad62a5c155af9199af9e69b889claireho // nothing to do 1182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(U_FAILURE(*status) || coll == NULL) { 1183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // clear the reordering 1187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->reorderCodes == NULL || coll->reorderCodesLength == 0 1188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho || (coll->reorderCodesLength == 1 && coll->reorderCodes[0] == UCOL_REORDER_CODE_NONE)) { 1189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->leadBytePermutationTable != NULL) { 1190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->freeLeadBytePermutationTableOnClose) { 119127f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(coll->leadBytePermutationTable); 119227f654740f2a26ad62a5c155af9199af9e69b889claireho } 1193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->leadBytePermutationTable = NULL; 119427f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodesLength = 0; 119527f654740f2a26ad62a5c155af9199af9e69b889claireho } 119627f654740f2a26ad62a5c155af9199af9e69b889claireho return; 119727f654740f2a26ad62a5c155af9199af9e69b889claireho } 119827f654740f2a26ad62a5c155af9199af9e69b889claireho 1199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // set reordering to the default reordering 1200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->reorderCodes[0] == UCOL_REORDER_CODE_DEFAULT) { 1201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->reorderCodesLength != 1) { 1202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = U_ILLEGAL_ARGUMENT_ERROR; 1203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->freeReorderCodesOnClose == TRUE) { 1206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(coll->reorderCodes); 1207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->reorderCodes = NULL; 1209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) { 1211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_free(coll->leadBytePermutationTable); 1212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->leadBytePermutationTable = NULL; 1214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->defaultReorderCodesLength == 0) { 1216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->reorderCodes = (int32_t*)uprv_malloc(coll->defaultReorderCodesLength * sizeof(int32_t)); 1220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->freeReorderCodesOnClose = TRUE; 1221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->reorderCodes == NULL) { 1222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho *status = U_MEMORY_ALLOCATION_ERROR; 1223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->reorderCodesLength = coll->defaultReorderCodesLength; 1226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(coll->defaultReorderCodes, coll->reorderCodes, coll->reorderCodesLength * sizeof(int32_t)); 1227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 122927f654740f2a26ad62a5c155af9199af9e69b889claireho if (coll->leadBytePermutationTable == NULL) { 123027f654740f2a26ad62a5c155af9199af9e69b889claireho coll->leadBytePermutationTable = (uint8_t*)uprv_malloc(256*sizeof(uint8_t)); 1231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->freeLeadBytePermutationTableOnClose = TRUE; 123227f654740f2a26ad62a5c155af9199af9e69b889claireho if (coll->leadBytePermutationTable == NULL) { 123327f654740f2a26ad62a5c155af9199af9e69b889claireho *status = U_MEMORY_ALLOCATION_ERROR; 123427f654740f2a26ad62a5c155af9199af9e69b889claireho return; 123527f654740f2a26ad62a5c155af9199af9e69b889claireho } 123627f654740f2a26ad62a5c155af9199af9e69b889claireho } 123727f654740f2a26ad62a5c155af9199af9e69b889claireho 123827f654740f2a26ad62a5c155af9199af9e69b889claireho // prefill the reordering codes with the leading entries 123927f654740f2a26ad62a5c155af9199af9e69b889claireho internalReorderCodes = (int32_t*)uprv_malloc(internalReorderCodesLength * sizeof(int32_t)); 124027f654740f2a26ad62a5c155af9199af9e69b889claireho if (internalReorderCodes == NULL) { 124127f654740f2a26ad62a5c155af9199af9e69b889claireho *status = U_MEMORY_ALLOCATION_ERROR; 1242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) { 124327f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(coll->leadBytePermutationTable); 124427f654740f2a26ad62a5c155af9199af9e69b889claireho } 1245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->leadBytePermutationTable = NULL; 124627f654740f2a26ad62a5c155af9199af9e69b889claireho return; 124727f654740f2a26ad62a5c155af9199af9e69b889claireho } 124827f654740f2a26ad62a5c155af9199af9e69b889claireho 124927f654740f2a26ad62a5c155af9199af9e69b889claireho for (uint32_t codeIndex = 0; codeIndex < (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST); codeIndex++) { 125027f654740f2a26ad62a5c155af9199af9e69b889claireho internalReorderCodes[codeIndex] = UCOL_REORDER_CODE_FIRST + codeIndex; 125127f654740f2a26ad62a5c155af9199af9e69b889claireho } 125227f654740f2a26ad62a5c155af9199af9e69b889claireho for (int32_t codeIndex = 0; codeIndex < coll->reorderCodesLength; codeIndex++) { 125327f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t reorderCodesCode = coll->reorderCodes[codeIndex]; 125427f654740f2a26ad62a5c155af9199af9e69b889claireho internalReorderCodes[codeIndex + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST)] = reorderCodesCode; 125527f654740f2a26ad62a5c155af9199af9e69b889claireho if (reorderCodesCode >= UCOL_REORDER_CODE_FIRST && reorderCodesCode < UCOL_REORDER_CODE_LIMIT) { 125627f654740f2a26ad62a5c155af9199af9e69b889claireho internalReorderCodes[reorderCodesCode - UCOL_REORDER_CODE_FIRST] = UCOL_REORDER_CODE_IGNORE; 125727f654740f2a26ad62a5c155af9199af9e69b889claireho } 125827f654740f2a26ad62a5c155af9199af9e69b889claireho } 125927f654740f2a26ad62a5c155af9199af9e69b889claireho 126027f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < 256; i++) { 126127f654740f2a26ad62a5c155af9199af9e69b889claireho if (i < toBottom || i > toTop) { 126227f654740f2a26ad62a5c155af9199af9e69b889claireho permutationSlotFilled[i] = true; 126327f654740f2a26ad62a5c155af9199af9e69b889claireho newLeadByteUsed[i] = true; 126427f654740f2a26ad62a5c155af9199af9e69b889claireho coll->leadBytePermutationTable[i] = i; 126527f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 126627f654740f2a26ad62a5c155af9199af9e69b889claireho permutationSlotFilled[i] = false; 126727f654740f2a26ad62a5c155af9199af9e69b889claireho newLeadByteUsed[i] = false; 126827f654740f2a26ad62a5c155af9199af9e69b889claireho coll->leadBytePermutationTable[i] = 0; 126927f654740f2a26ad62a5c155af9199af9e69b889claireho } 127027f654740f2a26ad62a5c155af9199af9e69b889claireho } 127127f654740f2a26ad62a5c155af9199af9e69b889claireho 127227f654740f2a26ad62a5c155af9199af9e69b889claireho /* Start from the front of the list and place each script we encounter at the 127327f654740f2a26ad62a5c155af9199af9e69b889claireho * earliest possible locatation in the permutation table. If we encounter 127427f654740f2a26ad62a5c155af9199af9e69b889claireho * UNKNOWN, start processing from the back, and place each script in the last 127527f654740f2a26ad62a5c155af9199af9e69b889claireho * possible location. At each step, we also need to make sure that any scripts 127627f654740f2a26ad62a5c155af9199af9e69b889claireho * that need to not be moved are copied to their same location in the final table. 127727f654740f2a26ad62a5c155af9199af9e69b889claireho */ 1278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int reorderCodesCount = 0; reorderCodesCount < internalReorderCodesLength; reorderCodesCount++) { 1279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho reorderCodesIndex += fromTheBottom ? 1 : -1; 128027f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t next = internalReorderCodes[reorderCodesIndex]; 128127f654740f2a26ad62a5c155af9199af9e69b889claireho if (next == UCOL_REORDER_CODE_IGNORE) { 128227f654740f2a26ad62a5c155af9199af9e69b889claireho continue; 128327f654740f2a26ad62a5c155af9199af9e69b889claireho } 128427f654740f2a26ad62a5c155af9199af9e69b889claireho if (next == USCRIPT_UNKNOWN) { 128527f654740f2a26ad62a5c155af9199af9e69b889claireho if (fromTheBottom == false) { 128627f654740f2a26ad62a5c155af9199af9e69b889claireho // double turnaround 128727f654740f2a26ad62a5c155af9199af9e69b889claireho *status = U_ILLEGAL_ARGUMENT_ERROR; 1288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) { 128927f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(coll->leadBytePermutationTable); 129027f654740f2a26ad62a5c155af9199af9e69b889claireho } 1291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->leadBytePermutationTable = NULL; 129227f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodesLength = 0; 129327f654740f2a26ad62a5c155af9199af9e69b889claireho if (internalReorderCodes != NULL) { 129427f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(internalReorderCodes); 129527f654740f2a26ad62a5c155af9199af9e69b889claireho } 129627f654740f2a26ad62a5c155af9199af9e69b889claireho return; 129727f654740f2a26ad62a5c155af9199af9e69b889claireho } 129827f654740f2a26ad62a5c155af9199af9e69b889claireho fromTheBottom = false; 1299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho reorderCodesIndex = internalReorderCodesLength; 130027f654740f2a26ad62a5c155af9199af9e69b889claireho continue; 130127f654740f2a26ad62a5c155af9199af9e69b889claireho } 130227f654740f2a26ad62a5c155af9199af9e69b889claireho 1303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uint16_t leadByteCount = ucol_getLeadBytesForReorderCode(coll->UCA, next, leadBytes, leadBytesSize); 130427f654740f2a26ad62a5c155af9199af9e69b889claireho if (fromTheBottom) { 130527f654740f2a26ad62a5c155af9199af9e69b889claireho for (int leadByteIndex = 0; leadByteIndex < leadByteCount; leadByteIndex++) { 130627f654740f2a26ad62a5c155af9199af9e69b889claireho // don't place a lead byte twice in the permutation table 130727f654740f2a26ad62a5c155af9199af9e69b889claireho if (permutationSlotFilled[leadBytes[leadByteIndex]]) { 130827f654740f2a26ad62a5c155af9199af9e69b889claireho // lead byte already used 130927f654740f2a26ad62a5c155af9199af9e69b889claireho *status = U_ILLEGAL_ARGUMENT_ERROR; 1310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) { 131127f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(coll->leadBytePermutationTable); 131227f654740f2a26ad62a5c155af9199af9e69b889claireho } 1313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->leadBytePermutationTable = NULL; 131427f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodesLength = 0; 131527f654740f2a26ad62a5c155af9199af9e69b889claireho if (internalReorderCodes != NULL) { 131627f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(internalReorderCodes); 131727f654740f2a26ad62a5c155af9199af9e69b889claireho } 131827f654740f2a26ad62a5c155af9199af9e69b889claireho return; 131927f654740f2a26ad62a5c155af9199af9e69b889claireho } 132027f654740f2a26ad62a5c155af9199af9e69b889claireho 132127f654740f2a26ad62a5c155af9199af9e69b889claireho coll->leadBytePermutationTable[leadBytes[leadByteIndex]] = toBottom; 132227f654740f2a26ad62a5c155af9199af9e69b889claireho newLeadByteUsed[toBottom] = true; 132327f654740f2a26ad62a5c155af9199af9e69b889claireho permutationSlotFilled[leadBytes[leadByteIndex]] = true; 132427f654740f2a26ad62a5c155af9199af9e69b889claireho toBottom++; 132527f654740f2a26ad62a5c155af9199af9e69b889claireho } 132627f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 132727f654740f2a26ad62a5c155af9199af9e69b889claireho for (int leadByteIndex = leadByteCount - 1; leadByteIndex >= 0; leadByteIndex--) { 132827f654740f2a26ad62a5c155af9199af9e69b889claireho // don't place a lead byte twice in the permutation table 132927f654740f2a26ad62a5c155af9199af9e69b889claireho if (permutationSlotFilled[leadBytes[leadByteIndex]]) { 133027f654740f2a26ad62a5c155af9199af9e69b889claireho // lead byte already used 133127f654740f2a26ad62a5c155af9199af9e69b889claireho *status = U_ILLEGAL_ARGUMENT_ERROR; 1332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) { 133327f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(coll->leadBytePermutationTable); 133427f654740f2a26ad62a5c155af9199af9e69b889claireho } 1335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho coll->leadBytePermutationTable = NULL; 133627f654740f2a26ad62a5c155af9199af9e69b889claireho coll->reorderCodesLength = 0; 133727f654740f2a26ad62a5c155af9199af9e69b889claireho if (internalReorderCodes != NULL) { 133827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(internalReorderCodes); 133927f654740f2a26ad62a5c155af9199af9e69b889claireho } 134027f654740f2a26ad62a5c155af9199af9e69b889claireho return; 134127f654740f2a26ad62a5c155af9199af9e69b889claireho } 134227f654740f2a26ad62a5c155af9199af9e69b889claireho 134327f654740f2a26ad62a5c155af9199af9e69b889claireho coll->leadBytePermutationTable[leadBytes[leadByteIndex]] = toTop; 134427f654740f2a26ad62a5c155af9199af9e69b889claireho newLeadByteUsed[toTop] = true; 134527f654740f2a26ad62a5c155af9199af9e69b889claireho permutationSlotFilled[leadBytes[leadByteIndex]] = true; 134627f654740f2a26ad62a5c155af9199af9e69b889claireho toTop--; 134727f654740f2a26ad62a5c155af9199af9e69b889claireho } 134827f654740f2a26ad62a5c155af9199af9e69b889claireho } 134927f654740f2a26ad62a5c155af9199af9e69b889claireho } 135027f654740f2a26ad62a5c155af9199af9e69b889claireho 135127f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef REORDER_DEBUG 135227f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\n@@@@ Partial Script Reordering Table\n"); 135327f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < 256; i++) { 135427f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\t%02x = %02x\n", i, coll->leadBytePermutationTable[i]); 135527f654740f2a26ad62a5c155af9199af9e69b889claireho } 135627f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\n@@@@ Lead Byte Used Table\n"); 135727f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < 256; i++) { 135827f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\t%02x = %02x\n", i, newLeadByteUsed[i]); 135927f654740f2a26ad62a5c155af9199af9e69b889claireho } 136027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\n@@@@ Permutation Slot Filled Table\n"); 136127f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < 256; i++) { 136227f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\t%02x = %02x\n", i, permutationSlotFilled[i]); 136327f654740f2a26ad62a5c155af9199af9e69b889claireho } 136427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 136527f654740f2a26ad62a5c155af9199af9e69b889claireho 136627f654740f2a26ad62a5c155af9199af9e69b889claireho /* Copy everything that's left over */ 136727f654740f2a26ad62a5c155af9199af9e69b889claireho int reorderCode = 0; 136827f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < 256; i++) { 136927f654740f2a26ad62a5c155af9199af9e69b889claireho if (!permutationSlotFilled[i]) { 137027f654740f2a26ad62a5c155af9199af9e69b889claireho while (reorderCode < 256 && newLeadByteUsed[reorderCode]) { 137127f654740f2a26ad62a5c155af9199af9e69b889claireho reorderCode++; 137227f654740f2a26ad62a5c155af9199af9e69b889claireho } 137327f654740f2a26ad62a5c155af9199af9e69b889claireho coll->leadBytePermutationTable[i] = reorderCode; 137427f654740f2a26ad62a5c155af9199af9e69b889claireho permutationSlotFilled[i] = true; 137527f654740f2a26ad62a5c155af9199af9e69b889claireho newLeadByteUsed[reorderCode] = true; 137627f654740f2a26ad62a5c155af9199af9e69b889claireho } 137727f654740f2a26ad62a5c155af9199af9e69b889claireho } 137827f654740f2a26ad62a5c155af9199af9e69b889claireho 137927f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef REORDER_DEBUG 138027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\n@@@@ Script Reordering Table\n"); 138127f654740f2a26ad62a5c155af9199af9e69b889claireho for (int i = 0; i < 256; i++) { 138227f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stdout, "\t%02x = %02x\n", i, coll->leadBytePermutationTable[i]); 138327f654740f2a26ad62a5c155af9199af9e69b889claireho } 138427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 138527f654740f2a26ad62a5c155af9199af9e69b889claireho 138627f654740f2a26ad62a5c155af9199af9e69b889claireho if (internalReorderCodes != NULL) { 138727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(internalReorderCodes); 138827f654740f2a26ad62a5c155af9199af9e69b889claireho } 138927f654740f2a26ad62a5c155af9199af9e69b889claireho 139027f654740f2a26ad62a5c155af9199af9e69b889claireho // force a regen of the latin one table since it is affected by the script reordering 139127f654740f2a26ad62a5c155af9199af9e69b889claireho coll->latinOneRegenTable = TRUE; 139227f654740f2a26ad62a5c155af9199af9e69b889claireho ucol_updateInternalState(coll, status); 139327f654740f2a26ad62a5c155af9199af9e69b889claireho} 139427f654740f2a26ad62a5c155af9199af9e69b889claireho 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */ 1396