1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 1996-2010, International Business Machines 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: ucol_res.cpp 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* encoding: US-ASCII 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* tab size: 8 (not used) 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* indentation:4 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Description: 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* This file contains dependencies that the collation run-time doesn't normally 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* need. This mainly contains resource bundle usage and collation meta information 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification history 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Date Name Comments 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 1996-1999 various members of ICU team maintained C API for collation framework 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 02/16/2001 synwee Added internal method getPrevSpecialCE 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 03/01/2001 synwee Added maxexpansion functionality. 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 03/16/2001 weiv Collation framework is rewritten in C and made UCA compliant 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 12/08/2004 grhoten Split part of ucol.cpp into ucol_res.cpp 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_COLLATION 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uloc.h" 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/coll.h" 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/tblcoll.h" 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/caniter.h" 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uscript.h" 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucol_bld.h" 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucol_imp.h" 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucol_tok.h" 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucol_elm.h" 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uresimp.h" 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_imp.h" 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h" 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucln_in.h" 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustrenum.h" 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h" 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "utracimp.h" 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uenumimp.h" 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ulist.h" 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_USE 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UErrorCode *status); 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// static UCA. There is only one. Collators don't use it. 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// It is referenced only in ucol_initUCA and ucol_cleanup 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UCollator* _staticUCA = NULL; 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// static pointer to udata memory. Inited in ucol_initUCA 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// used for cleanup in ucol_cleanup 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UDataMemory* UCA_DATA_MEM = NULL; 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool U_CALLCONV 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_res_cleanup(void) 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (UCA_DATA_MEM) { 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_close(UCA_DATA_MEM); 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCA_DATA_MEM = NULL; 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (_staticUCA) { 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_close(_staticUCA); 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _staticUCA = NULL; 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool U_CALLCONV 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)isAcceptableUCA(void * /*context*/, 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char * /*type*/, const char * /*name*/, 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UDataInfo *pInfo){ 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* context, type & name are intentionally not used */ 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if( pInfo->size>=20 && 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->isBigEndian==U_IS_BIG_ENDIAN && 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->charsetFamily==U_CHARSET_FAMILY && 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->dataFormat[0]==UCA_DATA_FORMAT_0 && /* dataFormat="UCol" */ 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->dataFormat[1]==UCA_DATA_FORMAT_1 && 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->dataFormat[2]==UCA_DATA_FORMAT_2 && 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->dataFormat[3]==UCA_DATA_FORMAT_3 && 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->formatVersion[0]==UCA_FORMAT_VERSION_0 && 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pInfo->formatVersion[1]>=UCA_FORMAT_VERSION_1// && 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //pInfo->formatVersion[1]==UCA_FORMAT_VERSION_1 && 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //pInfo->formatVersion[2]==UCA_FORMAT_VERSION_2 && // Too harsh 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //pInfo->formatVersion[3]==UCA_FORMAT_VERSION_3 && // Too harsh 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ) { 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UVersionInfo UCDVersion; 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_getUnicodeVersion(UCDVersion); 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (UBool)(pInfo->dataVersion[0]==UCDVersion[0] 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) && pInfo->dataVersion[1]==UCDVersion[1]); 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //&& pInfo->dataVersion[2]==ucaDataInfo.dataVersion[2] 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) //&& pInfo->dataVersion[3]==ucaDataInfo.dataVersion[3]); 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_END 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* do not close UCA returned by ucol_initUCA! */ 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UCollator * 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_initUCA(UErrorCode *status) { 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) { 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool needsInit; 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UMTX_CHECK(NULL, (_staticUCA == NULL), needsInit); 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(needsInit) { 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDataMemory *result = udata_openChoice(U_ICUDATA_COLL, UCA_DATA_TYPE, UCA_DATA_NAME, isAcceptableUCA, NULL, status); 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*status)){ 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollator *newUCA = ucol_initCollator((const UCATableHeader *)udata_getMemory(result), NULL, NULL, status); 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*status)){ 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Initalize variables for implicit generation 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_uca_initImplicitConstants(status); 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(NULL); 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(_staticUCA == NULL) { 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCA_DATA_MEM = result; 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _staticUCA = newUCA; 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newUCA = NULL; 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = NULL; 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(NULL); 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucln_i18n_registerCleanup(UCLN_I18N_UCOL_RES, ucol_res_cleanup); 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(newUCA != NULL) { 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_close(newUCA); 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_close(result); 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) }else{ 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_close(newUCA); 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_close(result); 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) udata_close(result); 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return _staticUCA; 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI void U_EXPORT2 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_forgetUCA(void) 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) _staticUCA = NULL; 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCA_DATA_MEM = NULL; 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/****************************************************************************/ 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Following are the open/close functions */ 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* */ 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/****************************************************************************/ 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UCollator* 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)tryOpeningFromRules(UResourceBundle *collElem, UErrorCode *status) { 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rulesLen = 0; 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *rules = ures_getStringByKey(collElem, "Sequence", &rulesLen, status); 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ucol_openRules(rules, rulesLen, UCOL_DEFAULT, UCOL_DEFAULT, NULL, status); 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// API in ucol_imp.h 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC UCollator* 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_open_internal(const char *loc, 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode intStatus = U_ZERO_ERROR; 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UCollator* UCA = ucol_initUCA(status); 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* New version */ 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) return 0; 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollator *result = NULL; 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *b = ures_open(U_ICUDATA_COLL, loc, status); 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* we try to find stuff from keyword */ 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status); 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *collElem = NULL; 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char keyBuffer[256]; 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // if there is a keyword, we pick it up and try to get elements 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!uloc_getKeywordValue(loc, "collation", keyBuffer, 256, status) || 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) !uprv_strcmp(keyBuffer,"default")) { /* Treat 'zz@collation=default' as 'zz'. */ 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // no keyword. we try to find the default setting, which will give us the keyword value 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intStatus = U_ZERO_ERROR; 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // finding default value does not affect collation fallback status 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, &intStatus); 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(intStatus)) { 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t defaultKeyLen = 0; 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, &intStatus); 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen); 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) keyBuffer[defaultKeyLen] = 0; 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_INTERNAL_PROGRAM_ERROR; 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(defaultColl); 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) collElem = ures_getByKeyWithFallback(collations, keyBuffer, collations, status); 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) collations = NULL; // We just reused the collations object as collElem. 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *binary = NULL; 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle *reorderRes = NULL; 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_MISSING_RESOURCE_ERROR) { /* We didn't find the tailoring data, we fallback to the UCA */ 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_USING_DEFAULT_WARNING; 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ucol_initCollator(UCA->image, result, UCA, status); 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // if we use UCA, real locale is root 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(b); 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b = ures_open(U_ICUDATA_COLL, "", status); 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(collElem); 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) collElem = ures_open(U_ICUDATA_COLL, "", status); 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) { 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->hasRealData = FALSE; 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_SUCCESS(*status)) { 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intStatus = U_ZERO_ERROR; 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) binary = ures_getByKey(collElem, "%%CollationBin", NULL, &intStatus); 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(intStatus == U_MISSING_RESOURCE_ERROR) { /* we didn't find the binary image, we should use the rules */ 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) binary = NULL; 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = tryOpeningFromRules(collElem, status); 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) { 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(U_SUCCESS(intStatus)) { /* otherwise, we'll pick a collation data that exists */ 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = 0; 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const uint8_t *inData = ures_getBinary(binary, &len, status); 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) { 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCATableHeader *colData = (UCATableHeader *)inData; 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(uprv_memcmp(colData->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)) != 0 || 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcmp(colData->UCDVersion, UCA->image->UCDVersion, sizeof(UVersionInfo)) != 0 || 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) colData->version[0] != UCOL_BUILDER_VERSION) 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_DIFFERENT_UCA_VERSION; 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = tryOpeningFromRules(collElem, status); 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((uint32_t)len > (paddedsize(sizeof(UCATableHeader)) + paddedsize(sizeof(UColOptionSet)))) { 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ucol_initCollator((const UCATableHeader *)inData, result, UCA, status); 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->hasRealData = TRUE; 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ucol_initCollator(UCA->image, result, UCA, status); 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_setOptionsFromHeader(result, (UColOptionSet *)(inData+((const UCATableHeader *)inData)->options), status); 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->hasRealData = FALSE; 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->freeImageOnClose = FALSE; 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reorderRes = ures_getByKey(collElem, "%%ReorderCodes", NULL, &intStatus); 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(intStatus)) { 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t reorderCodesLen = 0; 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const int32_t* reorderCodes = ures_getIntVector(reorderRes, &reorderCodesLen, status); 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_setReorderCodes(result, reorderCodes, reorderCodesLen, status); 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { // !U_SUCCESS(binaryStatus) 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*status)) { 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = intStatus; // propagate underlying error 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intStatus = U_ZERO_ERROR; 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->rules = ures_getStringByKey(collElem, "Sequence", &result->rulesLength, &intStatus); 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->freeRulesOnClose = FALSE; 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { /* There is another error, and we're just gonna clean up */ 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) intStatus = U_ZERO_ERROR; 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->ucaRules = ures_getStringByKey(b,"UCARules",NULL,&intStatus); 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(loc == NULL) { 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) loc = ures_getLocaleByType(b, ULOC_ACTUAL_LOCALE, status); 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->requestedLocale = uprv_strdup(loc); 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* test for NULL */ 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result->requestedLocale == NULL) { 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) loc = ures_getLocaleByType(collElem, ULOC_ACTUAL_LOCALE, status); 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->actualLocale = uprv_strdup(loc); 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* test for NULL */ 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result->actualLocale == NULL) { 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) loc = ures_getLocaleByType(b, ULOC_ACTUAL_LOCALE, status); 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->validLocale = uprv_strdup(loc); 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* test for NULL */ 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result->validLocale == NULL) { 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto clean; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(b); 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(collElem); 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(binary); 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(reorderRes); 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)clean: 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(b); 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(collElem); 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(binary); 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(reorderRes); 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_close(result); 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UCollator* 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_open(const char *loc, 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_NAMESPACE_USE 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN); 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_DATA1(UTRACE_INFO, "locale = \"%s\"", loc); 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollator *result = NULL; 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_SERVICE 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = Collator::createUCollator(loc, status); 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (result == NULL) 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ucol_open_internal(loc, status); 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_EXIT_PTR_STATUS(result, *status); 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UCollator* 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_openRulesForImport( const UChar *rules, 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rulesLength, 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColAttributeValue normalizationMode, 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollationStrength strength, 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError *parseError, 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) GetCollationRulesFunction importFunc, 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) void* context, 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColTokenParser src; 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColAttributeValue norm; 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError tErr; 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)){ 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(rules == NULL || rulesLength < -1) { 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(rulesLength == -1) { 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesLength = u_strlen(rules); 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(parseError == NULL){ 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parseError = &tErr; 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(normalizationMode) { 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case UCOL_OFF: 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case UCOL_ON: 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case UCOL_DEFAULT: 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) norm = normalizationMode; 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollator *result = NULL; 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCATableHeader *table = NULL; 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollator *UCA = ucol_initUCA(status); 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)){ 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_initTokenList(&src, rules, rulesLength, UCA, importFunc, context, status); 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_assembleTokenList(&src,parseError, status); 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) { 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if status is U_ILLEGAL_ARGUMENT_ERROR, src->current points at the offending option */ 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if status is U_INVALID_FORMAT_ERROR, src->current points after the problematic part of the rules */ 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* so something might be done here... or on lower level */ 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef UCOL_DEBUG 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(*status == U_ILLEGAL_ARGUMENT_ERROR) { 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "bad option starting at offset %i\n", (int)(src.current-src.source)); 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "invalid rule just before offset %i\n", (int)(src.current-src.source)); 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src.resultLen > 0 || src.removeSet != NULL) { /* we have a set of rules, let's make something of it */ 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* also, if we wanted to remove some contractions, we should make a tailoring */ 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) table = ucol_assembleTailoringTable(&src, status); 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*status)) { 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // builder version 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) table->version[0] = UCOL_BUILDER_VERSION; 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // no tailoring information on this level 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) table->version[1] = table->version[2] = table->version[3] = 0; 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set UCD version 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_getUnicodeVersion(table->UCDVersion); 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // set UCA version 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(table->UCAVersion, UCA->image->UCAVersion, sizeof(UVersionInfo)); 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ucol_initCollator(table, 0, UCA, status); 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->hasRealData = TRUE; 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->freeImageOnClose = TRUE; 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { /* no rules, but no error either */ 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // must be only options 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We will init the collator from UCA 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = ucol_initCollator(UCA->image, 0, UCA, status); 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Check for null result 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // And set only the options 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColOptionSet *opts = (UColOptionSet *)uprv_malloc(sizeof(UColOptionSet)); 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* test for NULL */ 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (opts == NULL) { 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(opts, src.opts, sizeof(UColOptionSet)); 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_setOptionsFromHeader(result, opts, status); 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_setReorderCodesFromParser(result, &src, status); 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->freeOptionsOnClose = TRUE; 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->hasRealData = FALSE; 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->freeImageOnClose = FALSE; 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*status)) { 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *newRules; 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->dataVersion[0] = UCOL_BUILDER_VERSION; 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(rulesLength > 0) { 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newRules = (UChar *)uprv_malloc((rulesLength+1)*U_SIZEOF_UCHAR); 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* test for NULL */ 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (newRules == NULL) { 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto cleanup; 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(newRules, rules, rulesLength*U_SIZEOF_UCHAR); 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newRules[rulesLength]=0; 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->rules = newRules; 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->rulesLength = rulesLength; 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->freeRulesOnClose = TRUE; 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->ucaRules = NULL; 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->actualLocale = NULL; 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->validLocale = NULL; 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result->requestedLocale = NULL; 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_buildPermutationTable(result, status); 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_setAttribute(result, UCOL_STRENGTH, strength, status); 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_setAttribute(result, UCOL_NORMALIZATION_MODE, norm, status); 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)cleanup: 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(result != NULL) { 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_close(result); 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(table != NULL) { 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(table); 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = NULL; 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_closeTokenList(&src); 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UCollator* U_EXPORT2 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_openRules( const UChar *rules, 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rulesLength, 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColAttributeValue normalizationMode, 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCollationStrength strength, 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError *parseError, 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ucol_openRulesForImport(rules, 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) rulesLength, 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) normalizationMode, 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) strength, 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) parseError, 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_getRulesFromBundle, 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status); 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getRulesEx(const UCollator *coll, UColRuleOption delta, UChar *buffer, int32_t bufferLen) { 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t len = 0; 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t UCAlen = 0; 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar* ucaRules = 0; 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *rules = ucol_getRules(coll, &len); 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(delta == UCOL_FULL_RULES) { 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* take the UCA rules and append real rules at the end */ 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* UCA rules will be probably coming from the root RB */ 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucaRules = coll->ucaRules; 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (ucaRules) { 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UCAlen = u_strlen(ucaRules); 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucaRules = ures_getStringByKey(coll->rb,"UCARules",&UCAlen,&status); 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle* cresb = ures_getByKeyWithFallback(coll->rb, "collations", NULL, &status); 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle* uca = ures_getByKeyWithFallback(cresb, "UCA", NULL, &status); 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucaRules = ures_getStringByKey(uca,"Sequence",&UCAlen,&status); 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(uca); 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(cresb); 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(status)) { 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(buffer!=0 && bufferLen>0){ 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *buffer=0; 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UCAlen > 0) { 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_memcpy(buffer, ucaRules, uprv_min(UCAlen, bufferLen)); 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(len > 0 && bufferLen > UCAlen) { 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_memcpy(buffer+UCAlen, rules, uprv_min(len, bufferLen-UCAlen)); 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(buffer, bufferLen, len+UCAlen, &status); 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UChar _NUL = 0; 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI const UChar* U_EXPORT2 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getRules( const UCollator *coll, 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t *length) 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(coll->rules != NULL) { 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *length = coll->rulesLength; 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return coll->rules; 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *length = 0; 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return &_NUL; 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UBool U_EXPORT2 583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_equals(const UCollator *source, const UCollator *target) { 584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // if pointers are equal, collators are equal 586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source == target) { 587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t i = 0, j = 0; 590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // if any of attributes are different, collators are not equal 591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) { 592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(ucol_getAttribute(source, (UColAttribute)i, &status) != ucol_getAttribute(target, (UColAttribute)i, &status) || U_FAILURE(status)) { 593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (source->reorderCodesLength != target->reorderCodesLength){ 597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (i = 0; i < source->reorderCodesLength; i++) { 600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(source->reorderCodes[i] != target->reorderCodes[i]) { 601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t sourceRulesLen = 0, targetRulesLen = 0; 606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *sourceRules = ucol_getRules(source, &sourceRulesLen); 607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *targetRules = ucol_getRules(target, &targetRulesLen); 608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceRulesLen == targetRulesLen && u_strncmp(sourceRules, targetRules, sourceRulesLen) == 0) { 610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // all the attributes are equal and the rules are equal - collators are equal 611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return(TRUE); 612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // hard part, need to construct tree from rules and see if they yield the same tailoring 614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool result = TRUE; 615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError parseError; 616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColTokenParser sourceParser, targetParser; 617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t sourceListLen = 0, targetListLen = 0; 618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_initTokenList(&sourceParser, sourceRules, sourceRulesLen, source->UCA, ucol_tok_getRulesFromBundle, NULL, &status); 619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_initTokenList(&targetParser, targetRules, targetRulesLen, target->UCA, ucol_tok_getRulesFromBundle, NULL, &status); 620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceListLen = ucol_tok_assembleTokenList(&sourceParser, &parseError, &status); 621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetListLen = ucol_tok_assembleTokenList(&targetParser, &parseError, &status); 622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceListLen != targetListLen) { 624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // different number of resets 625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColToken *sourceReset = NULL, *targetReset = NULL; 628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *sourceResetString = NULL, *targetResetString = NULL; 629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t sourceStringLen = 0, targetStringLen = 0; 630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(i = 0; i < sourceListLen; i++) { 631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceReset = sourceParser.lh[i].reset; 632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceResetString = sourceParser.source+(sourceReset->source & 0xFFFFFF); 633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceStringLen = sourceReset->source >> 24; 634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(j = 0; j < sourceListLen; j++) { 635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetReset = targetParser.lh[j].reset; 636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetResetString = targetParser.source+(targetReset->source & 0xFFFFFF); 637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetStringLen = targetReset->source >> 24; 638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceStringLen == targetStringLen && (u_strncmp(sourceResetString, targetResetString, sourceStringLen) == 0)) { 639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceReset = sourceParser.lh[i].first; 640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetReset = targetParser.lh[j].first; 641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(sourceReset != NULL && targetReset != NULL) { 642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceResetString = sourceParser.source+(sourceReset->source & 0xFFFFFF); 643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceStringLen = sourceReset->source >> 24; 644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetResetString = targetParser.source+(targetReset->source & 0xFFFFFF); 645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetStringLen = targetReset->source >> 24; 646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceStringLen != targetStringLen || (u_strncmp(sourceResetString, targetResetString, sourceStringLen) != 0)) { 647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto returnResult; 649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // probably also need to check the expansions 651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceReset->expansion) { 652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!targetReset->expansion) { 653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto returnResult; 655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // compare expansions 657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceResetString = sourceParser.source+(sourceReset->expansion& 0xFFFFFF); 658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceStringLen = sourceReset->expansion >> 24; 659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetResetString = targetParser.source+(targetReset->expansion & 0xFFFFFF); 660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetStringLen = targetReset->expansion >> 24; 661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceStringLen != targetStringLen || (u_strncmp(sourceResetString, targetResetString, sourceStringLen) != 0)) { 662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto returnResult; 664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(targetReset->expansion) { 668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto returnResult; 670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) sourceReset = sourceReset->next; 673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) targetReset = targetReset->next; 674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(sourceReset != targetReset) { // at least one is not NULL 676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // there are more tailored elements in one list 677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto returnResult; 679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // couldn't find the reset anchor, so the collators are not equal 686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(j == sourceListLen) { 687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = FALSE; 688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto returnResult; 689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)returnResult: 694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_closeTokenList(&sourceParser); 695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_closeTokenList(&targetParser); 696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getDisplayName( const char *objLoc, 702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *dispLoc, 703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *result, 704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t resultLength, 705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *status) 706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_NAMESPACE_USE 708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status)) return -1; 710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString dst; 711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!(result==NULL && resultLength==0)) { 712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // NULL destination for pure preflighting: empty dummy string 713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // otherwise, alias the destination buffer 714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dst.setTo(result, 0, resultLength); 715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Collator::getDisplayName(Locale(objLoc), Locale(dispLoc), dst); 717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return dst.extract(result, resultLength, *status); 718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI const char* U_EXPORT2 721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getAvailable(int32_t index) 722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t count = 0; 724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const Locale *loc = Collator::getAvailableLocales(count); 725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (loc != NULL && index < count) { 726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return loc[index].getName(); 727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_countAvailable() 733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t count = 0; 735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Collator::getAvailableLocales(count); 736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return count; 737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_SERVICE 740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UEnumeration* U_EXPORT2 741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_openAvailableLocales(UErrorCode *status) { 742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_NAMESPACE_USE 743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This is a wrapper over Collator::getAvailableLocales() 745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) StringEnumeration *s = Collator::getAvailableLocales(); 749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (s == NULL) { 750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return uenum_openFromStringEnumeration(s, status); 754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Note: KEYWORDS[0] != RESOURCE_NAME - alan 758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char RESOURCE_NAME[] = "collations"; 760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const char* const KEYWORDS[] = { "collation" }; 762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define KEYWORD_COUNT (sizeof(KEYWORDS)/sizeof(KEYWORDS[0])) 764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UEnumeration* U_EXPORT2 766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getKeywords(UErrorCode *status) { 767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UEnumeration *result = NULL; 768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(*status)) { 769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return uenum_openCharStringsEnumeration(KEYWORDS, KEYWORD_COUNT, status); 770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UEnumeration* U_EXPORT2 775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getKeywordValues(const char *keyword, UErrorCode *status) { 776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // hard-coded to accept exactly one collation keyword 780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // modify if additional collation keyword is added later 781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (keyword==NULL || uprv_strcmp(keyword, KEYWORDS[0])!=0) 782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ures_getKeywordValues(U_ICUDATA_COLL, RESOURCE_NAME, status); 787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UEnumeration defaultKeywordValues = { 790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) NULL, 792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_close_keyword_values_iterator, 793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_count_keyword_values, 794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uenum_unextDefault, 795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_next_keyword_value, 796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_reset_keyword_values_iterator 797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h> 800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI UEnumeration* U_EXPORT2 802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getKeywordValuesForLocale(const char* /*key*/, const char* locale, 803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool /*commonlyUsed*/, UErrorCode* status) { 804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Get the locale base name. */ 805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char localeBuffer[ULOC_FULLNAME_CAPACITY] = ""; 806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uloc_getBaseName(locale, localeBuffer, sizeof(localeBuffer), status); 807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Create the 2 lists 809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * -values is the temp location for the keyword values 810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * -results hold the actual list used by the UEnumeration object 811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UList *values = ulist_createEmptyList(status); 813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UList *results = ulist_createEmptyList(status); 814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UEnumeration *en = (UEnumeration *)uprv_malloc(sizeof(UEnumeration)); 815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status) || en == NULL) { 816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (en == NULL) { 817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(en); 820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_deleteList(values); 822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_deleteList(results); 823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); 827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) en->context = results; 828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Open the resource bundle for collation with the given locale. */ 830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UResourceBundle bundle, collations, collres, defres; 831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_initStackObject(&bundle); 832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_initStackObject(&collations); 833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_initStackObject(&collres); 834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_initStackObject(&defres); 835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_openFillIn(&bundle, U_ICUDATA_COLL, localeBuffer, status); 837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (U_SUCCESS(*status)) { 839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_getByKey(&bundle, RESOURCE_NAME, &collations, status); 840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_resetIterator(&collations); 841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (U_SUCCESS(*status) && ures_hasNext(&collations)) { 842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_getNextResource(&collations, &collres, status); 843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *key = ures_getKey(&collres); 844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* If the key is default, get the string and store it in results list only 845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if results list is empty. 846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uprv_strcmp(key, "default") == 0) { 848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (ulist_getListSize(results) == 0) { 849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *defcoll = (char *)uprv_malloc(sizeof(char) * ULOC_KEYWORDS_CAPACITY); 850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t defcollLength = ULOC_KEYWORDS_CAPACITY; 851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_getNextResource(&collres, &defres, status); 853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if U_CHARSET_FAMILY==U_ASCII_FAMILY 854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* optimize - use the utf-8 string */ 855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_getUTF8String(&defres, defcoll, &defcollLength, TRUE, status); 856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar* defString = ures_getString(&defres, &defcollLength, status); 859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_SUCCESS(*status)) { 860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(defcollLength+1 > ULOC_KEYWORDS_CAPACITY) { 861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_BUFFER_OVERFLOW_ERROR; 862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) u_UCharsToChars(defString, defcoll, defcollLength+1); 864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_addItemBeginList(results, defcoll, TRUE, status); 870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_addItemEndList(values, key, FALSE, status); 873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* If the locale is "" this is root so exit. */ 877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (uprv_strlen(localeBuffer) == 0) { 878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Get the parent locale and open a new resource bundle. */ 881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uloc_getParent(localeBuffer, localeBuffer, sizeof(localeBuffer), status); 882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_openFillIn(&bundle, U_ICUDATA_COLL, localeBuffer, status); 883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(&defres); 886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(&collres); 887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(&collations); 888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ures_close(&bundle); 889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(*status)) { 891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) char *value = NULL; 892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_resetList(values); 893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while ((value = (char *)ulist_getNext(values)) != NULL) { 894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!ulist_containsString(results, value, (int32_t)uprv_strlen(value))) { 895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_addItemEndList(results, value, FALSE, status); 896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_deleteList(values); 904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)){ 906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uenum_close(en); 907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) en = NULL; 908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ulist_resetList(results); 910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return en; 913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int32_t U_EXPORT2 916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getFunctionalEquivalent(char* result, int32_t resultCapacity, 917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char* keyword, const char* locale, 918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool* isAvailable, UErrorCode* status) 919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // N.B.: Resource name is "collations" but keyword is "collation" 921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ures_getFunctionalEquivalent(result, resultCapacity, U_ICUDATA_COLL, 922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) "collations", keyword, locale, 923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) isAvailable, TRUE, status); 924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* returns the locale name the collation data comes from */ 927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI const char * U_EXPORT2 928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getLocale(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) { 929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return ucol_getLocaleByType(coll, type, status); 930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI const char * U_EXPORT2 933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getLocaleByType(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) { 934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const char *result = NULL; 935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)) { 936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_ENTRY(UTRACE_UCOL_GETLOCALE); 939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_DATA1(UTRACE_INFO, "coll=%p", coll); 940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) switch(type) { 942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ULOC_ACTUAL_LOCALE: 943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = coll->actualLocale; 944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ULOC_VALID_LOCALE: 946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = coll->validLocale; 947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) case ULOC_REQUESTED_LOCALE: 949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) result = coll->requestedLocale; 950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) default: 952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_DATA1(UTRACE_INFO, "result = %s", result); 955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTRACE_EXIT_STATUS(*status); 956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return result; 957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC void U_EXPORT2 960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_setReqValidLocales(UCollator *coll, char *requestedLocaleToAdopt, char *validLocaleToAdopt, char *actualLocaleToAdopt) 961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll) { 963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->validLocale) { 964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->validLocale); 965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->validLocale = validLocaleToAdopt; 967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->requestedLocale) { // should always have 968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->requestedLocale); 969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->requestedLocale = requestedLocaleToAdopt; 971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->actualLocale) { 972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->actualLocale); 973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->actualLocale = actualLocaleToAdopt; 975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI USet * U_EXPORT2 979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)ucol_getTailoredSet(const UCollator *coll, UErrorCode *status) 980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) U_NAMESPACE_USE 982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(status == NULL || U_FAILURE(*status)) { 984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(coll == NULL || coll->UCA == NULL) { 987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return NULL; 989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UParseError parseError; 991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UColTokenParser src; 992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t rulesLen = 0; 993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *rules = ucol_getRules(coll, &rulesLen); 994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool startOfRules = TRUE; 995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we internally use the C++ class, for the following reasons: 996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 1. we need to utilize canonical iterator, which is a C++ only class 997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 2. canonical iterator returns UnicodeStrings - USet cannot take them 998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // 3. USet is internally really UnicodeSet, C is just a wrapper 999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeSet *tailored = new UnicodeSet(); 1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString pattern; 1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UnicodeString empty; 1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CanonicalIterator it(empty, *status); 1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The idea is to tokenize the rule set. For each non-reset token, 1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // we add all the canonicaly equivalent FCD sequences 1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_initTokenList(&src, rules, rulesLen, coll->UCA, ucol_tok_getRulesFromBundle, NULL, status); 1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (ucol_tok_parseNextToken(&src, startOfRules, &parseError, status) != NULL) { 1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) startOfRules = FALSE; 1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src.parsedToken.strength != UCOL_TOK_RESET) { 1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UChar *stuff = src.source+(src.parsedToken.charsOffset); 1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) it.setSource(UnicodeString(stuff, src.parsedToken.charsLen), *status); 1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pattern = it.next(); 1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(!pattern.isBogus()) { 1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(Normalizer::quickCheck(pattern, UNORM_FCD, *status) != UNORM_NO) { 1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) tailored->add(pattern); 1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) pattern = it.next(); 1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_tok_closeTokenList(&src); 1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (USet *)tailored; 1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Collation Reordering 1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UErrorCode *status) { 1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(*status)) { 1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodesLength = 0; 1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->reorderCodes != NULL) { 1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->reorderCodes); 1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (parser->reorderCodesLength == 0 || parser->reorderCodes == NULL) { 1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodesLength = parser->reorderCodesLength; 1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodes = (int32_t*) uprv_malloc(coll->reorderCodesLength * sizeof(int32_t)); 1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(coll->reorderCodes, parser->reorderCodes, coll->reorderCodesLength * sizeof(int32_t)); 1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int ucol_getLeadBytesForReorderCode(UCollator *coll, int reorderCode, uint16_t* returnLeadBytes, int returnCapacity) { 1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t reorderCodeIndexLength = *((uint16_t*) ((uint8_t *)coll->UCA->image + coll->UCA->image->scriptToLeadByte)); 1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* reorderCodeIndex = (uint16_t*) ((uint8_t *)coll->UCA->image + coll->UCA->image->scriptToLeadByte + 2 *sizeof(uint16_t)); 1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // TODO - replace with a binary search 1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // reorder code index is 2 uint16_t's - reorder code + offset 1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < reorderCodeIndexLength; i++) { 1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (reorderCode == reorderCodeIndex[i*2]) { 1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t dataOffset = reorderCodeIndex[(i*2) + 1]; 1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ((dataOffset & 0x8000) == 0x8000) { 1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // offset isn't offset but instead is a single data element 1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (returnCapacity >= 1) { 1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) returnLeadBytes[0] = dataOffset & ~0x8000; 1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 1; 1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* dataOffsetBase = (uint16_t*) ((uint8_t *)reorderCodeIndex + reorderCodeIndexLength * (2 * sizeof(uint16_t))); 1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t leadByteCount = *(dataOffsetBase + dataOffset); 1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) leadByteCount = leadByteCount > returnCapacity ? returnCapacity : leadByteCount; 1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(returnLeadBytes, dataOffsetBase + dataOffset + 1, leadByteCount * sizeof(uint16_t)); 1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return leadByteCount; 1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int ucol_getReorderCodesForLeadByte(UCollator *coll, int leadByte, int16_t* returnReorderCodes, int returnCapacity) { 1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int leadByteIndexLength = *((uint16_t*) ((uint8_t *)coll->UCA->image + coll->UCA->image->leadByteToScript)); 1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* leadByteIndex = (uint16_t*) ((uint8_t *)coll->UCA->image + coll->UCA->image->leadByteToScript + 2 *sizeof(uint16_t)); 1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (leadByte >= leadByteIndexLength) { 1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ((leadByteIndex[leadByte] & 0x8000) == 0x8000) { 1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // offset isn't offset but instead is a single data element 1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (returnCapacity >= 1) { 1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) returnReorderCodes[0] = leadByteIndex[leadByte] & ~0x8000; 1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 1; 1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t* dataOffsetBase = (uint16_t*) ((uint8_t *)leadByteIndex + leadByteIndexLength * (2 * sizeof(uint16_t))); 1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t reorderCodeCount = *(dataOffsetBase + leadByteIndex[leadByte]); 1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reorderCodeCount = reorderCodeCount > returnCapacity ? returnCapacity : reorderCodeCount; 1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memcpy(returnReorderCodes, dataOffsetBase + leadByteIndex[leadByte] + 1, reorderCodeCount * sizeof(uint16_t)); 1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return reorderCodeCount; 1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// used to mark ignorable reorder code slots 1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t UCOL_REORDER_CODE_IGNORE = UCOL_REORDER_CODE_LIMIT + 1; 1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) { 1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t leadBytesSize = 256; 1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t leadBytes[256]; 1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t internalReorderCodesLength = coll->reorderCodesLength + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST); 1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t* internalReorderCodes; 1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The lowest byte that hasn't been assigned a mapping 1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int toBottom = 0x03; 1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The highest byte that hasn't been assigned a mapping - don't include the special or trailing 1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int toTop = 0xe4; 1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // are we filling from the bottom? 1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bool fromTheBottom = true; 1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // lead bytes that have alread been assigned to the permutation table 1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bool newLeadByteUsed[256]; 1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // permutation table slots that have already been filled 1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bool permutationSlotFilled[256]; 1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // nothing to do 1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(*status) || coll == NULL || coll->reorderCodesLength == 0) { 1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll != NULL) { 1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable != NULL) { 1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->leadBytePermutationTable); 1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable = NULL; 1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodesLength = 0; 1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable == NULL) { 1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable = (uint8_t*)uprv_malloc(256*sizeof(uint8_t)); 1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable == NULL) { 1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // prefill the reordering codes with the leading entries 1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalReorderCodes = (int32_t*)uprv_malloc(internalReorderCodesLength * sizeof(int32_t)); 1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (internalReorderCodes == NULL) { 1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_MEMORY_ALLOCATION_ERROR; 1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable != NULL) { 1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->leadBytePermutationTable); 1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable = NULL; 1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (uint32_t codeIndex = 0; codeIndex < (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST); codeIndex++) { 1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalReorderCodes[codeIndex] = UCOL_REORDER_CODE_FIRST + codeIndex; 1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int32_t codeIndex = 0; codeIndex < coll->reorderCodesLength; codeIndex++) { 1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint32_t reorderCodesCode = coll->reorderCodes[codeIndex]; 1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalReorderCodes[codeIndex + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST)] = reorderCodesCode; 1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (reorderCodesCode >= UCOL_REORDER_CODE_FIRST && reorderCodesCode < UCOL_REORDER_CODE_LIMIT) { 1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalReorderCodes[reorderCodesCode - UCOL_REORDER_CODE_FIRST] = UCOL_REORDER_CODE_IGNORE; 1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < 256; i++) { 1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (i < toBottom || i > toTop) { 1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) permutationSlotFilled[i] = true; 1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newLeadByteUsed[i] = true; 1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable[i] = i; 1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) permutationSlotFilled[i] = false; 1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newLeadByteUsed[i] = false; 1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable[i] = 0; 1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Start from the front of the list and place each script we encounter at the 1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * earliest possible locatation in the permutation table. If we encounter 1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * UNKNOWN, start processing from the back, and place each script in the last 1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * possible location. At each step, we also need to make sure that any scripts 1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * that need to not be moved are copied to their same location in the final table. 1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int reorderCodesIndex = 0; reorderCodesIndex < internalReorderCodesLength; reorderCodesIndex++) { 1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t next = internalReorderCodes[reorderCodesIndex]; 1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (next == UCOL_REORDER_CODE_IGNORE) { 1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (next == USCRIPT_UNKNOWN) { 1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fromTheBottom == false) { 1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // double turnaround 1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable != NULL) { 1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->leadBytePermutationTable); 1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable = NULL; 1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodesLength = 0; 1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (internalReorderCodes != NULL) { 1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(internalReorderCodes); 1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fromTheBottom = false; 1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) continue; 1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uint16_t leadByteCount = ucol_getLeadBytesForReorderCode(coll, next, leadBytes, leadBytesSize); 1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fromTheBottom) { 1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int leadByteIndex = 0; leadByteIndex < leadByteCount; leadByteIndex++) { 1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // don't place a lead byte twice in the permutation table 1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (permutationSlotFilled[leadBytes[leadByteIndex]]) { 1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // lead byte already used 1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable != NULL) { 1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->leadBytePermutationTable); 1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable = NULL; 1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodesLength = 0; 1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (internalReorderCodes != NULL) { 1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(internalReorderCodes); 1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable[leadBytes[leadByteIndex]] = toBottom; 1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newLeadByteUsed[toBottom] = true; 1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) permutationSlotFilled[leadBytes[leadByteIndex]] = true; 1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) toBottom++; 1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int leadByteIndex = leadByteCount - 1; leadByteIndex >= 0; leadByteIndex--) { 1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // don't place a lead byte twice in the permutation table 1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (permutationSlotFilled[leadBytes[leadByteIndex]]) { 1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // lead byte already used 1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *status = U_ILLEGAL_ARGUMENT_ERROR; 1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (coll->leadBytePermutationTable != NULL) { 1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(coll->leadBytePermutationTable); 1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable = NULL; 1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->reorderCodesLength = 0; 1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (internalReorderCodes != NULL) { 1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(internalReorderCodes); 1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 1241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable[leadBytes[leadByteIndex]] = toTop; 1244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newLeadByteUsed[toTop] = true; 1245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) permutationSlotFilled[leadBytes[leadByteIndex]] = true; 1246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) toTop--; 1247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef REORDER_DEBUG 1252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\n@@@@ Partial Script Reordering Table\n"); 1253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < 256; i++) { 1254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\t%02x = %02x\n", i, coll->leadBytePermutationTable[i]); 1255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\n@@@@ Lead Byte Used Table\n"); 1257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < 256; i++) { 1258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\t%02x = %02x\n", i, newLeadByteUsed[i]); 1259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\n@@@@ Permutation Slot Filled Table\n"); 1261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < 256; i++) { 1262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\t%02x = %02x\n", i, permutationSlotFilled[i]); 1263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Copy everything that's left over */ 1267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int reorderCode = 0; 1268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < 256; i++) { 1269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (!permutationSlotFilled[i]) { 1270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while (reorderCode < 256 && newLeadByteUsed[reorderCode]) { 1271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) reorderCode++; 1272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->leadBytePermutationTable[i] = reorderCode; 1274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) permutationSlotFilled[i] = true; 1275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) newLeadByteUsed[reorderCode] = true; 1276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef REORDER_DEBUG 1280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\n@@@@ Script Reordering Table\n"); 1281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for (int i = 0; i < 256; i++) { 1282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stdout, "\t%02x = %02x\n", i, coll->leadBytePermutationTable[i]); 1283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 1285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (internalReorderCodes != NULL) { 1287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_free(internalReorderCodes); 1288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 1289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // force a regen of the latin one table since it is affected by the script reordering 1291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) coll->latinOneRegenTable = TRUE; 1292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucol_updateInternalState(coll, status); 1293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 1294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 1295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_COLLATION */ 1296