intl/icu/source/i18n/ucol_cnt.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 *******************************************************************************
michael@0 3 *
michael@0 4 * Copyright (C) 2001-2008, International Business Machines
michael@0 5 * Corporation and others. All Rights Reserved.
michael@0 6 *
michael@0 7 *******************************************************************************
michael@0 8 * file name: ucol_cnt.cpp
michael@0 9 * encoding: US-ASCII
michael@0 10 * tab size: 8 (not used)
michael@0 11 * indentation:4
michael@0 12 *
michael@0 13 * created 02/22/2001
michael@0 14 * created by: Vladimir Weinstein
michael@0 15 *
michael@0 16 * This module maintains a contraction table structure in expanded form
michael@0 17 * and provides means to flatten this structure
michael@0 18 *
michael@0 19 */
michael@0 20
michael@0 21 #include "unicode/utypes.h"
michael@0 22
michael@0 23 #if !UCONFIG_NO_COLLATION
michael@0 24
michael@0 25 #include "unicode/uchar.h"
michael@0 26 #include "ucol_cnt.h"
michael@0 27 #include "cmemory.h"
michael@0 28
michael@0 29 static void uprv_growTable(ContractionTable *tbl, UErrorCode *status) {
michael@0 30 if(tbl->position == tbl->size) {
michael@0 31 uint32_t *newData = (uint32_t *)uprv_realloc(tbl->CEs, 2*tbl->size*sizeof(uint32_t));
michael@0 32 if(newData == NULL) {
michael@0 33 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 34 return;
michael@0 35 }
michael@0 36 UChar *newCPs = (UChar *)uprv_realloc(tbl->codePoints, 2*tbl->size*sizeof(UChar));
michael@0 37 if(newCPs == NULL) {
michael@0 38 uprv_free(newData);
michael@0 39 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 40 return;
michael@0 41 }
michael@0 42 tbl->CEs = newData;
michael@0 43 tbl->codePoints = newCPs;
michael@0 44 tbl->size *= 2;
michael@0 45 }
michael@0 46 }
michael@0 47
michael@0 48 U_CAPI CntTable* U_EXPORT2
michael@0 49 /*uprv_cnttab_open(CompactEIntArray *mapping, UErrorCode *status) {*/
michael@0 50 uprv_cnttab_open(UNewTrie *mapping, UErrorCode *status) {
michael@0 51 if(U_FAILURE(*status)) {
michael@0 52 return 0;
michael@0 53 }
michael@0 54 CntTable *tbl = (CntTable *)uprv_malloc(sizeof(CntTable));
michael@0 55 if(tbl == NULL) {
michael@0 56 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 57 return NULL;
michael@0 58 }
michael@0 59 tbl->mapping = mapping;
michael@0 60 tbl->elements = (ContractionTable **)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(ContractionTable *));
michael@0 61 if(tbl->elements == NULL) {
michael@0 62 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 63 uprv_free(tbl);
michael@0 64 return NULL;
michael@0 65 }
michael@0 66 tbl->capacity = INIT_EXP_TABLE_SIZE;
michael@0 67 uprv_memset(tbl->elements, 0, INIT_EXP_TABLE_SIZE*sizeof(ContractionTable *));
michael@0 68 tbl->size = 0;
michael@0 69 tbl->position = 0;
michael@0 70 tbl->CEs = NULL;
michael@0 71 tbl->codePoints = NULL;
michael@0 72 tbl->offsets = NULL;
michael@0 73 tbl->currentTag = NOT_FOUND_TAG;
michael@0 74 return tbl;
michael@0 75 }
michael@0 76
michael@0 77 static ContractionTable *addATableElement(CntTable *table, uint32_t *key, UErrorCode *status) {
michael@0 78 ContractionTable *el = (ContractionTable *)uprv_malloc(sizeof(ContractionTable));
michael@0 79 if(el == NULL) {
michael@0 80 goto outOfMemory;
michael@0 81 }
michael@0 82 el->CEs = (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(uint32_t));
michael@0 83 if(el->CEs == NULL) {
michael@0 84 goto outOfMemory;
michael@0 85 }
michael@0 86
michael@0 87 el->codePoints = (UChar *)uprv_malloc(INIT_EXP_TABLE_SIZE*sizeof(UChar));
michael@0 88 if(el->codePoints == NULL) {
michael@0 89 uprv_free(el->CEs);
michael@0 90 goto outOfMemory;
michael@0 91 }
michael@0 92
michael@0 93 el->position = 0;
michael@0 94 el->size = INIT_EXP_TABLE_SIZE;
michael@0 95 uprv_memset(el->CEs, 0, INIT_EXP_TABLE_SIZE*sizeof(uint32_t));
michael@0 96 uprv_memset(el->codePoints, 0, INIT_EXP_TABLE_SIZE*sizeof(UChar));
michael@0 97
michael@0 98 table->elements[table->size] = el;
michael@0 99
michael@0 100 //uhash_put(table->elements, (void *)table->size, el, status);
michael@0 101
michael@0 102 *key = table->size++;
michael@0 103
michael@0 104 if(table->size == table->capacity) {
michael@0 105 ContractionTable **newElements = (ContractionTable **)uprv_malloc(table->capacity*2*sizeof(ContractionTable *));
michael@0 106 // do realloc
michael@0 107 /* table->elements = (ContractionTable **)realloc(table->elements, table->capacity*2*sizeof(ContractionTable *));*/
michael@0 108 if(newElements == NULL) {
michael@0 109 uprv_free(el->codePoints);
michael@0 110 uprv_free(el->CEs);
michael@0 111 goto outOfMemory;
michael@0 112 }
michael@0 113 ContractionTable **oldElements = table->elements;
michael@0 114 uprv_memcpy(newElements, oldElements, table->capacity*sizeof(ContractionTable *));
michael@0 115 uprv_memset(newElements+table->capacity, 0, table->capacity*sizeof(ContractionTable *));
michael@0 116 table->capacity *= 2;
michael@0 117 table->elements = newElements;
michael@0 118 uprv_free(oldElements);
michael@0 119 }
michael@0 120
michael@0 121 return el;
michael@0 122
michael@0 123 outOfMemory:
michael@0 124 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 125 if (el) uprv_free(el);
michael@0 126 return NULL;
michael@0 127 }
michael@0 128
michael@0 129 U_CAPI int32_t U_EXPORT2
michael@0 130 uprv_cnttab_constructTable(CntTable *table, uint32_t mainOffset, UErrorCode *status) {
michael@0 131 int32_t i = 0, j = 0;
michael@0 132 if(U_FAILURE(*status) || table->size == 0) {
michael@0 133 return 0;
michael@0 134 }
michael@0 135
michael@0 136 table->position = 0;
michael@0 137
michael@0 138 if(table->offsets != NULL) {
michael@0 139 uprv_free(table->offsets);
michael@0 140 }
michael@0 141 table->offsets = (int32_t *)uprv_malloc(table->size*sizeof(int32_t));
michael@0 142 if(table->offsets == NULL) {
michael@0 143 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 144 return 0;
michael@0 145 }
michael@0 146
michael@0 147
michael@0 148 /* See how much memory we need */
michael@0 149 for(i = 0; i<table->size; i++) {
michael@0 150 table->offsets[i] = table->position+mainOffset;
michael@0 151 table->position += table->elements[i]->position;
michael@0 152 }
michael@0 153
michael@0 154 /* Allocate it */
michael@0 155 if(table->CEs != NULL) {
michael@0 156 uprv_free(table->CEs);
michael@0 157 }
michael@0 158 table->CEs = (uint32_t *)uprv_malloc(table->position*sizeof(uint32_t));
michael@0 159 if(table->CEs == NULL) {
michael@0 160 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 161 uprv_free(table->offsets);
michael@0 162 table->offsets = NULL;
michael@0 163 return 0;
michael@0 164 }
michael@0 165 uprv_memset(table->CEs, '?', table->position*sizeof(uint32_t));
michael@0 166
michael@0 167 if(table->codePoints != NULL) {
michael@0 168 uprv_free(table->codePoints);
michael@0 169 }
michael@0 170 table->codePoints = (UChar *)uprv_malloc(table->position*sizeof(UChar));
michael@0 171 if(table->codePoints == NULL) {
michael@0 172 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 173 uprv_free(table->offsets);
michael@0 174 table->offsets = NULL;
michael@0 175 uprv_free(table->CEs);
michael@0 176 table->CEs = NULL;
michael@0 177 return 0;
michael@0 178 }
michael@0 179 uprv_memset(table->codePoints, '?', table->position*sizeof(UChar));
michael@0 180
michael@0 181 /* Now stuff the things in*/
michael@0 182
michael@0 183 UChar *cpPointer = table->codePoints;
michael@0 184 uint32_t *CEPointer = table->CEs;
michael@0 185 for(i = 0; i<table->size; i++) {
michael@0 186 int32_t size = table->elements[i]->position;
michael@0 187 uint8_t ccMax = 0, ccMin = 255, cc = 0;
michael@0 188 for(j = 1; j<size; j++) {
michael@0 189 cc = u_getCombiningClass(table->elements[i]->codePoints[j]);
michael@0 190 if(cc>ccMax) {
michael@0 191 ccMax = cc;
michael@0 192 }
michael@0 193 if(cc<ccMin) {
michael@0 194 ccMin = cc;
michael@0 195 }
michael@0 196 *(cpPointer+j) = table->elements[i]->codePoints[j];
michael@0 197 }
michael@0 198 *cpPointer = ((ccMin==ccMax)?1:0 << 8) | ccMax;
michael@0 199
michael@0 200 uprv_memcpy(CEPointer, table->elements[i]->CEs, size*sizeof(uint32_t));
michael@0 201 for(j = 0; j<size; j++) {
michael@0 202 if(isCntTableElement(*(CEPointer+j))) {
michael@0 203 *(CEPointer+j) = constructContractCE(getCETag(*(CEPointer+j)), table->offsets[getContractOffset(*(CEPointer+j))]);
michael@0 204 }
michael@0 205 }
michael@0 206 cpPointer += size;
michael@0 207 CEPointer += size;
michael@0 208 }
michael@0 209
michael@0 210 // TODO: this one apparently updates the contraction CEs to point to a real address (relative to the
michael@0 211 // start of the flat file). However, what is done below is just wrong and it affects building of
michael@0 212 // tailorings that have constructions in a bad way. At least, one should enumerate the trie. Also,
michael@0 213 // keeping a list of code points that are contractions might be smart, although I'm not sure if it's
michael@0 214 // feasible.
michael@0 215 uint32_t CE;
michael@0 216 for(i = 0; i<=0x10FFFF; i++) {
michael@0 217 /*CE = ucmpe32_get(table->mapping, i);*/
michael@0 218 CE = utrie_get32(table->mapping, i, NULL);
michael@0 219 if(isCntTableElement(CE)) {
michael@0 220 CE = constructContractCE(getCETag(CE), table->offsets[getContractOffset(CE)]);
michael@0 221 /*ucmpe32_set(table->mapping, i, CE);*/
michael@0 222 utrie_set32(table->mapping, i, CE);
michael@0 223 }
michael@0 224 }
michael@0 225
michael@0 226
michael@0 227 return table->position;
michael@0 228 }
michael@0 229
michael@0 230 static ContractionTable *uprv_cnttab_cloneContraction(ContractionTable *t, UErrorCode *status) {
michael@0 231 ContractionTable *r = (ContractionTable *)uprv_malloc(sizeof(ContractionTable));
michael@0 232 if(r == NULL) {
michael@0 233 goto outOfMemory;
michael@0 234 }
michael@0 235
michael@0 236 r->position = t->position;
michael@0 237 r->size = t->size;
michael@0 238
michael@0 239 r->codePoints = (UChar *)uprv_malloc(sizeof(UChar)*t->size);
michael@0 240 if(r->codePoints == NULL) {
michael@0 241 goto outOfMemory;
michael@0 242 }
michael@0 243 r->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->size);
michael@0 244 if(r->CEs == NULL) {
michael@0 245 uprv_free(r->codePoints);
michael@0 246 goto outOfMemory;
michael@0 247 }
michael@0 248 uprv_memcpy(r->codePoints, t->codePoints, sizeof(UChar)*t->size);
michael@0 249 uprv_memcpy(r->CEs, t->CEs, sizeof(uint32_t)*t->size);
michael@0 250
michael@0 251 return r;
michael@0 252
michael@0 253 outOfMemory:
michael@0 254 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 255 if (r) uprv_free(r);
michael@0 256 return NULL;
michael@0 257 }
michael@0 258
michael@0 259 U_CAPI CntTable* U_EXPORT2
michael@0 260 uprv_cnttab_clone(CntTable *t, UErrorCode *status) {
michael@0 261 if(U_FAILURE(*status)) {
michael@0 262 return NULL;
michael@0 263 }
michael@0 264 int32_t i = 0;
michael@0 265 CntTable *r = (CntTable *)uprv_malloc(sizeof(CntTable));
michael@0 266 /* test for NULL */
michael@0 267 if (r == NULL) {
michael@0 268 goto outOfMemory;
michael@0 269 }
michael@0 270 r->position = t->position;
michael@0 271 r->size = t->size;
michael@0 272 r->capacity = t->capacity;
michael@0 273
michael@0 274 r->mapping = t->mapping;
michael@0 275
michael@0 276 r->elements = (ContractionTable **)uprv_malloc(t->capacity*sizeof(ContractionTable *));
michael@0 277 /* test for NULL */
michael@0 278 if (r->elements == NULL) {
michael@0 279 goto outOfMemory;
michael@0 280 }
michael@0 281 //uprv_memcpy(r->elements, t->elements, t->capacity*sizeof(ContractionTable *));
michael@0 282
michael@0 283 for(i = 0; i<t->size; i++) {
michael@0 284 r->elements[i] = uprv_cnttab_cloneContraction(t->elements[i], status);
michael@0 285 }
michael@0 286
michael@0 287 if(t->CEs != NULL) {
michael@0 288 r->CEs = (uint32_t *)uprv_malloc(t->position*sizeof(uint32_t));
michael@0 289 /* test for NULL */
michael@0 290 if (r->CEs == NULL) {
michael@0 291 uprv_free(r->elements);
michael@0 292 goto outOfMemory;
michael@0 293 }
michael@0 294 uprv_memcpy(r->CEs, t->CEs, t->position*sizeof(uint32_t));
michael@0 295 } else {
michael@0 296 r->CEs = NULL;
michael@0 297 }
michael@0 298
michael@0 299 if(t->codePoints != NULL) {
michael@0 300 r->codePoints = (UChar *)uprv_malloc(t->position*sizeof(UChar));
michael@0 301 /* test for NULL */
michael@0 302 if (r->codePoints == NULL) {
michael@0 303 uprv_free(r->CEs);
michael@0 304 uprv_free(r->elements);
michael@0 305 goto outOfMemory;
michael@0 306 }
michael@0 307 uprv_memcpy(r->codePoints, t->codePoints, t->position*sizeof(UChar));
michael@0 308 } else {
michael@0 309 r->codePoints = NULL;
michael@0 310 }
michael@0 311
michael@0 312 if(t->offsets != NULL) {
michael@0 313 r->offsets = (int32_t *)uprv_malloc(t->size*sizeof(int32_t));
michael@0 314 /* test for NULL */
michael@0 315 if (r->offsets == NULL) {
michael@0 316 uprv_free(r->codePoints);
michael@0 317 uprv_free(r->CEs);
michael@0 318 uprv_free(r->elements);
michael@0 319 goto outOfMemory;
michael@0 320 }
michael@0 321 uprv_memcpy(r->offsets, t->offsets, t->size*sizeof(int32_t));
michael@0 322 } else {
michael@0 323 r->offsets = NULL;
michael@0 324 }
michael@0 325
michael@0 326 return r;
michael@0 327
michael@0 328 outOfMemory:
michael@0 329 *status = U_MEMORY_ALLOCATION_ERROR;
michael@0 330 if (r) uprv_free(r);
michael@0 331 return NULL;
michael@0 332 }
michael@0 333
michael@0 334 U_CAPI void U_EXPORT2
michael@0 335 uprv_cnttab_close(CntTable *table) {
michael@0 336 int32_t i = 0;
michael@0 337 for(i = 0; i<table->size; i++) {
michael@0 338 uprv_free(table->elements[i]->CEs);
michael@0 339 uprv_free(table->elements[i]->codePoints);
michael@0 340 uprv_free(table->elements[i]);
michael@0 341 }
michael@0 342 uprv_free(table->elements);
michael@0 343 uprv_free(table->CEs);
michael@0 344 uprv_free(table->offsets);
michael@0 345 uprv_free(table->codePoints);
michael@0 346 uprv_free(table);
michael@0 347 }
michael@0 348
michael@0 349 /* this is for adding non contractions */
michael@0 350 U_CAPI uint32_t U_EXPORT2
michael@0 351 uprv_cnttab_changeLastCE(CntTable *table, uint32_t element, uint32_t value, UErrorCode *status) {
michael@0 352 element &= 0xFFFFFF;
michael@0 353
michael@0 354 ContractionTable *tbl = NULL;
michael@0 355 if(U_FAILURE(*status)) {
michael@0 356 return 0;
michael@0 357 }
michael@0 358
michael@0 359 if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
michael@0 360 return 0;
michael@0 361 }
michael@0 362
michael@0 363 tbl->CEs[tbl->position-1] = value;
michael@0 364
michael@0 365 return(constructContractCE(table->currentTag, element));
michael@0 366 }
michael@0 367
michael@0 368
michael@0 369 /* 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 */
michael@0 370 U_CAPI uint32_t U_EXPORT2
michael@0 371 uprv_cnttab_insertContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t value, UErrorCode *status) {
michael@0 372
michael@0 373 ContractionTable *tbl = NULL;
michael@0 374
michael@0 375 if(U_FAILURE(*status)) {
michael@0 376 return 0;
michael@0 377 }
michael@0 378 element &= 0xFFFFFF;
michael@0 379
michael@0 380 if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
michael@0 381 tbl = addATableElement(table, &element, status);
michael@0 382 if (U_FAILURE(*status)) {
michael@0 383 return 0;
michael@0 384 }
michael@0 385 }
michael@0 386
michael@0 387 uprv_growTable(tbl, status);
michael@0 388
michael@0 389 uint32_t offset = 0;
michael@0 390
michael@0 391
michael@0 392 while(tbl->codePoints[offset] < codePoint && offset<tbl->position) {
michael@0 393 offset++;
michael@0 394 }
michael@0 395
michael@0 396 uint32_t i = tbl->position;
michael@0 397 for(i = tbl->position; i > offset; i--) {
michael@0 398 tbl->CEs[i] = tbl->CEs[i-1];
michael@0 399 tbl->codePoints[i] = tbl->codePoints[i-1];
michael@0 400 }
michael@0 401
michael@0 402 tbl->CEs[offset] = value;
michael@0 403 tbl->codePoints[offset] = codePoint;
michael@0 404
michael@0 405 tbl->position++;
michael@0 406
michael@0 407 return(constructContractCE(table->currentTag, element));
michael@0 408 }
michael@0 409
michael@0 410
michael@0 411 /* adds more contractions in table. If element is non existant, it creates on. Returns element handle */
michael@0 412 U_CAPI uint32_t U_EXPORT2
michael@0 413 uprv_cnttab_addContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t value, UErrorCode *status) {
michael@0 414
michael@0 415 element &= 0xFFFFFF;
michael@0 416
michael@0 417 ContractionTable *tbl = NULL;
michael@0 418
michael@0 419 if(U_FAILURE(*status)) {
michael@0 420 return 0;
michael@0 421 }
michael@0 422
michael@0 423 if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
michael@0 424 tbl = addATableElement(table, &element, status);
michael@0 425 if (U_FAILURE(*status)) {
michael@0 426 return 0;
michael@0 427 }
michael@0 428 }
michael@0 429
michael@0 430 uprv_growTable(tbl, status);
michael@0 431
michael@0 432 tbl->CEs[tbl->position] = value;
michael@0 433 tbl->codePoints[tbl->position] = codePoint;
michael@0 434
michael@0 435 tbl->position++;
michael@0 436
michael@0 437 return(constructContractCE(table->currentTag, element));
michael@0 438 }
michael@0 439
michael@0 440 /* sets a part of contraction sequence in table. If element is non existant, it creates on. Returns element handle */
michael@0 441 U_CAPI uint32_t U_EXPORT2
michael@0 442 uprv_cnttab_setContraction(CntTable *table, uint32_t element, uint32_t offset, UChar codePoint, uint32_t value, UErrorCode *status) {
michael@0 443
michael@0 444 element &= 0xFFFFFF;
michael@0 445 ContractionTable *tbl = NULL;
michael@0 446
michael@0 447 if(U_FAILURE(*status)) {
michael@0 448 return 0;
michael@0 449 }
michael@0 450
michael@0 451 if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
michael@0 452 tbl = addATableElement(table, &element, status);
michael@0 453 if (U_FAILURE(*status)) {
michael@0 454 return 0;
michael@0 455 }
michael@0 456
michael@0 457 }
michael@0 458
michael@0 459 if(offset >= tbl->size) {
michael@0 460 *status = U_INDEX_OUTOFBOUNDS_ERROR;
michael@0 461 return 0;
michael@0 462 }
michael@0 463 tbl->CEs[offset] = value;
michael@0 464 tbl->codePoints[offset] = codePoint;
michael@0 465
michael@0 466 //return(offset);
michael@0 467 return(constructContractCE(table->currentTag, element));
michael@0 468 }
michael@0 469
michael@0 470 static ContractionTable *_cnttab_getContractionTable(CntTable *table, uint32_t element) {
michael@0 471 element &= 0xFFFFFF;
michael@0 472 ContractionTable *tbl = NULL;
michael@0 473
michael@0 474 if(element != 0xFFFFFF) {
michael@0 475 tbl = table->elements[element]; /* This could also return NULL */
michael@0 476 }
michael@0 477 return tbl;
michael@0 478 }
michael@0 479
michael@0 480 static int32_t _cnttab_findCP(ContractionTable *tbl, UChar codePoint) {
michael@0 481 uint32_t position = 0;
michael@0 482 if(tbl == NULL) {
michael@0 483 return -1;
michael@0 484 }
michael@0 485
michael@0 486 while(codePoint > tbl->codePoints[position]) {
michael@0 487 position++;
michael@0 488 if(position > tbl->position) {
michael@0 489 return -1;
michael@0 490 }
michael@0 491 }
michael@0 492 if (codePoint == tbl->codePoints[position]) {
michael@0 493 return position;
michael@0 494 } else {
michael@0 495 return -1;
michael@0 496 }
michael@0 497 }
michael@0 498
michael@0 499 static uint32_t _cnttab_getCE(ContractionTable *tbl, int32_t position) {
michael@0 500 if(tbl == NULL) {
michael@0 501 return UCOL_NOT_FOUND;
michael@0 502 }
michael@0 503 if((uint32_t)position > tbl->position || position == -1) {
michael@0 504 return UCOL_NOT_FOUND;
michael@0 505 } else {
michael@0 506 return tbl->CEs[position];
michael@0 507 }
michael@0 508 }
michael@0 509
michael@0 510 U_CAPI int32_t U_EXPORT2
michael@0 511 uprv_cnttab_findCP(CntTable *table, uint32_t element, UChar codePoint, UErrorCode *status) {
michael@0 512
michael@0 513 if(U_FAILURE(*status)) {
michael@0 514 return 0;
michael@0 515 }
michael@0 516
michael@0 517 return _cnttab_findCP(_cnttab_getContractionTable(table, element), codePoint);
michael@0 518 }
michael@0 519
michael@0 520 U_CAPI uint32_t U_EXPORT2
michael@0 521 uprv_cnttab_getCE(CntTable *table, uint32_t element, uint32_t position, UErrorCode *status) {
michael@0 522 if(U_FAILURE(*status)) {
michael@0 523 return UCOL_NOT_FOUND;
michael@0 524 }
michael@0 525
michael@0 526 return(_cnttab_getCE(_cnttab_getContractionTable(table, element), position));
michael@0 527 }
michael@0 528
michael@0 529 U_CAPI uint32_t U_EXPORT2
michael@0 530 uprv_cnttab_findCE(CntTable *table, uint32_t element, UChar codePoint, UErrorCode *status) {
michael@0 531 if(U_FAILURE(*status)) {
michael@0 532 return UCOL_NOT_FOUND;
michael@0 533 }
michael@0 534 ContractionTable *tbl = _cnttab_getContractionTable(table, element);
michael@0 535 return _cnttab_getCE(tbl, _cnttab_findCP(tbl, codePoint));
michael@0 536 }
michael@0 537
michael@0 538 U_CAPI UBool U_EXPORT2
michael@0 539 uprv_cnttab_isTailored(CntTable *table, uint32_t element, UChar *ztString, UErrorCode *status) {
michael@0 540 if(U_FAILURE(*status)) {
michael@0 541 return FALSE;
michael@0 542 }
michael@0 543
michael@0 544 while(*(ztString)!=0) {
michael@0 545 element = uprv_cnttab_findCE(table, element, *(ztString), status);
michael@0 546 if(element == UCOL_NOT_FOUND) {
michael@0 547 return FALSE;
michael@0 548 }
michael@0 549 if(!isCntTableElement(element)) {
michael@0 550 return TRUE;
michael@0 551 }
michael@0 552 ztString++;
michael@0 553 }
michael@0 554 return (UBool)(uprv_cnttab_getCE(table, element, 0, status) != UCOL_NOT_FOUND);
michael@0 555 }
michael@0 556
michael@0 557 U_CAPI uint32_t U_EXPORT2
michael@0 558 uprv_cnttab_changeContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t newCE, UErrorCode *status) {
michael@0 559
michael@0 560 element &= 0xFFFFFF;
michael@0 561 ContractionTable *tbl = NULL;
michael@0 562
michael@0 563 if(U_FAILURE(*status)) {
michael@0 564 return 0;
michael@0 565 }
michael@0 566
michael@0 567 if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) {
michael@0 568 return 0;
michael@0 569 }
michael@0 570
michael@0 571 uint32_t position = 0;
michael@0 572
michael@0 573 while(codePoint > tbl->codePoints[position]) {
michael@0 574 position++;
michael@0 575 if(position > tbl->position) {
michael@0 576 return UCOL_NOT_FOUND;
michael@0 577 }
michael@0 578 }
michael@0 579 if (codePoint == tbl->codePoints[position]) {
michael@0 580 tbl->CEs[position] = newCE;
michael@0 581 return element;
michael@0 582 } else {
michael@0 583 return UCOL_NOT_FOUND;
michael@0 584 }
michael@0 585 }
michael@0 586
michael@0 587 #endif /* #if !UCONFIG_NO_COLLATION */

mercurial