1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/ucol_cnt.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,587 @@ 1.4 +/* 1.5 + ******************************************************************************* 1.6 + * 1.7 + * Copyright (C) 2001-2008, International Business Machines 1.8 + * Corporation and others. All Rights Reserved. 1.9 + * 1.10 + ******************************************************************************* 1.11 + * file name: ucol_cnt.cpp 1.12 + * encoding: US-ASCII 1.13 + * tab size: 8 (not used) 1.14 + * indentation:4 1.15 + * 1.16 + * created 02/22/2001 1.17 + * created by: Vladimir Weinstein 1.18 + * 1.19 + * This module maintains a contraction table structure in expanded form 1.20 + * and provides means to flatten this structure 1.21 + * 1.22 + */ 1.23 + 1.24 +#include "unicode/utypes.h" 1.25 + 1.26 +#if !UCONFIG_NO_COLLATION 1.27 + 1.28 +#include "unicode/uchar.h" 1.29 +#include "ucol_cnt.h" 1.30 +#include "cmemory.h" 1.31 + 1.32 +static void uprv_growTable(ContractionTable *tbl, UErrorCode *status) { 1.33 + if(tbl->position == tbl->size) { 1.34 + uint32_t *newData = (uint32_t *)uprv_realloc(tbl->CEs, 2*tbl->size*sizeof(uint32_t)); 1.35 + if(newData == NULL) { 1.36 + *status = U_MEMORY_ALLOCATION_ERROR; 1.37 + return; 1.38 + } 1.39 + UChar *newCPs = (UChar *)uprv_realloc(tbl->codePoints, 2*tbl->size*sizeof(UChar)); 1.40 + if(newCPs == NULL) { 1.41 + uprv_free(newData); 1.42 + *status = U_MEMORY_ALLOCATION_ERROR; 1.43 + return; 1.44 + } 1.45 + tbl->CEs = newData; 1.46 + tbl->codePoints = newCPs; 1.47 + tbl->size *= 2; 1.48 + } 1.49 +} 1.50 + 1.51 +U_CAPI CntTable* U_EXPORT2 1.52 +/*uprv_cnttab_open(CompactEIntArray *mapping, UErrorCode *status) {*/ 1.53 +uprv_cnttab_open(UNewTrie *mapping, UErrorCode *status) { 1.54 + if(U_FAILURE(*status)) { 1.55 + return 0; 1.56 + } 1.57 + CntTable *tbl = (CntTable *)uprv_malloc(sizeof(CntTable)); 1.58 + if(tbl == NULL) { 1.59 + *status = U_MEMORY_ALLOCATION_ERROR; 1.60 + return NULL; 1.61 + } 1.62 + tbl->mapping = mapping; 1.63 + tbl->elements = (ContractionTable **)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(ContractionTable *)); 1.64 + if(tbl->elements == NULL) { 1.65 + *status = U_MEMORY_ALLOCATION_ERROR; 1.66 + uprv_free(tbl); 1.67 + return NULL; 1.68 + } 1.69 + tbl->capacity = INIT_EXP_TABLE_SIZE; 1.70 + uprv_memset(tbl->elements, 0, INIT_EXP_TABLE_SIZE*sizeof(ContractionTable *)); 1.71 + tbl->size = 0; 1.72 + tbl->position = 0; 1.73 + tbl->CEs = NULL; 1.74 + tbl->codePoints = NULL; 1.75 + tbl->offsets = NULL; 1.76 + tbl->currentTag = NOT_FOUND_TAG; 1.77 + return tbl; 1.78 +} 1.79 + 1.80 +static ContractionTable *addATableElement(CntTable *table, uint32_t *key, UErrorCode *status) { 1.81 + ContractionTable *el = (ContractionTable *)uprv_malloc(sizeof(ContractionTable)); 1.82 + if(el == NULL) { 1.83 + goto outOfMemory; 1.84 + } 1.85 + el->CEs = (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(uint32_t)); 1.86 + if(el->CEs == NULL) { 1.87 + goto outOfMemory; 1.88 + } 1.89 + 1.90 + el->codePoints = (UChar *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(UChar)); 1.91 + if(el->codePoints == NULL) { 1.92 + uprv_free(el->CEs); 1.93 + goto outOfMemory; 1.94 + } 1.95 + 1.96 + el->position = 0; 1.97 + el->size = INIT_EXP_TABLE_SIZE; 1.98 + uprv_memset(el->CEs, 0, INIT_EXP_TABLE_SIZE*sizeof(uint32_t)); 1.99 + uprv_memset(el->codePoints, 0, INIT_EXP_TABLE_SIZE*sizeof(UChar)); 1.100 + 1.101 + table->elements[table->size] = el; 1.102 + 1.103 + //uhash_put(table->elements, (void *)table->size, el, status); 1.104 + 1.105 + *key = table->size++; 1.106 + 1.107 + if(table->size == table->capacity) { 1.108 + ContractionTable **newElements = (ContractionTable **)uprv_malloc(table->capacity*2*sizeof(ContractionTable *)); 1.109 + // do realloc 1.110 + /* table->elements = (ContractionTable **)realloc(table->elements, table->capacity*2*sizeof(ContractionTable *));*/ 1.111 + if(newElements == NULL) { 1.112 + uprv_free(el->codePoints); 1.113 + uprv_free(el->CEs); 1.114 + goto outOfMemory; 1.115 + } 1.116 + ContractionTable **oldElements = table->elements; 1.117 + uprv_memcpy(newElements, oldElements, table->capacity*sizeof(ContractionTable *)); 1.118 + uprv_memset(newElements+table->capacity, 0, table->capacity*sizeof(ContractionTable *)); 1.119 + table->capacity *= 2; 1.120 + table->elements = newElements; 1.121 + uprv_free(oldElements); 1.122 + } 1.123 + 1.124 + return el; 1.125 + 1.126 +outOfMemory: 1.127 + *status = U_MEMORY_ALLOCATION_ERROR; 1.128 + if (el) uprv_free(el); 1.129 + return NULL; 1.130 +} 1.131 + 1.132 +U_CAPI int32_t U_EXPORT2 1.133 +uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *status) { 1.134 + int32_t i = 0, j = 0; 1.135 + if(U_FAILURE(*status) || table->size == 0) { 1.136 + return 0; 1.137 + } 1.138 + 1.139 + table->position = 0; 1.140 + 1.141 + if(table->offsets != NULL) { 1.142 + uprv_free(table->offsets); 1.143 + } 1.144 + table->offsets = (int32_t *)uprv_malloc(table->size*sizeof(int32_t)); 1.145 + if(table->offsets == NULL) { 1.146 + *status = U_MEMORY_ALLOCATION_ERROR; 1.147 + return 0; 1.148 + } 1.149 + 1.150 + 1.151 + /* See how much memory we need */ 1.152 + for(i = 0; i<table->size; i++) { 1.153 + table->offsets[i] = table->position+mainOffset; 1.154 + table->position += table->elements[i]->position; 1.155 + } 1.156 + 1.157 + /* Allocate it */ 1.158 + if(table->CEs != NULL) { 1.159 + uprv_free(table->CEs); 1.160 + } 1.161 + table->CEs = (uint32_t *)uprv_malloc(table->position*sizeof(uint32_t)); 1.162 + if(table->CEs == NULL) { 1.163 + *status = U_MEMORY_ALLOCATION_ERROR; 1.164 + uprv_free(table->offsets); 1.165 + table->offsets = NULL; 1.166 + return 0; 1.167 + } 1.168 + uprv_memset(table->CEs, '?', table->position*sizeof(uint32_t)); 1.169 + 1.170 + if(table->codePoints != NULL) { 1.171 + uprv_free(table->codePoints); 1.172 + } 1.173 + table->codePoints = (UChar *)uprv_malloc(table->position*sizeof(UChar)); 1.174 + if(table->codePoints == NULL) { 1.175 + *status = U_MEMORY_ALLOCATION_ERROR; 1.176 + uprv_free(table->offsets); 1.177 + table->offsets = NULL; 1.178 + uprv_free(table->CEs); 1.179 + table->CEs = NULL; 1.180 + return 0; 1.181 + } 1.182 + uprv_memset(table->codePoints, '?', table->position*sizeof(UChar)); 1.183 + 1.184 + /* Now stuff the things in*/ 1.185 + 1.186 + UChar *cpPointer = table->codePoints; 1.187 + uint32_t *CEPointer = table->CEs; 1.188 + for(i = 0; i<table->size; i++) { 1.189 + int32_t size = table->elements[i]->position; 1.190 + uint8_t ccMax = 0, ccMin = 255, cc = 0; 1.191 + for(j = 1; j<size; j++) { 1.192 + cc = u_getCombiningClass(table->elements[i]->codePoints[j]); 1.193 + if(cc>ccMax) { 1.194 + ccMax = cc; 1.195 + } 1.196 + if(cc<ccMin) { 1.197 + ccMin = cc; 1.198 + } 1.199 + *(cpPointer+j) = table->elements[i]->codePoints[j]; 1.200 + } 1.201 + *cpPointer = ((ccMin==ccMax)?1:0 << 8) | ccMax; 1.202 + 1.203 + uprv_memcpy(CEPointer, table->elements[i]->CEs, size*sizeof(uint32_t)); 1.204 + for(j = 0; j<size; j++) { 1.205 + if(isCntTableElement(*(CEPointer+j))) { 1.206 + *(CEPointer+j) = constructContractCE(getCETag(*(CEPointer+j)), table->offsets[getContractOffset(*(CEPointer+j))]); 1.207 + } 1.208 + } 1.209 + cpPointer += size; 1.210 + CEPointer += size; 1.211 + } 1.212 + 1.213 + // TODO: this one apparently updates the contraction CEs to point to a real address (relative to the 1.214 + // start of the flat file). However, what is done below is just wrong and it affects building of 1.215 + // tailorings that have constructions in a bad way. At least, one should enumerate the trie. Also, 1.216 + // keeping a list of code points that are contractions might be smart, although I'm not sure if it's 1.217 + // feasible. 1.218 + uint32_t CE; 1.219 + for(i = 0; i<=0x10FFFF; i++) { 1.220 + /*CE = ucmpe32_get(table->mapping, i);*/ 1.221 + CE = utrie_get32(table->mapping, i, NULL); 1.222 + if(isCntTableElement(CE)) { 1.223 + CE = constructContractCE(getCETag(CE), table->offsets[getContractOffset(CE)]); 1.224 + /*ucmpe32_set(table->mapping, i, CE);*/ 1.225 + utrie_set32(table->mapping, i, CE); 1.226 + } 1.227 + } 1.228 + 1.229 + 1.230 + return table->position; 1.231 +} 1.232 + 1.233 +static ContractionTable *uprv_cnttab_cloneContraction(ContractionTable *t, UErrorCode *status) { 1.234 + ContractionTable *r = (ContractionTable *)uprv_malloc(sizeof(ContractionTable)); 1.235 + if(r == NULL) { 1.236 + goto outOfMemory; 1.237 + } 1.238 + 1.239 + r->position = t->position; 1.240 + r->size = t->size; 1.241 + 1.242 + r->codePoints = (UChar *)uprv_malloc(sizeof(UChar)*t->size); 1.243 + if(r->codePoints == NULL) { 1.244 + goto outOfMemory; 1.245 + } 1.246 + r->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->size); 1.247 + if(r->CEs == NULL) { 1.248 + uprv_free(r->codePoints); 1.249 + goto outOfMemory; 1.250 + } 1.251 + uprv_memcpy(r->codePoints, t->codePoints, sizeof(UChar)*t->size); 1.252 + uprv_memcpy(r->CEs, t->CEs, sizeof(uint32_t)*t->size); 1.253 + 1.254 + return r; 1.255 + 1.256 +outOfMemory: 1.257 + *status = U_MEMORY_ALLOCATION_ERROR; 1.258 + if (r) uprv_free(r); 1.259 + return NULL; 1.260 +} 1.261 + 1.262 +U_CAPI CntTable* U_EXPORT2 1.263 +uprv_cnttab_clone(CntTable *t, UErrorCode *status) { 1.264 + if(U_FAILURE(*status)) { 1.265 + return NULL; 1.266 + } 1.267 + int32_t i = 0; 1.268 + CntTable *r = (CntTable *)uprv_malloc(sizeof(CntTable)); 1.269 + /* test for NULL */ 1.270 + if (r == NULL) { 1.271 + goto outOfMemory; 1.272 + } 1.273 + r->position = t->position; 1.274 + r->size = t->size; 1.275 + r->capacity = t->capacity; 1.276 + 1.277 + r->mapping = t->mapping; 1.278 + 1.279 + r->elements = (ContractionTable **)uprv_malloc(t->capacity*sizeof(ContractionTable *)); 1.280 + /* test for NULL */ 1.281 + if (r->elements == NULL) { 1.282 + goto outOfMemory; 1.283 + } 1.284 + //uprv_memcpy(r->elements, t->elements, t->capacity*sizeof(ContractionTable *)); 1.285 + 1.286 + for(i = 0; i<t->size; i++) { 1.287 + r->elements[i] = uprv_cnttab_cloneContraction(t->elements[i], status); 1.288 + } 1.289 + 1.290 + if(t->CEs != NULL) { 1.291 + r->CEs = (uint32_t *)uprv_malloc(t->position*sizeof(uint32_t)); 1.292 + /* test for NULL */ 1.293 + if (r->CEs == NULL) { 1.294 + uprv_free(r->elements); 1.295 + goto outOfMemory; 1.296 + } 1.297 + uprv_memcpy(r->CEs, t->CEs, t->position*sizeof(uint32_t)); 1.298 + } else { 1.299 + r->CEs = NULL; 1.300 + } 1.301 + 1.302 + if(t->codePoints != NULL) { 1.303 + r->codePoints = (UChar *)uprv_malloc(t->position*sizeof(UChar)); 1.304 + /* test for NULL */ 1.305 + if (r->codePoints == NULL) { 1.306 + uprv_free(r->CEs); 1.307 + uprv_free(r->elements); 1.308 + goto outOfMemory; 1.309 + } 1.310 + uprv_memcpy(r->codePoints, t->codePoints, t->position*sizeof(UChar)); 1.311 + } else { 1.312 + r->codePoints = NULL; 1.313 + } 1.314 + 1.315 + if(t->offsets != NULL) { 1.316 + r->offsets = (int32_t *)uprv_malloc(t->size*sizeof(int32_t)); 1.317 + /* test for NULL */ 1.318 + if (r->offsets == NULL) { 1.319 + uprv_free(r->codePoints); 1.320 + uprv_free(r->CEs); 1.321 + uprv_free(r->elements); 1.322 + goto outOfMemory; 1.323 + } 1.324 + uprv_memcpy(r->offsets, t->offsets, t->size*sizeof(int32_t)); 1.325 + } else { 1.326 + r->offsets = NULL; 1.327 + } 1.328 + 1.329 + return r; 1.330 + 1.331 +outOfMemory: 1.332 + *status = U_MEMORY_ALLOCATION_ERROR; 1.333 + if (r) uprv_free(r); 1.334 + return NULL; 1.335 +} 1.336 + 1.337 +U_CAPI void U_EXPORT2 1.338 +uprv_cnttab_close(CntTable *table) { 1.339 + int32_t i = 0; 1.340 + for(i = 0; i<table->size; i++) { 1.341 + uprv_free(table->elements[i]->CEs); 1.342 + uprv_free(table->elements[i]->codePoints); 1.343 + uprv_free(table->elements[i]); 1.344 + } 1.345 + uprv_free(table->elements); 1.346 + uprv_free(table->CEs); 1.347 + uprv_free(table->offsets); 1.348 + uprv_free(table->codePoints); 1.349 + uprv_free(table); 1.350 +} 1.351 + 1.352 +/* this is for adding non contractions */ 1.353 +U_CAPI uint32_t U_EXPORT2 1.354 +uprv_cnttab_changeLastCE(CntTable *table, uint32_t element, uint32_t value, UErrorCode *status) { 1.355 + element &= 0xFFFFFF; 1.356 + 1.357 + ContractionTable *tbl = NULL; 1.358 + if(U_FAILURE(*status)) { 1.359 + return 0; 1.360 + } 1.361 + 1.362 + if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { 1.363 + return 0; 1.364 + } 1.365 + 1.366 + tbl->CEs[tbl->position-1] = value; 1.367 + 1.368 + return(constructContractCE(table->currentTag, element)); 1.369 +} 1.370 + 1.371 + 1.372 +/* inserts a part of contraction sequence in table. Sequences behind the offset are moved back. If element is non existent, it creates on. Returns element handle */ 1.373 +U_CAPI uint32_t U_EXPORT2 1.374 +uprv_cnttab_insertContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t value, UErrorCode *status) { 1.375 + 1.376 + ContractionTable *tbl = NULL; 1.377 + 1.378 + if(U_FAILURE(*status)) { 1.379 + return 0; 1.380 + } 1.381 + element &= 0xFFFFFF; 1.382 + 1.383 + if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { 1.384 + tbl = addATableElement(table, &element, status); 1.385 + if (U_FAILURE(*status)) { 1.386 + return 0; 1.387 + } 1.388 + } 1.389 + 1.390 + uprv_growTable(tbl, status); 1.391 + 1.392 + uint32_t offset = 0; 1.393 + 1.394 + 1.395 + while(tbl->codePoints[offset] < codePoint && offset<tbl->position) { 1.396 + offset++; 1.397 + } 1.398 + 1.399 + uint32_t i = tbl->position; 1.400 + for(i = tbl->position; i > offset; i--) { 1.401 + tbl->CEs[i] = tbl->CEs[i-1]; 1.402 + tbl->codePoints[i] = tbl->codePoints[i-1]; 1.403 + } 1.404 + 1.405 + tbl->CEs[offset] = value; 1.406 + tbl->codePoints[offset] = codePoint; 1.407 + 1.408 + tbl->position++; 1.409 + 1.410 + return(constructContractCE(table->currentTag, element)); 1.411 +} 1.412 + 1.413 + 1.414 +/* adds more contractions in table. If element is non existant, it creates on. Returns element handle */ 1.415 +U_CAPI uint32_t U_EXPORT2 1.416 +uprv_cnttab_addContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t value, UErrorCode *status) { 1.417 + 1.418 + element &= 0xFFFFFF; 1.419 + 1.420 + ContractionTable *tbl = NULL; 1.421 + 1.422 + if(U_FAILURE(*status)) { 1.423 + return 0; 1.424 + } 1.425 + 1.426 + if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { 1.427 + tbl = addATableElement(table, &element, status); 1.428 + if (U_FAILURE(*status)) { 1.429 + return 0; 1.430 + } 1.431 + } 1.432 + 1.433 + uprv_growTable(tbl, status); 1.434 + 1.435 + tbl->CEs[tbl->position] = value; 1.436 + tbl->codePoints[tbl->position] = codePoint; 1.437 + 1.438 + tbl->position++; 1.439 + 1.440 + return(constructContractCE(table->currentTag, element)); 1.441 +} 1.442 + 1.443 +/* sets a part of contraction sequence in table. If element is non existant, it creates on. Returns element handle */ 1.444 +U_CAPI uint32_t U_EXPORT2 1.445 +uprv_cnttab_setContraction(CntTable *table, uint32_t element, uint32_t offset, UChar codePoint, uint32_t value, UErrorCode *status) { 1.446 + 1.447 + element &= 0xFFFFFF; 1.448 + ContractionTable *tbl = NULL; 1.449 + 1.450 + if(U_FAILURE(*status)) { 1.451 + return 0; 1.452 + } 1.453 + 1.454 + if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { 1.455 + tbl = addATableElement(table, &element, status); 1.456 + if (U_FAILURE(*status)) { 1.457 + return 0; 1.458 + } 1.459 + 1.460 + } 1.461 + 1.462 + if(offset >= tbl->size) { 1.463 + *status = U_INDEX_OUTOFBOUNDS_ERROR; 1.464 + return 0; 1.465 + } 1.466 + tbl->CEs[offset] = value; 1.467 + tbl->codePoints[offset] = codePoint; 1.468 + 1.469 + //return(offset); 1.470 + return(constructContractCE(table->currentTag, element)); 1.471 +} 1.472 + 1.473 +static ContractionTable *_cnttab_getContractionTable(CntTable *table, uint32_t element) { 1.474 + element &= 0xFFFFFF; 1.475 + ContractionTable *tbl = NULL; 1.476 + 1.477 + if(element != 0xFFFFFF) { 1.478 + tbl = table->elements[element]; /* This could also return NULL */ 1.479 + } 1.480 + return tbl; 1.481 +} 1.482 + 1.483 +static int32_t _cnttab_findCP(ContractionTable *tbl, UChar codePoint) { 1.484 + uint32_t position = 0; 1.485 + if(tbl == NULL) { 1.486 + return -1; 1.487 + } 1.488 + 1.489 + while(codePoint > tbl->codePoints[position]) { 1.490 + position++; 1.491 + if(position > tbl->position) { 1.492 + return -1; 1.493 + } 1.494 + } 1.495 + if (codePoint == tbl->codePoints[position]) { 1.496 + return position; 1.497 + } else { 1.498 + return -1; 1.499 + } 1.500 +} 1.501 + 1.502 +static uint32_t _cnttab_getCE(ContractionTable *tbl, int32_t position) { 1.503 + if(tbl == NULL) { 1.504 + return UCOL_NOT_FOUND; 1.505 + } 1.506 + if((uint32_t)position > tbl->position || position == -1) { 1.507 + return UCOL_NOT_FOUND; 1.508 + } else { 1.509 + return tbl->CEs[position]; 1.510 + } 1.511 +} 1.512 + 1.513 +U_CAPI int32_t U_EXPORT2 1.514 +uprv_cnttab_findCP(CntTable *table, uint32_t element, UChar codePoint, UErrorCode *status) { 1.515 + 1.516 + if(U_FAILURE(*status)) { 1.517 + return 0; 1.518 + } 1.519 + 1.520 + return _cnttab_findCP(_cnttab_getContractionTable(table, element), codePoint); 1.521 +} 1.522 + 1.523 +U_CAPI uint32_t U_EXPORT2 1.524 +uprv_cnttab_getCE(CntTable *table, uint32_t element, uint32_t position, UErrorCode *status) { 1.525 + if(U_FAILURE(*status)) { 1.526 + return UCOL_NOT_FOUND; 1.527 + } 1.528 + 1.529 + return(_cnttab_getCE(_cnttab_getContractionTable(table, element), position)); 1.530 +} 1.531 + 1.532 +U_CAPI uint32_t U_EXPORT2 1.533 +uprv_cnttab_findCE(CntTable *table, uint32_t element, UChar codePoint, UErrorCode *status) { 1.534 + if(U_FAILURE(*status)) { 1.535 + return UCOL_NOT_FOUND; 1.536 + } 1.537 + ContractionTable *tbl = _cnttab_getContractionTable(table, element); 1.538 + return _cnttab_getCE(tbl, _cnttab_findCP(tbl, codePoint)); 1.539 +} 1.540 + 1.541 +U_CAPI UBool U_EXPORT2 1.542 +uprv_cnttab_isTailored(CntTable *table, uint32_t element, UChar *ztString, UErrorCode *status) { 1.543 + if(U_FAILURE(*status)) { 1.544 + return FALSE; 1.545 + } 1.546 + 1.547 + while(*(ztString)!=0) { 1.548 + element = uprv_cnttab_findCE(table, element, *(ztString), status); 1.549 + if(element == UCOL_NOT_FOUND) { 1.550 + return FALSE; 1.551 + } 1.552 + if(!isCntTableElement(element)) { 1.553 + return TRUE; 1.554 + } 1.555 + ztString++; 1.556 + } 1.557 + return (UBool)(uprv_cnttab_getCE(table, element, 0, status) != UCOL_NOT_FOUND); 1.558 +} 1.559 + 1.560 +U_CAPI uint32_t U_EXPORT2 1.561 +uprv_cnttab_changeContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t newCE, UErrorCode *status) { 1.562 + 1.563 + element &= 0xFFFFFF; 1.564 + ContractionTable *tbl = NULL; 1.565 + 1.566 + if(U_FAILURE(*status)) { 1.567 + return 0; 1.568 + } 1.569 + 1.570 + if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { 1.571 + return 0; 1.572 + } 1.573 + 1.574 + uint32_t position = 0; 1.575 + 1.576 + while(codePoint > tbl->codePoints[position]) { 1.577 + position++; 1.578 + if(position > tbl->position) { 1.579 + return UCOL_NOT_FOUND; 1.580 + } 1.581 + } 1.582 + if (codePoint == tbl->codePoints[position]) { 1.583 + tbl->CEs[position] = newCE; 1.584 + return element; 1.585 + } else { 1.586 + return UCOL_NOT_FOUND; 1.587 + } 1.588 +} 1.589 + 1.590 +#endif /* #if !UCONFIG_NO_COLLATION */