/*
*******************************************************************************
*
-* Copyright (C) 2001-2004, International Business Machines
+* Copyright (C) 2001-2012, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
#include "unicode/unistr.h"
#include "unicode/ucoleitr.h"
#include "unicode/normlzr.h"
+#include "unicode/utf16.h"
+#include "normalizer2impl.h"
#include "ucol_elm.h"
-#include "unormimp.h"
+#include "ucol_tok.h"
+#include "ucol_cnt.h"
#include "unicode/caniter.h"
#include "cmemory.h"
+#include "uassert.h"
-U_NAMESPACE_BEGIN
+U_NAMESPACE_USE
static uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements *element, uint32_t existingCE, UErrorCode *status);
U_CDECL_BEGIN
-static int32_t U_EXPORT2 U_CALLCONV
+static int32_t U_CALLCONV
prefixLookupHash(const UHashTok e) {
- UCAElements *element = (UCAElements *)e.pointer;
- UChar buf[256];
- UHashTok key;
- key.pointer = buf;
- uprv_memcpy(buf, element->cPoints, element->cSize*sizeof(UChar));
- buf[element->cSize] = 0;
- //key.pointer = element->cPoints;
- //element->cPoints[element->cSize] = 0;
- return uhash_hashUChars(key);
+ UCAElements *element = (UCAElements *)e.pointer;
+ UChar buf[256];
+ UHashTok key;
+ key.pointer = buf;
+ uprv_memcpy(buf, element->cPoints, element->cSize*sizeof(UChar));
+ buf[element->cSize] = 0;
+ //key.pointer = element->cPoints;
+ //element->cPoints[element->cSize] = 0;
+ return uhash_hashUChars(key);
}
-static int8_t U_EXPORT2 U_CALLCONV
+static int8_t U_CALLCONV
prefixLookupComp(const UHashTok e1, const UHashTok e2) {
- UCAElements *element1 = (UCAElements *)e1.pointer;
- UCAElements *element2 = (UCAElements *)e2.pointer;
-
- UChar buf1[256];
- UHashTok key1;
- key1.pointer = buf1;
- uprv_memcpy(buf1, element1->cPoints, element1->cSize*sizeof(UChar));
- buf1[element1->cSize] = 0;
-
- UChar buf2[256];
- UHashTok key2;
- key2.pointer = buf2;
- uprv_memcpy(buf2, element2->cPoints, element2->cSize*sizeof(UChar));
- buf2[element2->cSize] = 0;
-
- return uhash_compareUChars(key1, key2);
+ UCAElements *element1 = (UCAElements *)e1.pointer;
+ UCAElements *element2 = (UCAElements *)e2.pointer;
+
+ UChar buf1[256];
+ UHashTok key1;
+ key1.pointer = buf1;
+ uprv_memcpy(buf1, element1->cPoints, element1->cSize*sizeof(UChar));
+ buf1[element1->cSize] = 0;
+
+ UChar buf2[256];
+ UHashTok key2;
+ key2.pointer = buf2;
+ uprv_memcpy(buf2, element2->cPoints, element2->cSize*sizeof(UChar));
+ buf2[element2->cSize] = 0;
+
+ return uhash_compareUChars(key1, key2);
}
U_CDECL_END
U_CAPI tempUCATable* U_EXPORT2
uprv_uca_initTempTable(UCATableHeader *image, UColOptionSet *opts, const UCollator *UCA, UColCETags initTag, UColCETags supplementaryInitTag, UErrorCode *status) {
- tempUCATable *t = (tempUCATable *)uprv_malloc(sizeof(tempUCATable));
- /* test for NULL */
- if (t == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- MaxExpansionTable *maxet = (MaxExpansionTable *)uprv_malloc(
- sizeof(MaxExpansionTable));
- /* test for NULL */
- if (maxet == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- uprv_free(t);
- return NULL;
- }
- MaxJamoExpansionTable *maxjet = (MaxJamoExpansionTable *)uprv_malloc(
- sizeof(MaxJamoExpansionTable));
- /* test for NULL */
- if (maxjet == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- uprv_free(t);
- uprv_free(maxet);
- return NULL;
- }
- t->image = image;
- t->options = opts;
-
- t->UCA = UCA;
- t->expansions = (ExpansionTable *)uprv_malloc(sizeof(ExpansionTable));
- /* test for NULL */
- if (t->expansions == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- uprv_free(t);
- uprv_free(maxet);
- uprv_free(maxjet);
- return NULL;
- }
- uprv_memset(t->expansions, 0, sizeof(ExpansionTable));
- /*t->mapping = ucmpe32_open(UCOL_SPECIAL_FLAG | (initTag<<24), UCOL_SPECIAL_FLAG | (SURROGATE_TAG<<24), UCOL_SPECIAL_FLAG | (LEAD_SURROGATE_TAG<<24), status);*/
- /*t->mapping = utrie_open(NULL, NULL, 0x100000, UCOL_SPECIAL_FLAG | (initTag<<24), TRUE); // Do your own mallocs for the structure, array and have linear Latin 1*/
-
- t->mapping = utrie_open(NULL, NULL, 0x100000,
- UCOL_SPECIAL_FLAG | (initTag<<24),
- UCOL_SPECIAL_FLAG | (supplementaryInitTag << 24),
- TRUE); // Do your own mallocs for the structure, array and have linear Latin 1
- t->prefixLookup = uhash_open(prefixLookupHash, prefixLookupComp, status);
- uhash_setValueDeleter(t->prefixLookup, uhash_freeBlock);
-
- t->contractions = uprv_cnttab_open(t->mapping, status);
-
- /* copy UCA's maxexpansion and merge as we go along */
- t->maxExpansions = maxet;
- if (UCA != NULL) {
- /* adding an extra initial value for easier manipulation */
- maxet->size = (UCA->lastEndExpansionCE - UCA->endExpansionCE)
- + 2;
- maxet->position = maxet->size - 1;
- maxet->endExpansionCE =
- (uint32_t *)uprv_malloc(sizeof(uint32_t) * maxet->size);
+ MaxJamoExpansionTable *maxjet;
+ MaxExpansionTable *maxet;
+ tempUCATable *t = (tempUCATable *)uprv_malloc(sizeof(tempUCATable));
/* test for NULL */
- if (maxet->endExpansionCE == NULL) {
+ if (t == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
- maxet->expansionCESize =
- (uint8_t *)uprv_malloc(sizeof(uint8_t) * maxet->size);
- /* test for NULL */
- if (maxet->expansionCESize == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- uprv_free(maxet->endExpansionCE);
- return NULL;
+ uprv_memset(t, 0, sizeof(tempUCATable));
+
+ maxet = (MaxExpansionTable *)uprv_malloc(sizeof(MaxExpansionTable));
+ if (maxet == NULL) {
+ goto allocation_failure;
}
- /* initialized value */
- *(maxet->endExpansionCE) = 0;
- *(maxet->expansionCESize) = 0;
- uprv_memcpy(maxet->endExpansionCE + 1, UCA->endExpansionCE,
- sizeof(uint32_t) * (maxet->size - 1));
- uprv_memcpy(maxet->expansionCESize + 1, UCA->expansionCESize,
- sizeof(uint8_t) * (maxet->size - 1));
- }
- else {
- maxet->size = 0;
- }
- t->maxJamoExpansions = maxjet;
- maxjet->endExpansionCE = NULL;
- maxjet->isV = NULL;
- maxjet->size = 0;
- maxjet->position = 0;
- maxjet->maxLSize = 1;
- maxjet->maxVSize = 1;
- maxjet->maxTSize = 1;
-
- t->unsafeCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
- /* test for NULL */
- if (t->unsafeCP == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- t->contrEndCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
- /* test for NULL */
- if (t->contrEndCP == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- uprv_free(t->unsafeCP);
- return NULL;
- }
- uprv_memset(t->unsafeCP, 0, UCOL_UNSAFECP_TABLE_SIZE);
- uprv_memset(t->contrEndCP, 0, UCOL_UNSAFECP_TABLE_SIZE);
-return t;
-}
+ uprv_memset(maxet, 0, sizeof(MaxExpansionTable));
+ t->maxExpansions = maxet;
-U_CAPI tempUCATable* U_EXPORT2
-uprv_uca_cloneTempTable(tempUCATable *t, UErrorCode *status) {
- if(U_FAILURE(*status)) {
- return NULL;
- }
+ maxjet = (MaxJamoExpansionTable *)uprv_malloc(sizeof(MaxJamoExpansionTable));
+ if (maxjet == NULL) {
+ goto allocation_failure;
+ }
+ uprv_memset(maxjet, 0, sizeof(MaxJamoExpansionTable));
+ t->maxJamoExpansions = maxjet;
- tempUCATable *r = (tempUCATable *)uprv_malloc(sizeof(tempUCATable));
- /* test for NULL */
- if (r == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uprv_memset(r, 0, sizeof(tempUCATable));
-
- /* mapping */
- if(t->mapping != NULL) {
- /*r->mapping = ucmpe32_clone(t->mapping, status);*/
- r->mapping = utrie_clone(NULL, t->mapping, NULL, 0);
- }
-
- // a hashing clone function would be very nice. We have none currently...
- // However, we should be good, as closing should not produce any prefixed elements.
- r->prefixLookup = NULL; // prefixes are not used in closing
-
- /* expansions */
- if(t->expansions != NULL) {
- r->expansions = (ExpansionTable *)uprv_malloc(sizeof(ExpansionTable));
+ t->image = image;
+ t->options = opts;
+
+ t->UCA = UCA;
+ t->expansions = (ExpansionTable *)uprv_malloc(sizeof(ExpansionTable));
/* test for NULL */
- if (r->expansions == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ if (t->expansions == NULL) {
+ goto allocation_failure;
}
- r->expansions->position = t->expansions->position;
- r->expansions->size = t->expansions->size;
- if(t->expansions->CEs != NULL) {
- r->expansions->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->expansions->size);
- /* test for NULL */
- if (r->expansions->CEs == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uprv_memcpy(r->expansions->CEs, t->expansions->CEs, sizeof(uint32_t)*t->expansions->position);
- } else {
- r->expansions->CEs = NULL;
+ uprv_memset(t->expansions, 0, sizeof(ExpansionTable));
+
+ t->mapping = utrie_open(NULL, NULL, UCOL_ELM_TRIE_CAPACITY,
+ UCOL_SPECIAL_FLAG | (initTag<<24),
+ UCOL_SPECIAL_FLAG | (supplementaryInitTag << 24),
+ TRUE); // Do your own mallocs for the structure, array and have linear Latin 1
+ if (U_FAILURE(*status)) {
+ goto allocation_failure;
+ }
+ t->prefixLookup = uhash_open(prefixLookupHash, prefixLookupComp, NULL, status);
+ if (U_FAILURE(*status)) {
+ goto allocation_failure;
}
- }
+ uhash_setValueDeleter(t->prefixLookup, uprv_free);
- if(t->contractions != NULL) {
- r->contractions = uprv_cnttab_clone(t->contractions, status);
- r->contractions->mapping = r->mapping;
- }
+ t->contractions = uprv_cnttab_open(t->mapping, status);
+ if (U_FAILURE(*status)) {
+ goto cleanup;
+ }
- if(t->maxExpansions != NULL) {
- r->maxExpansions = (MaxExpansionTable *)uprv_malloc(sizeof(MaxExpansionTable));
- /* test for NULL */
- if (r->maxExpansions == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ /* copy UCA's maxexpansion and merge as we go along */
+ if (UCA != NULL) {
+ /* adding an extra initial value for easier manipulation */
+ maxet->size = (int32_t)(UCA->lastEndExpansionCE - UCA->endExpansionCE) + 2;
+ maxet->position = maxet->size - 1;
+ maxet->endExpansionCE =
+ (uint32_t *)uprv_malloc(sizeof(uint32_t) * maxet->size);
+ /* test for NULL */
+ if (maxet->endExpansionCE == NULL) {
+ goto allocation_failure;
+ }
+ maxet->expansionCESize =
+ (uint8_t *)uprv_malloc(sizeof(uint8_t) * maxet->size);
+ /* test for NULL */
+ if (maxet->expansionCESize == NULL) {
+ goto allocation_failure;
+ }
+ /* initialized value */
+ *(maxet->endExpansionCE) = 0;
+ *(maxet->expansionCESize) = 0;
+ uprv_memcpy(maxet->endExpansionCE + 1, UCA->endExpansionCE,
+ sizeof(uint32_t) * (maxet->size - 1));
+ uprv_memcpy(maxet->expansionCESize + 1, UCA->expansionCESize,
+ sizeof(uint8_t) * (maxet->size - 1));
}
- r->maxExpansions->size = t->maxExpansions->size;
- r->maxExpansions->position = t->maxExpansions->position;
- if(t->maxExpansions->endExpansionCE != NULL) {
- r->maxExpansions->endExpansionCE = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->maxExpansions->size);
- /* test for NULL */
- if (r->maxExpansions->endExpansionCE == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uprv_memcpy(r->maxExpansions->endExpansionCE, t->maxExpansions->endExpansionCE, t->maxExpansions->position*sizeof(uint32_t));
- } else {
- r->maxExpansions->endExpansionCE = NULL;
- }
- if(t->maxExpansions->expansionCESize != NULL) {
- r->maxExpansions->expansionCESize = (uint8_t *)uprv_malloc(sizeof(uint8_t)*t->maxExpansions->size);
- /* test for NULL */
- if (r->maxExpansions->expansionCESize == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uprv_memcpy(r->maxExpansions->expansionCESize, t->maxExpansions->expansionCESize, t->maxExpansions->position*sizeof(uint8_t));
- } else {
- r->maxExpansions->expansionCESize = NULL;
+ else {
+ maxet->size = 0;
}
- }
-
- if(t->maxJamoExpansions != NULL) {
- r->maxJamoExpansions = (MaxJamoExpansionTable *)uprv_malloc(sizeof(MaxJamoExpansionTable));
+ maxjet->endExpansionCE = NULL;
+ maxjet->isV = NULL;
+ maxjet->size = 0;
+ maxjet->position = 0;
+ maxjet->maxLSize = 1;
+ maxjet->maxVSize = 1;
+ maxjet->maxTSize = 1;
+
+ t->unsafeCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
/* test for NULL */
- if (r->maxJamoExpansions == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
+ if (t->unsafeCP == NULL) {
+ goto allocation_failure;
}
- r->maxJamoExpansions->size = t->maxJamoExpansions->size;
- r->maxJamoExpansions->position = t->maxJamoExpansions->position;
- r->maxJamoExpansions->maxLSize = t->maxJamoExpansions->maxLSize;
- r->maxJamoExpansions->maxVSize = t->maxJamoExpansions->maxVSize;
- r->maxJamoExpansions->maxTSize = t->maxJamoExpansions->maxTSize;
- if(t->maxJamoExpansions->size != 0) {
- r->maxJamoExpansions->endExpansionCE = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->maxJamoExpansions->size);
- /* test for NULL */
- if (r->maxJamoExpansions->endExpansionCE == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uprv_memcpy(r->maxJamoExpansions->endExpansionCE, t->maxJamoExpansions->endExpansionCE, t->maxJamoExpansions->position*sizeof(uint32_t));
- r->maxJamoExpansions->isV = (UBool *)uprv_malloc(sizeof(UBool)*t->maxJamoExpansions->size);
- /* test for NULL */
- if (r->maxJamoExpansions->isV == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return NULL;
- }
- uprv_memcpy(r->maxJamoExpansions->isV, t->maxJamoExpansions->isV, t->maxJamoExpansions->position*sizeof(UBool));
- } else {
- r->maxJamoExpansions->endExpansionCE = NULL;
- r->maxJamoExpansions->isV = NULL;
+ t->contrEndCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
+ /* test for NULL */
+ if (t->contrEndCP == NULL) {
+ goto allocation_failure;
}
- }
+ uprv_memset(t->unsafeCP, 0, UCOL_UNSAFECP_TABLE_SIZE);
+ uprv_memset(t->contrEndCP, 0, UCOL_UNSAFECP_TABLE_SIZE);
+ t->cmLookup = NULL;
+ return t;
- if(t->unsafeCP != NULL) {
- r->unsafeCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
- /* test for NULL */
- if (r->unsafeCP == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
+allocation_failure:
+ *status = U_MEMORY_ALLOCATION_ERROR;
+cleanup:
+ uprv_uca_closeTempTable(t);
+ return NULL;
+}
+
+static tempUCATable* U_EXPORT2
+uprv_uca_cloneTempTable(tempUCATable *t, UErrorCode *status) {
+ if(U_FAILURE(*status)) {
return NULL;
}
- uprv_memcpy(r->unsafeCP, t->unsafeCP, UCOL_UNSAFECP_TABLE_SIZE);
- }
- if(t->contrEndCP != NULL) {
- r->contrEndCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
+ tempUCATable *r = (tempUCATable *)uprv_malloc(sizeof(tempUCATable));
/* test for NULL */
- if (r->contrEndCP == NULL) {
+ if (r == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return NULL;
}
- uprv_memcpy(r->contrEndCP, t->contrEndCP, UCOL_UNSAFECP_TABLE_SIZE);
- }
+ uprv_memset(r, 0, sizeof(tempUCATable));
- r->UCA = t->UCA;
- r->image = t->image;
- r->options = t->options;
+ /* mapping */
+ if(t->mapping != NULL) {
+ /*r->mapping = ucmpe32_clone(t->mapping, status);*/
+ r->mapping = utrie_clone(NULL, t->mapping, NULL, 0);
+ }
- return r;
-}
+ // a hashing clone function would be very nice. We have none currently...
+ // However, we should be good, as closing should not produce any prefixed elements.
+ r->prefixLookup = NULL; // prefixes are not used in closing
+ /* expansions */
+ if(t->expansions != NULL) {
+ r->expansions = (ExpansionTable *)uprv_malloc(sizeof(ExpansionTable));
+ /* test for NULL */
+ if (r->expansions == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ r->expansions->position = t->expansions->position;
+ r->expansions->size = t->expansions->size;
+ if(t->expansions->CEs != NULL) {
+ r->expansions->CEs = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->expansions->size);
+ /* test for NULL */
+ if (r->expansions->CEs == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memcpy(r->expansions->CEs, t->expansions->CEs, sizeof(uint32_t)*t->expansions->position);
+ } else {
+ r->expansions->CEs = NULL;
+ }
+ }
-U_CAPI void U_EXPORT2
-uprv_uca_closeTempTable(tempUCATable *t) {
- if(t != NULL) {
- uprv_free(t->expansions->CEs);
- uprv_free(t->expansions);
if(t->contractions != NULL) {
- uprv_cnttab_close(t->contractions);
+ r->contractions = uprv_cnttab_clone(t->contractions, status);
+ // Check for cloning failure.
+ if (r->contractions == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ r->contractions->mapping = r->mapping;
}
- /*ucmpe32_close(t->mapping);*/
- utrie_close(t->mapping);
- if(t->prefixLookup != NULL) {
- uhash_close(t->prefixLookup);
+ if(t->maxExpansions != NULL) {
+ r->maxExpansions = (MaxExpansionTable *)uprv_malloc(sizeof(MaxExpansionTable));
+ /* test for NULL */
+ if (r->maxExpansions == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ r->maxExpansions->size = t->maxExpansions->size;
+ r->maxExpansions->position = t->maxExpansions->position;
+ if(t->maxExpansions->endExpansionCE != NULL) {
+ r->maxExpansions->endExpansionCE = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->maxExpansions->size);
+ /* test for NULL */
+ if (r->maxExpansions->endExpansionCE == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memset(r->maxExpansions->endExpansionCE, 0xDB, sizeof(uint32_t)*t->maxExpansions->size);
+ uprv_memcpy(r->maxExpansions->endExpansionCE, t->maxExpansions->endExpansionCE, t->maxExpansions->position*sizeof(uint32_t));
+ } else {
+ r->maxExpansions->endExpansionCE = NULL;
+ }
+ if(t->maxExpansions->expansionCESize != NULL) {
+ r->maxExpansions->expansionCESize = (uint8_t *)uprv_malloc(sizeof(uint8_t)*t->maxExpansions->size);
+ /* test for NULL */
+ if (r->maxExpansions->expansionCESize == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memset(r->maxExpansions->expansionCESize, 0xDB, sizeof(uint8_t)*t->maxExpansions->size);
+ uprv_memcpy(r->maxExpansions->expansionCESize, t->maxExpansions->expansionCESize, t->maxExpansions->position*sizeof(uint8_t));
+ } else {
+ r->maxExpansions->expansionCESize = NULL;
+ }
}
- uprv_free(t->maxExpansions->endExpansionCE);
- uprv_free(t->maxExpansions->expansionCESize);
- uprv_free(t->maxExpansions);
+ if(t->maxJamoExpansions != NULL) {
+ r->maxJamoExpansions = (MaxJamoExpansionTable *)uprv_malloc(sizeof(MaxJamoExpansionTable));
+ /* test for NULL */
+ if (r->maxJamoExpansions == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ r->maxJamoExpansions->size = t->maxJamoExpansions->size;
+ r->maxJamoExpansions->position = t->maxJamoExpansions->position;
+ r->maxJamoExpansions->maxLSize = t->maxJamoExpansions->maxLSize;
+ r->maxJamoExpansions->maxVSize = t->maxJamoExpansions->maxVSize;
+ r->maxJamoExpansions->maxTSize = t->maxJamoExpansions->maxTSize;
+ if(t->maxJamoExpansions->size != 0) {
+ r->maxJamoExpansions->endExpansionCE = (uint32_t *)uprv_malloc(sizeof(uint32_t)*t->maxJamoExpansions->size);
+ /* test for NULL */
+ if (r->maxJamoExpansions->endExpansionCE == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memcpy(r->maxJamoExpansions->endExpansionCE, t->maxJamoExpansions->endExpansionCE, t->maxJamoExpansions->position*sizeof(uint32_t));
+ r->maxJamoExpansions->isV = (UBool *)uprv_malloc(sizeof(UBool)*t->maxJamoExpansions->size);
+ /* test for NULL */
+ if (r->maxJamoExpansions->isV == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memcpy(r->maxJamoExpansions->isV, t->maxJamoExpansions->isV, t->maxJamoExpansions->position*sizeof(UBool));
+ } else {
+ r->maxJamoExpansions->endExpansionCE = NULL;
+ r->maxJamoExpansions->isV = NULL;
+ }
+ }
- if (t->maxJamoExpansions->size > 0) {
- uprv_free(t->maxJamoExpansions->endExpansionCE);
- uprv_free(t->maxJamoExpansions->isV);
+ if(t->unsafeCP != NULL) {
+ r->unsafeCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
+ /* test for NULL */
+ if (r->unsafeCP == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memcpy(r->unsafeCP, t->unsafeCP, UCOL_UNSAFECP_TABLE_SIZE);
+ }
+
+ if(t->contrEndCP != NULL) {
+ r->contrEndCP = (uint8_t *)uprv_malloc(UCOL_UNSAFECP_TABLE_SIZE);
+ /* test for NULL */
+ if (r->contrEndCP == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ goto cleanup;
+ }
+ uprv_memcpy(r->contrEndCP, t->contrEndCP, UCOL_UNSAFECP_TABLE_SIZE);
}
- uprv_free(t->maxJamoExpansions);
- uprv_free(t->unsafeCP);
- uprv_free(t->contrEndCP);
+ r->UCA = t->UCA;
+ r->image = t->image;
+ r->options = t->options;
- uprv_free(t);
- }
+ return r;
+cleanup:
+ uprv_uca_closeTempTable(t);
+ return NULL;
+}
+
+
+U_CAPI void U_EXPORT2
+uprv_uca_closeTempTable(tempUCATable *t) {
+ if(t != NULL) {
+ if (t->expansions != NULL) {
+ uprv_free(t->expansions->CEs);
+ uprv_free(t->expansions);
+ }
+ if(t->contractions != NULL) {
+ uprv_cnttab_close(t->contractions);
+ }
+ if (t->mapping != NULL) {
+ utrie_close(t->mapping);
+ }
+
+ if(t->prefixLookup != NULL) {
+ uhash_close(t->prefixLookup);
+ }
+
+ if (t->maxExpansions != NULL) {
+ uprv_free(t->maxExpansions->endExpansionCE);
+ uprv_free(t->maxExpansions->expansionCESize);
+ uprv_free(t->maxExpansions);
+ }
+
+ if (t->maxJamoExpansions->size > 0) {
+ uprv_free(t->maxJamoExpansions->endExpansionCE);
+ uprv_free(t->maxJamoExpansions->isV);
+ }
+ uprv_free(t->maxJamoExpansions);
+
+ uprv_free(t->unsafeCP);
+ uprv_free(t->contrEndCP);
+
+ if (t->cmLookup != NULL) {
+ uprv_free(t->cmLookup->cPoints);
+ uprv_free(t->cmLookup);
+ }
+
+ uprv_free(t);
+ }
}
/**
* @returns size of the maxexpansion and maxsize used.
*/
static int uprv_uca_setMaxExpansion(uint32_t endexpansion,
- uint8_t expansionsize,
- MaxExpansionTable *maxexpansion,
- UErrorCode *status)
+ uint8_t expansionsize,
+ MaxExpansionTable *maxexpansion,
+ UErrorCode *status)
{
- if (maxexpansion->size == 0) {
- /* we'll always make the first element 0, for easier manipulation */
- maxexpansion->endExpansionCE =
- (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(int32_t));
- /* test for NULL */
- if (maxexpansion->endExpansionCE == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
+ if (maxexpansion->size == 0) {
+ /* we'll always make the first element 0, for easier manipulation */
+ maxexpansion->endExpansionCE =
+ (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(int32_t));
+ /* test for NULL */
+ if (maxexpansion->endExpansionCE == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ *(maxexpansion->endExpansionCE) = 0;
+ maxexpansion->expansionCESize =
+ (uint8_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(uint8_t));
+ /* test for NULL */;
+ if (maxexpansion->expansionCESize == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ *(maxexpansion->expansionCESize) = 0;
+ maxexpansion->size = INIT_EXP_TABLE_SIZE;
+ maxexpansion->position = 0;
}
- *(maxexpansion->endExpansionCE) = 0;
- maxexpansion->expansionCESize =
- (uint8_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(uint8_t));
- /* test for NULL */;
- if (maxexpansion->expansionCESize == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
+
+ if (maxexpansion->position + 1 == maxexpansion->size) {
+ uint32_t *neweece = (uint32_t *)uprv_realloc(maxexpansion->endExpansionCE,
+ 2 * maxexpansion->size * sizeof(uint32_t));
+ if (neweece == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ maxexpansion->endExpansionCE = neweece;
+
+ uint8_t *neweces = (uint8_t *)uprv_realloc(maxexpansion->expansionCESize,
+ 2 * maxexpansion->size * sizeof(uint8_t));
+ if (neweces == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ maxexpansion->expansionCESize = neweces;
+ maxexpansion->size *= 2;
}
- *(maxexpansion->expansionCESize) = 0;
- maxexpansion->size = INIT_EXP_TABLE_SIZE;
- maxexpansion->position = 0;
- }
-
- if (maxexpansion->position + 1 == maxexpansion->size) {
- uint32_t *neweece = (uint32_t *)uprv_realloc(maxexpansion->endExpansionCE,
- 2 * maxexpansion->size * sizeof(uint32_t));
- uint8_t *neweces = (uint8_t *)uprv_realloc(maxexpansion->expansionCESize,
- 2 * maxexpansion->size * sizeof(uint8_t));
- if (neweece == NULL || neweces == NULL) {
-#ifdef UCOL_DEBUG
- fprintf(stderr, "out of memory for maxExpansions\n");
-#endif
- *status = U_MEMORY_ALLOCATION_ERROR;
- return -1;
- }
- maxexpansion->endExpansionCE = neweece;
- maxexpansion->expansionCESize = neweces;
- maxexpansion->size *= 2;
- }
-
- uint32_t *pendexpansionce = maxexpansion->endExpansionCE;
- uint8_t *pexpansionsize = maxexpansion->expansionCESize;
- int pos = maxexpansion->position;
-
- uint32_t *start = pendexpansionce;
- uint32_t *limit = pendexpansionce + pos;
-
- /* using binary search to determine if last expansion element is
- already in the array */
- uint32_t *mid;
- int result = -1;
- while (start < limit - 1) {
- mid = start + ((limit - start) >> 1);
- if (endexpansion <= *mid) {
- limit = mid;
- }
- else {
- start = mid;
- }
- }
-
- if (*start == endexpansion) {
- result = start - pendexpansionce;
- }
- else
- if (*limit == endexpansion) {
- result = limit - pendexpansionce;
- }
-
- if (result > -1) {
- /* found the ce in expansion, we'll just modify the size if it is
- smaller */
- uint8_t *currentsize = pexpansionsize + result;
- if (*currentsize < expansionsize) {
- *currentsize = expansionsize;
- }
- }
- else {
- /* we'll need to squeeze the value into the array.
- initial implementation. */
- /* shifting the subarray down by 1 */
- int shiftsize = (pendexpansionce + pos) - start;
- uint32_t *shiftpos = start + 1;
- uint8_t *sizeshiftpos = pexpansionsize + (shiftpos - pendexpansionce);
-
- /* okay need to rearrange the array into sorted order */
- if (shiftsize == 0 /*|| *(pendexpansionce + pos) < endexpansion*/) { /* the commented part is actually both redundant and dangerous */
- *(pendexpansionce + pos + 1) = endexpansion;
- *(pexpansionsize + pos + 1) = expansionsize;
+
+ uint32_t *pendexpansionce = maxexpansion->endExpansionCE;
+ uint8_t *pexpansionsize = maxexpansion->expansionCESize;
+ int pos = maxexpansion->position;
+
+ uint32_t *start = pendexpansionce;
+ uint32_t *limit = pendexpansionce + pos;
+
+ /* using binary search to determine if last expansion element is
+ already in the array */
+ uint32_t *mid;
+ int result = -1;
+ while (start < limit - 1) {
+ mid = start + ((limit - start) >> 1);
+ if (endexpansion <= *mid) {
+ limit = mid;
+ }
+ else {
+ start = mid;
+ }
}
- else {
- uprv_memmove(shiftpos + 1, shiftpos, shiftsize * sizeof(int32_t));
- uprv_memmove(sizeshiftpos + 1, sizeshiftpos,
- shiftsize * sizeof(uint8_t));
- *shiftpos = endexpansion;
- *sizeshiftpos = expansionsize;
+
+ if (*start == endexpansion) {
+ result = (int)(start - pendexpansionce);
+ }
+ else if (*limit == endexpansion) {
+ result = (int)(limit - pendexpansionce);
}
- maxexpansion->position ++;
+
+ if (result > -1) {
+ /* found the ce in expansion, we'll just modify the size if it is
+ smaller */
+ uint8_t *currentsize = pexpansionsize + result;
+ if (*currentsize < expansionsize) {
+ *currentsize = expansionsize;
+ }
+ }
+ else {
+ /* we'll need to squeeze the value into the array.
+ initial implementation. */
+ /* shifting the subarray down by 1 */
+ int shiftsize = (int)((pendexpansionce + pos) - start);
+ uint32_t *shiftpos = start + 1;
+ uint8_t *sizeshiftpos = pexpansionsize + (shiftpos - pendexpansionce);
+
+ /* okay need to rearrange the array into sorted order */
+ if (shiftsize == 0 /*|| *(pendexpansionce + pos) < endexpansion*/) { /* the commented part is actually both redundant and dangerous */
+ *(pendexpansionce + pos + 1) = endexpansion;
+ *(pexpansionsize + pos + 1) = expansionsize;
+ }
+ else {
+ uprv_memmove(shiftpos + 1, shiftpos, shiftsize * sizeof(int32_t));
+ uprv_memmove(sizeshiftpos + 1, sizeshiftpos,
+ shiftsize * sizeof(uint8_t));
+ *shiftpos = endexpansion;
+ *sizeshiftpos = expansionsize;
+ }
+ maxexpansion->position ++;
#ifdef UCOL_DEBUG
- int temp;
- UBool found = FALSE;
- for (temp = 0; temp < maxexpansion->position; temp ++) {
- if (pendexpansionce[temp] >= pendexpansionce[temp + 1]) {
- fprintf(stderr, "expansions %d\n", temp);
- }
- if (pendexpansionce[temp] == endexpansion) {
- found =TRUE;
- if (pexpansionsize[temp] < expansionsize) {
- fprintf(stderr, "expansions size %d\n", temp);
- }
- }
- }
- if (pendexpansionce[temp] == endexpansion) {
- found =TRUE;
- if (pexpansionsize[temp] < expansionsize) {
- fprintf(stderr, "expansions size %d\n", temp);
- }
- }
- if (!found)
- fprintf(stderr, "expansion not found %d\n", temp);
+ int temp;
+ UBool found = FALSE;
+ for (temp = 0; temp < maxexpansion->position; temp ++) {
+ if (pendexpansionce[temp] >= pendexpansionce[temp + 1]) {
+ fprintf(stderr, "expansions %d\n", temp);
+ }
+ if (pendexpansionce[temp] == endexpansion) {
+ found =TRUE;
+ if (pexpansionsize[temp] < expansionsize) {
+ fprintf(stderr, "expansions size %d\n", temp);
+ }
+ }
+ }
+ if (pendexpansionce[temp] == endexpansion) {
+ found =TRUE;
+ if (pexpansionsize[temp] < expansionsize) {
+ fprintf(stderr, "expansions size %d\n", temp);
+ }
+ }
+ if (!found)
+ fprintf(stderr, "expansion not found %d\n", temp);
#endif
- }
+ }
- return maxexpansion->position;
+ return maxexpansion->position;
}
/**
* @returns size of the maxexpansion and maxsize used.
*/
static int uprv_uca_setMaxJamoExpansion(UChar ch,
- uint32_t endexpansion,
- uint8_t expansionsize,
- MaxJamoExpansionTable *maxexpansion,
- UErrorCode *status)
+ uint32_t endexpansion,
+ uint8_t expansionsize,
+ MaxJamoExpansionTable *maxexpansion,
+ UErrorCode *status)
{
- UBool isV = TRUE;
- if (((uint32_t)ch - 0x1100) <= (0x1112 - 0x1100)) {
- /* determines L for Jamo, doesn't need to store this since it is never
- at the end of a expansion */
- if (maxexpansion->maxLSize < expansionsize) {
- maxexpansion->maxLSize = expansionsize;
- }
- return maxexpansion->position;
- }
-
- if (((uint32_t)ch - 0x1161) <= (0x1175 - 0x1161)) {
- /* determines V for Jamo */
- if (maxexpansion->maxVSize < expansionsize) {
- maxexpansion->maxVSize = expansionsize;
- }
- }
-
- if (((uint32_t)ch - 0x11A8) <= (0x11C2 - 0x11A8)) {
- isV = FALSE;
- /* determines T for Jamo */
- if (maxexpansion->maxTSize < expansionsize) {
- maxexpansion->maxTSize = expansionsize;
- }
- }
-
- if (maxexpansion->size == 0) {
- /* we'll always make the first element 0, for easier manipulation */
- maxexpansion->endExpansionCE =
- (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(uint32_t));
- /* test for NULL */;
- if (maxexpansion->endExpansionCE == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
+ UBool isV = TRUE;
+ if (((uint32_t)ch - 0x1100) <= (0x1112 - 0x1100)) {
+ /* determines L for Jamo, doesn't need to store this since it is never
+ at the end of a expansion */
+ if (maxexpansion->maxLSize < expansionsize) {
+ maxexpansion->maxLSize = expansionsize;
+ }
+ return maxexpansion->position;
}
- *(maxexpansion->endExpansionCE) = 0;
- maxexpansion->isV =
- (UBool *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(UBool));
- /* test for NULL */;
- if (maxexpansion->isV == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
+
+ if (((uint32_t)ch - 0x1161) <= (0x1175 - 0x1161)) {
+ /* determines V for Jamo */
+ if (maxexpansion->maxVSize < expansionsize) {
+ maxexpansion->maxVSize = expansionsize;
+ }
+ }
+
+ if (((uint32_t)ch - 0x11A8) <= (0x11C2 - 0x11A8)) {
+ isV = FALSE;
+ /* determines T for Jamo */
+ if (maxexpansion->maxTSize < expansionsize) {
+ maxexpansion->maxTSize = expansionsize;
+ }
+ }
+
+ if (maxexpansion->size == 0) {
+ /* we'll always make the first element 0, for easier manipulation */
+ maxexpansion->endExpansionCE =
+ (uint32_t *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(uint32_t));
+ /* test for NULL */;
+ if (maxexpansion->endExpansionCE == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ *(maxexpansion->endExpansionCE) = 0;
+ maxexpansion->isV =
+ (UBool *)uprv_malloc(INIT_EXP_TABLE_SIZE * sizeof(UBool));
+ /* test for NULL */;
+ if (maxexpansion->isV == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ uprv_free(maxexpansion->endExpansionCE);
+ maxexpansion->endExpansionCE = NULL;
+ return 0;
+ }
+ *(maxexpansion->isV) = 0;
+ maxexpansion->size = INIT_EXP_TABLE_SIZE;
+ maxexpansion->position = 0;
}
- *(maxexpansion->isV) = 0;
- maxexpansion->size = INIT_EXP_TABLE_SIZE;
- maxexpansion->position = 0;
- }
-
- if (maxexpansion->position + 1 == maxexpansion->size) {
- uint32_t *neweece = (uint32_t *)uprv_realloc(maxexpansion->endExpansionCE,
- 2 * maxexpansion->size * sizeof(uint32_t));
- UBool *newisV = (UBool *)uprv_realloc(maxexpansion->isV,
- 2 * maxexpansion->size * sizeof(UBool));
- if (neweece == NULL || newisV == NULL) {
+
+ if (maxexpansion->position + 1 == maxexpansion->size) {
+ maxexpansion->size *= 2;
+ maxexpansion->endExpansionCE = (uint32_t *)uprv_realloc(maxexpansion->endExpansionCE,
+ maxexpansion->size * sizeof(uint32_t));
+ if (maxexpansion->endExpansionCE == NULL) {
+#ifdef UCOL_DEBUG
+ fprintf(stderr, "out of memory for maxExpansions\n");
+#endif
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ maxexpansion->isV = (UBool *)uprv_realloc(maxexpansion->isV,
+ maxexpansion->size * sizeof(UBool));
+ if (maxexpansion->isV == NULL) {
#ifdef UCOL_DEBUG
- fprintf(stderr, "out of memory for maxExpansions\n");
+ fprintf(stderr, "out of memory for maxExpansions\n");
#endif
- *status = U_MEMORY_ALLOCATION_ERROR;
- return -1;
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ uprv_free(maxexpansion->endExpansionCE);
+ maxexpansion->endExpansionCE = NULL;
+ return 0;
+ }
}
- maxexpansion->endExpansionCE = neweece;
- maxexpansion->isV = newisV;
- maxexpansion->size *= 2;
- }
- uint32_t *pendexpansionce = maxexpansion->endExpansionCE;
- int pos = maxexpansion->position;
+ uint32_t *pendexpansionce = maxexpansion->endExpansionCE;
+ int pos = maxexpansion->position;
- while (pos > 0) {
- pos --;
- if (*(pendexpansionce + pos) == endexpansion) {
- return maxexpansion->position;
- }
- }
+ while (pos > 0) {
+ pos --;
+ if (*(pendexpansionce + pos) == endexpansion) {
+ return maxexpansion->position;
+ }
+ }
- *(pendexpansionce + maxexpansion->position) = endexpansion;
- *(maxexpansion->isV + maxexpansion->position) = isV;
- maxexpansion->position ++;
+ *(pendexpansionce + maxexpansion->position) = endexpansion;
+ *(maxexpansion->isV + maxexpansion->position) = isV;
+ maxexpansion->position ++;
- return maxexpansion->position;
+ return maxexpansion->position;
}
*htByte |= (1 << (hash & 7));
}
+static void
+uprv_uca_createCMTable(tempUCATable *t, int32_t noOfCM, UErrorCode *status) {
+ t->cmLookup = (CombinClassTable *)uprv_malloc(sizeof(CombinClassTable));
+ if (t->cmLookup==NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ t->cmLookup->cPoints=(UChar *)uprv_malloc(noOfCM*sizeof(UChar));
+ if (t->cmLookup->cPoints ==NULL) {
+ uprv_free(t->cmLookup);
+ t->cmLookup = NULL;
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+
+ t->cmLookup->size=noOfCM;
+ uprv_memset(t->cmLookup->index, 0, sizeof(t->cmLookup->index));
+
+ return;
+}
-/* to the UnsafeCP hash table, add all chars with combining class != 0 */
+static void
+uprv_uca_copyCMTable(tempUCATable *t, UChar *cm, uint16_t *index) {
+ int32_t count=0;
+
+ for (int32_t i=0; i<256; ++i) {
+ if (index[i]>0) {
+ // cPoints is ordered by combining class value.
+ uprv_memcpy(t->cmLookup->cPoints+count, cm+(i<<8), index[i]*sizeof(UChar));
+ count += index[i];
+ }
+ t->cmLookup->index[i]=count;
+ }
+ return;
+}
+
+/* 1. to the UnsafeCP hash table, add all chars with combining class != 0 */
+/* 2. build combining marks table for all chars with combining class != 0 */
static void uprv_uca_unsafeCPAddCCNZ(tempUCATable *t, UErrorCode *status) {
UChar c;
- uint16_t fcd; // Hi byte is lead combining class.
- // lo byte is trailing combing class.
- const uint16_t *fcdTrieData;
-
- fcdTrieData = unorm_getFCDTrie(status);
+ uint16_t fcd; // Hi byte is lead combining class. lo byte is trailing combing class.
+ UBool buildCMTable = (t->cmLookup==NULL); // flag for building combining class table
+ UChar *cm=NULL;
+ uint16_t index[256];
+ int32_t count=0;
+ const Normalizer2Impl *nfcImpl = Normalizer2Factory::getNFCImpl(*status);
if (U_FAILURE(*status)) {
return;
}
+ if (buildCMTable) {
+ if (cm==NULL) {
+ cm = (UChar *)uprv_malloc(sizeof(UChar)*UCOL_MAX_CM_TAB);
+ if (cm==NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ }
+ uprv_memset(index, 0, sizeof(index));
+ }
for (c=0; c<0xffff; c++) {
- fcd = unorm_getFCD16(fcdTrieData, c);
+ if (U16_IS_LEAD(c)) {
+ fcd = 0;
+ if (nfcImpl->singleLeadMightHaveNonZeroFCD16(c)) {
+ UChar32 supp = U16_GET_SUPPLEMENTARY(c, 0xdc00);
+ UChar32 suppLimit = supp + 0x400;
+ while (supp < suppLimit) {
+ fcd |= nfcImpl->getFCD16FromNormData(supp++);
+ }
+ }
+ } else {
+ fcd = nfcImpl->getFCD16(c);
+ }
if (fcd >= 0x100 || // if the leading combining class(c) > 0 ||
- (UTF_IS_LEAD(c) && fcd != 0)) // c is a leading surrogate with some FCD data
- unsafeCPSet(t->unsafeCP, c);
+ (U16_IS_LEAD(c) && fcd != 0)) {// c is a leading surrogate with some FCD data
+ if (buildCMTable) {
+ uint32_t cClass = fcd & 0xff;
+ //uint32_t temp=(cClass<<8)+index[cClass];
+ cm[(cClass<<8)+index[cClass]] = c; //
+ index[cClass]++;
+ count++;
+ }
+ unsafeCPSet(t->unsafeCP, c);
+ }
+ }
+
+ // copy to cm table
+ if (buildCMTable) {
+ uprv_uca_createCMTable(t, count, status);
+ if(U_FAILURE(*status)) {
+ if (cm!=NULL) {
+ uprv_free(cm);
+ }
+ return;
+ }
+ uprv_uca_copyCMTable(t, cm, index);
}
if(t->prefixLookup != NULL) {
- int32_t i = -1;
- const UHashElement *e = NULL;
- UCAElements *element = NULL;
- UChar NFCbuf[256];
- uint32_t NFCbufLen = 0;
- while((e = uhash_nextElement(t->prefixLookup, &i)) != NULL) {
- element = (UCAElements *)e->value.pointer;
- // codepoints here are in the NFD form. We need to add the
- // first code point of the NFC form to unsafe, because
- // strcoll needs to backup over them.
- NFCbufLen = unorm_normalize(element->cPoints, element->cSize, UNORM_NFC, 0,
- NFCbuf, 256, status);
- unsafeCPSet(t->unsafeCP, NFCbuf[0]);
- }
+ int32_t i = -1;
+ const UHashElement *e = NULL;
+ UCAElements *element = NULL;
+ UChar NFCbuf[256];
+ while((e = uhash_nextElement(t->prefixLookup, &i)) != NULL) {
+ element = (UCAElements *)e->value.pointer;
+ // codepoints here are in the NFD form. We need to add the
+ // first code point of the NFC form to unsafe, because
+ // strcoll needs to backup over them.
+ unorm_normalize(element->cPoints, element->cSize, UNORM_NFC, 0,
+ NFCbuf, 256, status);
+ unsafeCPSet(t->unsafeCP, NFCbuf[0]);
+ }
+ }
+
+ if (cm!=NULL) {
+ uprv_free(cm);
}
}
-static uint32_t uprv_uca_addPrefix(tempUCATable *t, uint32_t CE,
- UCAElements *element, UErrorCode *status) {
- // currently the longest prefix we're supporting in Japanese is two characters
- // long. Although this table could quite easily mimic complete contraction stuff
- // there is no good reason to make a general solution, as it would require some
- // error prone messing.
+static uint32_t uprv_uca_addPrefix(tempUCATable *t, uint32_t CE,
+ UCAElements *element, UErrorCode *status)
+{
+ // currently the longest prefix we're supporting in Japanese is two characters
+ // long. Although this table could quite easily mimic complete contraction stuff
+ // there is no good reason to make a general solution, as it would require some
+ // error prone messing.
CntTable *contractions = t->contractions;
UChar32 cp;
uint32_t cpsize = 0;
uint32_t j = 0;
#ifdef UCOL_DEBUG
for(j=0; j<element->cSize; j++) {
- fprintf(stdout, "CP: %04X ", element->cPoints[j]);
+ fprintf(stdout, "CP: %04X ", element->cPoints[j]);
}
fprintf(stdout, "El: %08X Pref: ", CE);
for(j=0; j<element->prefixSize; j++) {
- fprintf(stdout, "%04X ", element->prefix[j]);
+ fprintf(stdout, "%04X ", element->prefix[j]);
}
fprintf(stdout, "%08X ", element->mapCE);
#endif
for (j = 1; j<element->prefixSize; j++) { /* First add NFD prefix chars to unsafe CP hash table */
- // Unless it is a trail surrogate, which is handled algoritmically and
- // shouldn't take up space in the table.
- if(!(UTF_IS_TRAIL(element->prefix[j]))) {
- unsafeCPSet(t->unsafeCP, element->prefix[j]);
- }
+ // Unless it is a trail surrogate, which is handled algoritmically and
+ // shouldn't take up space in the table.
+ if(!(U16_IS_TRAIL(element->prefix[j]))) {
+ unsafeCPSet(t->unsafeCP, element->prefix[j]);
+ }
}
UChar tempPrefix = 0;
for(j = 0; j < /*nfcSize*/element->prefixSize/2; j++) { // prefixes are going to be looked up backwards
- // therefore, we will promptly reverse the prefix buffer...
- tempPrefix = *(/*nfcBuffer*/element->prefix+element->prefixSize-j-1);
- *(/*nfcBuffer*/element->prefix+element->prefixSize-j-1) = element->prefix[j];
- element->prefix[j] = tempPrefix;
+ // therefore, we will promptly reverse the prefix buffer...
+ tempPrefix = *(/*nfcBuffer*/element->prefix+element->prefixSize-j-1);
+ *(/*nfcBuffer*/element->prefix+element->prefixSize-j-1) = element->prefix[j];
+ element->prefix[j] = tempPrefix;
}
#ifdef UCOL_DEBUG
fprintf(stdout, "Reversed: ");
for(j=0; j<element->prefixSize; j++) {
- fprintf(stdout, "%04X ", element->prefix[j]);
+ fprintf(stdout, "%04X ", element->prefix[j]);
}
fprintf(stdout, "%08X\n", element->mapCE);
#endif
// the first codepoint is also unsafe, as it forms a 'contraction' with the prefix
- if(!(UTF_IS_TRAIL(element->cPoints[0]))) {
- unsafeCPSet(t->unsafeCP, element->cPoints[0]);
+ if(!(U16_IS_TRAIL(element->cPoints[0]))) {
+ unsafeCPSet(t->unsafeCP, element->cPoints[0]);
}
// Maybe we need this... To handle prefixes completely in the forward direction...
//if(element->cSize == 1) {
- // if(!(UTF_IS_TRAIL(element->cPoints[0]))) {
+ // if(!(U16_IS_TRAIL(element->cPoints[0]))) {
// ContrEndCPSet(t->contrEndCP, element->cPoints[0]);
// }
//}
element->cSize = element->prefixSize;
// Add the last char of the contraction to the contraction-end hash table.
- // unless it is a trail surrogate, which is handled algorithmically and
+ // unless it is a trail surrogate, which is handled algorithmically and
// shouldn't be in the table
- if(!(UTF_IS_TRAIL(element->cPoints[element->cSize -1]))) {
- ContrEndCPSet(t->contrEndCP, element->cPoints[element->cSize -1]);
+ if(!(U16_IS_TRAIL(element->cPoints[element->cSize -1]))) {
+ ContrEndCPSet(t->contrEndCP, element->cPoints[element->cSize -1]);
}
// First we need to check if contractions starts with a surrogate
- UTF_NEXT_CHAR(element->cPoints, cpsize, element->cSize, cp);
+ U16_NEXT(element->cPoints, cpsize, element->cSize, cp);
- // If there are any Jamos in the contraction, we should turn on special
+ // If there are any Jamos in the contraction, we should turn on special
// processing for Jamos
if(UCOL_ISJAMO(element->prefix[0])) {
- t->image->jamoSpecial = TRUE;
+ t->image->jamoSpecial = TRUE;
}
/* then we need to deal with it */
/* we could aready have something in table - or we might not */
- if(!isPrefix(CE)) {
- /* if it wasn't contraction, we wouldn't end up here*/
- int32_t firstContractionOffset = 0;
- int32_t contractionOffset = 0;
- firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, CE, status);
- uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
- contractionOffset = uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->prefix, newCE, status);
- contractionOffset = uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, CE, status);
- CE = constructContractCE(SPEC_PROC_TAG, firstContractionOffset);
+ if(!isPrefix(CE)) {
+ /* if it wasn't contraction, we wouldn't end up here*/
+ int32_t firstContractionOffset = 0;
+ firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, CE, status);
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
+ uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->prefix, newCE, status);
+ uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, CE, status);
+ CE = constructContractCE(SPEC_PROC_TAG, firstContractionOffset);
} else { /* we are adding to existing contraction */
- /* there were already some elements in the table, so we need to add a new contraction */
- /* Two things can happen here: either the codepoint is already in the table, or it is not */
- int32_t position = uprv_cnttab_findCP(contractions, CE, *element->prefix, status);
- if(position > 0) { /* if it is we just continue down the chain */
- uint32_t eCE = uprv_cnttab_getCE(contractions, CE, position, status);
- uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
- uprv_cnttab_setContraction(contractions, CE, position, *(element->prefix), newCE, status);
- } else { /* if it isn't, we will have to create a new sequence */
- uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
- uprv_cnttab_insertContraction(contractions, CE, *(element->prefix), element->mapCE, status);
- }
+ /* there were already some elements in the table, so we need to add a new contraction */
+ /* Two things can happen here: either the codepoint is already in the table, or it is not */
+ int32_t position = uprv_cnttab_findCP(contractions, CE, *element->prefix, status);
+ if(position > 0) { /* if it is we just continue down the chain */
+ uint32_t eCE = uprv_cnttab_getCE(contractions, CE, position, status);
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
+ uprv_cnttab_setContraction(contractions, CE, position, *(element->prefix), newCE, status);
+ } else { /* if it isn't, we will have to create a new sequence */
+ uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
+ uprv_cnttab_insertContraction(contractions, CE, *(element->prefix), element->mapCE, status);
+ }
}
element->cPoints = oldCP;
// as it doesn't affect the performance AND handling surrogates specially
// would complicate code way too much.
static uint32_t uprv_uca_addContraction(tempUCATable *t, uint32_t CE,
- UCAElements *element, UErrorCode *status) {
+ UCAElements *element, UErrorCode *status)
+{
CntTable *contractions = t->contractions;
UChar32 cp;
uint32_t cpsize = 0;
contractions->currentTag = CONTRACTION_TAG;
// First we need to check if contractions starts with a surrogate
- UTF_NEXT_CHAR(element->cPoints, cpsize, element->cSize, cp);
+ U16_NEXT(element->cPoints, cpsize, element->cSize, cp);
if(cpsize<element->cSize) { // This is a real contraction, if there are other characters after the first
- uint32_t j = 0;
- for (j=1; j<element->cSize; j++) { /* First add contraction chars to unsafe CP hash table */
- // Unless it is a trail surrogate, which is handled algoritmically and
- // shouldn't take up space in the table.
- if(!(UTF_IS_TRAIL(element->cPoints[j]))) {
- unsafeCPSet(t->unsafeCP, element->cPoints[j]);
- }
- }
- // Add the last char of the contraction to the contraction-end hash table.
- // unless it is a trail surrogate, which is handled algorithmically and
- // shouldn't be in the table
- if(!(UTF_IS_TRAIL(element->cPoints[element->cSize -1]))) {
- ContrEndCPSet(t->contrEndCP, element->cPoints[element->cSize -1]);
- }
+ uint32_t j = 0;
+ for (j=1; j<element->cSize; j++) { /* First add contraction chars to unsafe CP hash table */
+ // Unless it is a trail surrogate, which is handled algoritmically and
+ // shouldn't take up space in the table.
+ if(!(U16_IS_TRAIL(element->cPoints[j]))) {
+ unsafeCPSet(t->unsafeCP, element->cPoints[j]);
+ }
+ }
+ // Add the last char of the contraction to the contraction-end hash table.
+ // unless it is a trail surrogate, which is handled algorithmically and
+ // shouldn't be in the table
+ if(!(U16_IS_TRAIL(element->cPoints[element->cSize -1]))) {
+ ContrEndCPSet(t->contrEndCP, element->cPoints[element->cSize -1]);
+ }
- // If there are any Jamos in the contraction, we should turn on special
- // processing for Jamos
- if(UCOL_ISJAMO(element->cPoints[0])) {
- t->image->jamoSpecial = TRUE;
- }
- /* then we need to deal with it */
- /* we could aready have something in table - or we might not */
- element->cPoints+=cpsize;
- element->cSize-=cpsize;
- if(!isContraction(CE)) {
- /* if it wasn't contraction, we wouldn't end up here*/
- int32_t firstContractionOffset = 0;
- int32_t contractionOffset = 0;
- firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, CE, status);
- uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
- contractionOffset = uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->cPoints, newCE, status);
- contractionOffset = uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, CE, status);
- CE = constructContractCE(CONTRACTION_TAG, firstContractionOffset);
- } else { /* we are adding to existing contraction */
- /* there were already some elements in the table, so we need to add a new contraction */
- /* Two things can happen here: either the codepoint is already in the table, or it is not */
- int32_t position = uprv_cnttab_findCP(contractions, CE, *element->cPoints, status);
- if(position > 0) { /* if it is we just continue down the chain */
- uint32_t eCE = uprv_cnttab_getCE(contractions, CE, position, status);
- uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
- uprv_cnttab_setContraction(contractions, CE, position, *(element->cPoints), newCE, status);
- } else { /* if it isn't, we will have to create a new sequence */
- uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
- uprv_cnttab_insertContraction(contractions, CE, *(element->cPoints), newCE, status);
- }
- }
- element->cPoints-=cpsize;
- element->cSize+=cpsize;
- /*ucmpe32_set(t->mapping, cp, CE);*/
- utrie_set32(t->mapping, cp, CE);
+ // If there are any Jamos in the contraction, we should turn on special
+ // processing for Jamos
+ if(UCOL_ISJAMO(element->cPoints[0])) {
+ t->image->jamoSpecial = TRUE;
+ }
+ /* then we need to deal with it */
+ /* we could aready have something in table - or we might not */
+ element->cPoints+=cpsize;
+ element->cSize-=cpsize;
+ if(!isContraction(CE)) {
+ /* if it wasn't contraction, we wouldn't end up here*/
+ int32_t firstContractionOffset = 0;
+ firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, CE, status);
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
+ uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->cPoints, newCE, status);
+ uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, CE, status);
+ CE = constructContractCE(CONTRACTION_TAG, firstContractionOffset);
+ } else { /* we are adding to existing contraction */
+ /* there were already some elements in the table, so we need to add a new contraction */
+ /* Two things can happen here: either the codepoint is already in the table, or it is not */
+ int32_t position = uprv_cnttab_findCP(contractions, CE, *element->cPoints, status);
+ if(position > 0) { /* if it is we just continue down the chain */
+ uint32_t eCE = uprv_cnttab_getCE(contractions, CE, position, status);
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
+ uprv_cnttab_setContraction(contractions, CE, position, *(element->cPoints), newCE, status);
+ } else { /* if it isn't, we will have to create a new sequence */
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
+ uprv_cnttab_insertContraction(contractions, CE, *(element->cPoints), newCE, status);
+ }
+ }
+ element->cPoints-=cpsize;
+ element->cSize+=cpsize;
+ /*ucmpe32_set(t->mapping, cp, CE);*/
+ utrie_set32(t->mapping, cp, CE);
} else if(!isContraction(CE)) { /* this is just a surrogate, and there is no contraction */
- /*ucmpe32_set(t->mapping, cp, element->mapCE);*/
- utrie_set32(t->mapping, cp, element->mapCE);
+ /*ucmpe32_set(t->mapping, cp, element->mapCE);*/
+ utrie_set32(t->mapping, cp, element->mapCE);
} else { /* fill out the first stage of the contraction with the surrogate CE */
- uprv_cnttab_changeContraction(contractions, CE, 0, element->mapCE, status);
- uprv_cnttab_changeContraction(contractions, CE, 0xFFFF, element->mapCE, status);
+ uprv_cnttab_changeContraction(contractions, CE, 0, element->mapCE, status);
+ uprv_cnttab_changeContraction(contractions, CE, 0xFFFF, element->mapCE, status);
}
return CE;
}
static uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements *element, uint32_t existingCE, UErrorCode *status) {
int32_t firstContractionOffset = 0;
- int32_t contractionOffset = 0;
-// uint32_t contractionElement = UCOL_NOT_FOUND;
+ // uint32_t contractionElement = UCOL_NOT_FOUND;
if(U_FAILURE(*status)) {
return UCOL_NOT_FOUND;
/* end of recursion */
if(element->cSize == 1) {
- if(isCntTableElement(existingCE) && ((UColCETags)getCETag(existingCE) == contractions->currentTag)) {
- uprv_cnttab_changeContraction(contractions, existingCE, 0, element->mapCE, status);
- uprv_cnttab_changeContraction(contractions, existingCE, 0xFFFF, element->mapCE, status);
- return existingCE;
- } else {
- return element->mapCE; /*can't do just that. existingCe might be a contraction, meaning that we need to do another step */
- }
+ if(isCntTableElement(existingCE) && ((UColCETags)getCETag(existingCE) == contractions->currentTag)) {
+ uprv_cnttab_changeContraction(contractions, existingCE, 0, element->mapCE, status);
+ uprv_cnttab_changeContraction(contractions, existingCE, 0xFFFF, element->mapCE, status);
+ return existingCE;
+ } else {
+ return element->mapCE; /*can't do just that. existingCe might be a contraction, meaning that we need to do another step */
+ }
}
/* this recursion currently feeds on the only element we have... We will have to copy it in order to accomodate */
element->cPoints++;
element->cSize--;
if(!isCntTableElement(existingCE)) {
- /* if it wasn't contraction, we wouldn't end up here*/
- firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, existingCE, status);
- uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
- contractionOffset = uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->cPoints, newCE, status);
- contractionOffset = uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, existingCE, status);
- existingCE = constructContractCE(contractions->currentTag, firstContractionOffset);
- } else { /* we are adding to existing contraction */
- /* there were already some elements in the table, so we need to add a new contraction */
- /* Two things can happen here: either the codepoint is already in the table, or it is not */
- int32_t position = uprv_cnttab_findCP(contractions, existingCE, *element->cPoints, status);
- if(position > 0) { /* if it is we just continue down the chain */
- uint32_t eCE = uprv_cnttab_getCE(contractions, existingCE, position, status);
- uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
- uprv_cnttab_setContraction(contractions, existingCE, position, *(element->cPoints), newCE, status);
- } else { /* if it isn't, we will have to create a new sequence */
+ /* if it wasn't contraction, we wouldn't end up here*/
+ firstContractionOffset = uprv_cnttab_addContraction(contractions, UPRV_CNTTAB_NEWELEMENT, 0, existingCE, status);
uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
- uprv_cnttab_insertContraction(contractions, existingCE, *(element->cPoints), newCE, status);
- }
+ uprv_cnttab_addContraction(contractions, firstContractionOffset, *element->cPoints, newCE, status);
+ uprv_cnttab_addContraction(contractions, firstContractionOffset, 0xFFFF, existingCE, status);
+ existingCE = constructContractCE(contractions->currentTag, firstContractionOffset);
+ } else { /* we are adding to existing contraction */
+ /* there were already some elements in the table, so we need to add a new contraction */
+ /* Two things can happen here: either the codepoint is already in the table, or it is not */
+ int32_t position = uprv_cnttab_findCP(contractions, existingCE, *element->cPoints, status);
+ if(position > 0) { /* if it is we just continue down the chain */
+ uint32_t eCE = uprv_cnttab_getCE(contractions, existingCE, position, status);
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, eCE, status);
+ uprv_cnttab_setContraction(contractions, existingCE, position, *(element->cPoints), newCE, status);
+ } else { /* if it isn't, we will have to create a new sequence */
+ uint32_t newCE = uprv_uca_processContraction(contractions, element, UCOL_NOT_FOUND, status);
+ uprv_cnttab_insertContraction(contractions, existingCE, *(element->cPoints), newCE, status);
+ }
}
element->cPoints--;
element->cSize++;
}
static uint32_t uprv_uca_finalizeAddition(tempUCATable *t, UCAElements *element, UErrorCode *status) {
- uint32_t CE = UCOL_NOT_FOUND;
- // This should add a completely ignorable element to the
- // unsafe table, so that backward iteration will skip
- // over it when treating contractions.
- uint32_t i = 0;
- if(element->mapCE == 0) {
- for(i = 0; i < element->cSize; i++) {
- if(!UTF_IS_TRAIL(element->cPoints[i])) {
- unsafeCPSet(t->unsafeCP, element->cPoints[i]);
- }
- }
- }
- if(element->cSize > 1) { /* we're adding a contraction */
+ uint32_t CE = UCOL_NOT_FOUND;
+ // This should add a completely ignorable element to the
+ // unsafe table, so that backward iteration will skip
+ // over it when treating contractions.
uint32_t i = 0;
- UChar32 cp;
-
- UTF_NEXT_CHAR(element->cPoints, i, element->cSize, cp);
- /*CE = ucmpe32_get(t->mapping, cp);*/
- CE = utrie_get32(t->mapping, cp, NULL);
-
- CE = uprv_uca_addContraction(t, CE, element, status);
- } else { /* easy case, */
- /*CE = ucmpe32_get(t->mapping, element->cPoints[0]);*/
- CE = utrie_get32(t->mapping, element->cPoints[0], NULL);
-
- if( CE != UCOL_NOT_FOUND) {
- if(isCntTableElement(CE) /*isContraction(CE)*/) { /* adding a non contraction element (thai, expansion, single) to already existing contraction */
- if(!isPrefix(element->mapCE)) { // we cannot reenter prefix elements - as we are going to create a dead loop
- // Only expansions and regular CEs can go here... Contractions will never happen in this place
- uprv_cnttab_setContraction(t->contractions, CE, 0, 0, element->mapCE, status);
- /* This loop has to change the CE at the end of contraction REDO!*/
- uprv_cnttab_changeLastCE(t->contractions, CE, element->mapCE, status);
- }
- } else {
- /*ucmpe32_set(t->mapping, element->cPoints[0], element->mapCE);*/
- utrie_set32(t->mapping, element->cPoints[0], element->mapCE);
+ if(element->mapCE == 0) {
+ for(i = 0; i < element->cSize; i++) {
+ if(!U16_IS_TRAIL(element->cPoints[i])) {
+ unsafeCPSet(t->unsafeCP, element->cPoints[i]);
+ }
+ }
+ }
+ if(element->cSize > 1) { /* we're adding a contraction */
+ uint32_t i = 0;
+ UChar32 cp;
+
+ U16_NEXT(element->cPoints, i, element->cSize, cp);
+ /*CE = ucmpe32_get(t->mapping, cp);*/
+ CE = utrie_get32(t->mapping, cp, NULL);
+
+ CE = uprv_uca_addContraction(t, CE, element, status);
+ } else { /* easy case, */
+ /*CE = ucmpe32_get(t->mapping, element->cPoints[0]);*/
+ CE = utrie_get32(t->mapping, element->cPoints[0], NULL);
+
+ if( CE != UCOL_NOT_FOUND) {
+ if(isCntTableElement(CE) /*isContraction(CE)*/) { /* adding a non contraction element (thai, expansion, single) to already existing contraction */
+ if(!isPrefix(element->mapCE)) { // we cannot reenter prefix elements - as we are going to create a dead loop
+ // Only expansions and regular CEs can go here... Contractions will never happen in this place
+ uprv_cnttab_setContraction(t->contractions, CE, 0, 0, element->mapCE, status);
+ /* This loop has to change the CE at the end of contraction REDO!*/
+ uprv_cnttab_changeLastCE(t->contractions, CE, element->mapCE, status);
+ }
+ } else {
+ /*ucmpe32_set(t->mapping, element->cPoints[0], element->mapCE);*/
+ utrie_set32(t->mapping, element->cPoints[0], element->mapCE);
+ if ((element->prefixSize!=0) && (!isSpecial(CE) || (getCETag(CE)!=IMPLICIT_TAG))) {
+ UCAElements *origElem = (UCAElements *)uprv_malloc(sizeof(UCAElements));
+ /* test for NULL */
+ if (origElem== NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ /* copy the original UCA value */
+ origElem->prefixSize = 0;
+ origElem->prefix = NULL;
+ origElem->cPoints = origElem->uchars;
+ origElem->cPoints[0] = element->cPoints[0];
+ origElem->cSize = 1;
+ origElem->CEs[0]=CE;
+ origElem->mapCE=CE;
+ origElem->noOfCEs=1;
+ uprv_uca_finalizeAddition(t, origElem, status);
+ uprv_free(origElem);
+ }
#ifdef UCOL_DEBUG
- fprintf(stderr, "Warning - trying to overwrite existing data %08X for cp %04X with %08X\n", CE, element->cPoints[0], element->CEs[0]);
- //*status = U_ILLEGAL_ARGUMENT_ERROR;
+ fprintf(stderr, "Warning - trying to overwrite existing data %08X for cp %04X with %08X\n", CE, element->cPoints[0], element->CEs[0]);
+ //*status = U_ILLEGAL_ARGUMENT_ERROR;
#endif
- }
- } else {
- /*ucmpe32_set(t->mapping, element->cPoints[0], element->mapCE);*/
- utrie_set32(t->mapping, element->cPoints[0], element->mapCE);
+ }
+ } else {
+ /*ucmpe32_set(t->mapping, element->cPoints[0], element->mapCE);*/
+ utrie_set32(t->mapping, element->cPoints[0], element->mapCE);
+ }
}
- }
- return CE;
+ return CE;
}
/* This adds a read element, while testing for existence */
U_CAPI uint32_t U_EXPORT2
uprv_uca_addAnElement(tempUCATable *t, UCAElements *element, UErrorCode *status) {
- ExpansionTable *expansions = t->expansions;
-
- uint32_t i = 1;
- uint32_t expansion = 0;
- uint32_t CE;
-
- if(U_FAILURE(*status)) {
- return 0xFFFF;
- }
-
- element->mapCE = 0; // clear mapCE so that we can catch expansions
-
- if(element->noOfCEs == 1) {
- if(element->isThai == FALSE) {
- element->mapCE = element->CEs[0];
- } else { /* add thai - totally bad here */
- expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (THAI_TAG<<UCOL_TAG_SHIFT)
- | ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4)
- | 0x1);
- element->mapCE = expansion;
- }
- } else {
- /* ICU 2.1 long primaries */
- /* unfortunately, it looks like we have to look for a long primary here */
- /* since in canonical closure we are going to hit some long primaries from */
- /* the first phase, and they will come back as continuations/expansions */
- /* destroying the effect of the previous opitimization */
- /* A long primary is a three byte primary with starting secondaries and tertiaries */
- /* It can appear in long runs of only primary differences (like east Asian tailorings) */
- /* also, it should not be an expansion, as expansions would break with this */
- // This part came in from ucol_bld.cpp
- //if(tok->expansion == 0
- //&& noOfBytes[0] == 3 && noOfBytes[1] == 1 && noOfBytes[2] == 1
- //&& CEparts[1] == (UCOL_BYTE_COMMON << 24) && CEparts[2] == (UCOL_BYTE_COMMON << 24)) {
- /* we will construct a special CE that will go unchanged to the table */
- if(element->noOfCEs == 2 // a two CE expansion
- && isContinuation(element->CEs[1]) // which is a continuation
- && (element->CEs[1] & (~(0xFF << 24 | UCOL_CONTINUATION_MARKER))) == 0 // that has only primaries in continuation,
- && (((element->CEs[0]>>8) & 0xFF) == UCOL_BYTE_COMMON) // a common secondary
- && ((element->CEs[0] & 0xFF) == UCOL_BYTE_COMMON) // and a common tertiary
- ) {
+ U_NAMESPACE_USE
+
+ ExpansionTable *expansions = t->expansions;
+
+ uint32_t i = 1;
+ uint32_t expansion = 0;
+ uint32_t CE;
+
+ if(U_FAILURE(*status)) {
+ return 0xFFFF;
+ }
+
+ element->mapCE = 0; // clear mapCE so that we can catch expansions
+
+ if(element->noOfCEs == 1) {
+ element->mapCE = element->CEs[0];
+ } else {
+ /* ICU 2.1 long primaries */
+ /* unfortunately, it looks like we have to look for a long primary here */
+ /* since in canonical closure we are going to hit some long primaries from */
+ /* the first phase, and they will come back as continuations/expansions */
+ /* destroying the effect of the previous opitimization */
+ /* A long primary is a three byte primary with starting secondaries and tertiaries */
+ /* It can appear in long runs of only primary differences (like east Asian tailorings) */
+ /* also, it should not be an expansion, as expansions would break with this */
+ // This part came in from ucol_bld.cpp
+ //if(tok->expansion == 0
+ //&& noOfBytes[0] == 3 && noOfBytes[1] == 1 && noOfBytes[2] == 1
+ //&& CEparts[1] == (UCOL_BYTE_COMMON << 24) && CEparts[2] == (UCOL_BYTE_COMMON << 24)) {
+ /* we will construct a special CE that will go unchanged to the table */
+ if(element->noOfCEs == 2 // a two CE expansion
+ && isContinuation(element->CEs[1]) // which is a continuation
+ && (element->CEs[1] & (~(0xFF << 24 | UCOL_CONTINUATION_MARKER))) == 0 // that has only primaries in continuation,
+ && (((element->CEs[0]>>8) & 0xFF) == UCOL_BYTE_COMMON) // a common secondary
+ && ((element->CEs[0] & 0xFF) == UCOL_BYTE_COMMON) // and a common tertiary
+ )
+ {
#ifdef UCOL_DEBUG
- fprintf(stdout, "Long primary %04X\n", element->cPoints[0]);
+ fprintf(stdout, "Long primary %04X\n", element->cPoints[0]);
#endif
- element->mapCE = UCOL_SPECIAL_FLAG | (LONG_PRIMARY_TAG<<24) // a long primary special
- | ((element->CEs[0]>>8) & 0xFFFF00) // first and second byte of primary
- | ((element->CEs[1]>>24) & 0xFF); // third byte of primary
- } else {
- expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (EXPANSION_TAG<<UCOL_TAG_SHIFT)
- | ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4)
- & 0xFFFFF0);
-
- for(i = 1; i<element->noOfCEs; i++) {
- uprv_uca_addExpansion(expansions, element->CEs[i], status);
- }
- if(element->noOfCEs <= 0xF) {
- expansion |= element->noOfCEs;
- } else {
- uprv_uca_addExpansion(expansions, 0, status);
- }
- element->mapCE = expansion;
- uprv_uca_setMaxExpansion(element->CEs[element->noOfCEs - 1],
- (uint8_t)element->noOfCEs,
- t->maxExpansions,
- status);
- if(UCOL_ISJAMO(element->cPoints[0])) {
- t->image->jamoSpecial = TRUE;
- uprv_uca_setMaxJamoExpansion(element->cPoints[0],
- element->CEs[element->noOfCEs - 1],
- (uint8_t)element->noOfCEs,
- t->maxJamoExpansions,
- status);
- }
- }
- }
-
- // We treat digits differently - they are "uber special" and should be
- // processed differently if numeric collation is on.
- UChar32 uniChar = 0;
- //printElement(element);
- if ((element->cSize == 2) && U16_IS_LEAD(element->uchars[0])){
- uniChar = U16_GET_SUPPLEMENTARY(element->uchars[0], element->uchars[1]);
- } else if (element->cSize == 1){
- uniChar = element->uchars[0];
- }
-
- // Here, we either have one normal CE OR mapCE is set. Therefore, we stuff only
- // one element to the expansion buffer. When we encounter a digit and we don't
- // do numeric collation, we will just pick the CE we have and break out of case
- // (see ucol.cpp ucol_prv_getSpecialCE && ucol_prv_getSpecialPrevCE). If we picked
- // a special, further processing will occur. If it's a simple CE, we'll return due
- // to how the loop is constructed.
- if (uniChar != 0 && u_isdigit(uniChar)){
- expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (DIGIT_TAG<<UCOL_TAG_SHIFT) | 1); // prepare the element
- if(element->mapCE) { // if there is an expansion, we'll pick it here
- expansion |= ((uprv_uca_addExpansion(expansions, element->mapCE, status)+(headersize>>2))<<4);
- } else {
- expansion |= ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4);
- }
- element->mapCE = expansion;
-
- // Need to go back to the beginning of the digit string if in the middle!
- if(uniChar <= 0xFFFF) { // supplementaries are always unsafe. API takes UChars
- unsafeCPSet(t->unsafeCP, (UChar)uniChar);
- }
- }
-
- // here we want to add the prefix structure.
- // I will try to process it as a reverse contraction, if possible.
- // prefix buffer is already reversed.
-
- if(element->prefixSize!=0) {
- // We keep the seen prefix starter elements in a hashtable
- // we need it to be able to distinguish between the simple
- // codepoints and prefix starters. Also, we need to use it
- // for canonical closure.
-
- UCAElements *composed = (UCAElements *)uprv_malloc(sizeof(UCAElements));
- /* test for NULL */
- if (composed == NULL) {
- *status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
+ element->mapCE = UCOL_SPECIAL_FLAG | (LONG_PRIMARY_TAG<<24) // a long primary special
+ | ((element->CEs[0]>>8) & 0xFFFF00) // first and second byte of primary
+ | ((element->CEs[1]>>24) & 0xFF); // third byte of primary
+ }
+ else {
+ expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (EXPANSION_TAG<<UCOL_TAG_SHIFT)
+ | (((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4)
+ & 0xFFFFF0));
+
+ for(i = 1; i<element->noOfCEs; i++) {
+ uprv_uca_addExpansion(expansions, element->CEs[i], status);
+ }
+ if(element->noOfCEs <= 0xF) {
+ expansion |= element->noOfCEs;
+ } else {
+ uprv_uca_addExpansion(expansions, 0, status);
+ }
+ element->mapCE = expansion;
+ uprv_uca_setMaxExpansion(element->CEs[element->noOfCEs - 1],
+ (uint8_t)element->noOfCEs,
+ t->maxExpansions,
+ status);
+ if(UCOL_ISJAMO(element->cPoints[0])) {
+ t->image->jamoSpecial = TRUE;
+ uprv_uca_setMaxJamoExpansion(element->cPoints[0],
+ element->CEs[element->noOfCEs - 1],
+ (uint8_t)element->noOfCEs,
+ t->maxJamoExpansions,
+ status);
+ }
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
+ }
}
- uprv_memcpy(composed, element, sizeof(UCAElements));
- composed->cPoints = composed->uchars;
- composed->prefix = composed->prefixChars;
- composed->prefixSize = unorm_normalize(element->prefix, element->prefixSize, UNORM_NFC, 0, composed->prefix, 128, status);
+ // We treat digits differently - they are "uber special" and should be
+ // processed differently if numeric collation is on.
+ UChar32 uniChar = 0;
+ //printElement(element);
+ if ((element->cSize == 2) && U16_IS_LEAD(element->cPoints[0])){
+ uniChar = U16_GET_SUPPLEMENTARY(element->cPoints[0], element->cPoints[1]);
+ } else if (element->cSize == 1){
+ uniChar = element->cPoints[0];
+ }
+ // Here, we either have one normal CE OR mapCE is set. Therefore, we stuff only
+ // one element to the expansion buffer. When we encounter a digit and we don't
+ // do numeric collation, we will just pick the CE we have and break out of case
+ // (see ucol.cpp ucol_prv_getSpecialCE && ucol_prv_getSpecialPrevCE). If we picked
+ // a special, further processing will occur. If it's a simple CE, we'll return due
+ // to how the loop is constructed.
+ if (uniChar != 0 && u_isdigit(uniChar)){
+ expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (DIGIT_TAG<<UCOL_TAG_SHIFT) | 1); // prepare the element
+ if(element->mapCE) { // if there is an expansion, we'll pick it here
+ expansion |= ((uprv_uca_addExpansion(expansions, element->mapCE, status)+(headersize>>2))<<4);
+ } else {
+ expansion |= ((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4);
+ }
+ element->mapCE = expansion;
- if(t->prefixLookup != NULL) {
- UCAElements *uCE = (UCAElements *)uhash_get(t->prefixLookup, element);
- if(uCE != NULL) { // there is already a set of code points here
- element->mapCE = uprv_uca_addPrefix(t, uCE->mapCE, element, status);
- } else { // no code points, so this spot is clean
- element->mapCE = uprv_uca_addPrefix(t, UCOL_NOT_FOUND, element, status);
- uCE = (UCAElements *)uprv_malloc(sizeof(UCAElements));
+ // Need to go back to the beginning of the digit string if in the middle!
+ if(uniChar <= 0xFFFF) { // supplementaries are always unsafe. API takes UChars
+ unsafeCPSet(t->unsafeCP, (UChar)uniChar);
+ }
+ }
+
+ // here we want to add the prefix structure.
+ // I will try to process it as a reverse contraction, if possible.
+ // prefix buffer is already reversed.
+
+ if(element->prefixSize!=0) {
+ // We keep the seen prefix starter elements in a hashtable
+ // we need it to be able to distinguish between the simple
+ // codepoints and prefix starters. Also, we need to use it
+ // for canonical closure.
+
+ UCAElements *composed = (UCAElements *)uprv_malloc(sizeof(UCAElements));
/* test for NULL */
- if (uCE == NULL) {
+ if (composed == NULL) {
*status = U_MEMORY_ALLOCATION_ERROR;
return 0;
}
- uprv_memcpy(uCE, element, sizeof(UCAElements));
- uCE->cPoints = uCE->uchars;
- uhash_put(t->prefixLookup, uCE, uCE, status);
- }
- if(composed->prefixSize != element->prefixSize || uprv_memcmp(composed->prefix, element->prefix, element->prefixSize)) {
- // do it!
- composed->mapCE = uprv_uca_addPrefix(t, element->mapCE, composed, status);
- }
- }
- uprv_free(composed);
- }
-
- // We need to use the canonical iterator here
- // the way we do it is to generate the canonically equivalent strings
- // for the contraction and then add the sequences that pass FCD check
- if(element->cSize > 1 && !(element->cSize==2 && UTF16_IS_LEAD(element->cPoints[0]) && UTF16_IS_TRAIL(element->cPoints[1]))) { // this is a contraction, we should check whether a composed form should also be included
- UnicodeString source(element->cPoints, element->cSize);
- CanonicalIterator it(source, *status);
- source = it.next();
- while(!source.isBogus()) {
- if(Normalizer::quickCheck(source, UNORM_FCD, *status) != UNORM_NO) {
- element->cSize = source.extract(element->cPoints, 128, *status);
- uprv_uca_finalizeAddition(t, element, status);
- }
- source = it.next();
- }
- CE = element->mapCE;
- } else {
- CE = uprv_uca_finalizeAddition(t, element, status);
- }
-
- return CE;
+ uprv_memcpy(composed, element, sizeof(UCAElements));
+ composed->cPoints = composed->uchars;
+ composed->prefix = composed->prefixChars;
+
+ composed->prefixSize = unorm_normalize(element->prefix, element->prefixSize, UNORM_NFC, 0, composed->prefix, 128, status);
+
+
+ if(t->prefixLookup != NULL) {
+ UCAElements *uCE = (UCAElements *)uhash_get(t->prefixLookup, element);
+ if(uCE != NULL) { // there is already a set of code points here
+ element->mapCE = uprv_uca_addPrefix(t, uCE->mapCE, element, status);
+ } else { // no code points, so this spot is clean
+ element->mapCE = uprv_uca_addPrefix(t, UCOL_NOT_FOUND, element, status);
+ uCE = (UCAElements *)uprv_malloc(sizeof(UCAElements));
+ /* test for NULL */
+ if (uCE == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ return 0;
+ }
+ uprv_memcpy(uCE, element, sizeof(UCAElements));
+ uCE->cPoints = uCE->uchars;
+ uhash_put(t->prefixLookup, uCE, uCE, status);
+ }
+ if(composed->prefixSize != element->prefixSize || uprv_memcmp(composed->prefix, element->prefix, element->prefixSize)) {
+ // do it!
+ composed->mapCE = uprv_uca_addPrefix(t, element->mapCE, composed, status);
+ }
+ }
+ uprv_free(composed);
+ }
+
+ // We need to use the canonical iterator here
+ // the way we do it is to generate the canonically equivalent strings
+ // for the contraction and then add the sequences that pass FCD check
+ if(element->cSize > 1 && !(element->cSize==2 && U16_IS_LEAD(element->cPoints[0]) && U16_IS_TRAIL(element->cPoints[1]))) { // this is a contraction, we should check whether a composed form should also be included
+ UnicodeString source(element->cPoints, element->cSize);
+ CanonicalIterator it(source, *status);
+ source = it.next();
+ while(!source.isBogus()) {
+ if(Normalizer::quickCheck(source, UNORM_FCD, *status) != UNORM_NO) {
+ element->cSize = source.extract(element->cPoints, 128, *status);
+ uprv_uca_finalizeAddition(t, element, status);
+ }
+ source = it.next();
+ }
+ CE = element->mapCE;
+ } else {
+ CE = uprv_uca_finalizeAddition(t, element, status);
+ }
+
+ return CE;
}
/*void uprv_uca_getMaxExpansionJamo(CompactEIntArray *mapping, */
static void uprv_uca_getMaxExpansionJamo(UNewTrie *mapping,
- MaxExpansionTable *maxexpansion,
- MaxJamoExpansionTable *maxjamoexpansion,
- UBool jamospecial,
- UErrorCode *status)
+ MaxExpansionTable *maxexpansion,
+ MaxJamoExpansionTable *maxjamoexpansion,
+ UBool jamospecial,
+ UErrorCode *status)
{
- const uint32_t VBASE = 0x1161;
- const uint32_t TBASE = 0x11A8;
- const uint32_t VCOUNT = 21;
- const uint32_t TCOUNT = 28;
-
- uint32_t v = VBASE + VCOUNT - 1;
- uint32_t t = TBASE + TCOUNT - 1;
- uint32_t ce;
-
- while (v >= VBASE) {
- /*ce = ucmpe32_get(mapping, v);*/
- ce = utrie_get32(mapping, v, NULL);
- if (ce < UCOL_SPECIAL_FLAG) {
- uprv_uca_setMaxExpansion(ce, 2, maxexpansion, status);
- }
- v --;
- }
-
- while (t >= TBASE)
- {
- /*ce = ucmpe32_get(mapping, t);*/
- ce = utrie_get32(mapping, t, NULL);
- if (ce < UCOL_SPECIAL_FLAG) {
- uprv_uca_setMaxExpansion(ce, 3, maxexpansion, status);
- }
- t --;
- }
- /* According to the docs, 99% of the time, the Jamo will not be special */
- if (jamospecial) {
- /* gets the max expansion in all unicode characters */
- int count = maxjamoexpansion->position;
- uint8_t maxTSize = (uint8_t)(maxjamoexpansion->maxLSize +
- maxjamoexpansion->maxVSize +
- maxjamoexpansion->maxTSize);
- uint8_t maxVSize = (uint8_t)(maxjamoexpansion->maxLSize +
- maxjamoexpansion->maxVSize);
-
- while (count > 0) {
- count --;
- if (*(maxjamoexpansion->isV + count) == TRUE) {
+ const uint32_t VBASE = 0x1161;
+ const uint32_t TBASE = 0x11A8;
+ const uint32_t VCOUNT = 21;
+ const uint32_t TCOUNT = 28;
+
+ uint32_t v = VBASE + VCOUNT - 1;
+ uint32_t t = TBASE + TCOUNT - 1;
+ uint32_t ce;
+
+ while (v >= VBASE) {
+ /*ce = ucmpe32_get(mapping, v);*/
+ ce = utrie_get32(mapping, v, NULL);
+ if (ce < UCOL_SPECIAL_FLAG) {
+ uprv_uca_setMaxExpansion(ce, 2, maxexpansion, status);
+ }
+ v --;
+ }
+
+ while (t >= TBASE)
+ {
+ /*ce = ucmpe32_get(mapping, t);*/
+ ce = utrie_get32(mapping, t, NULL);
+ if (ce < UCOL_SPECIAL_FLAG) {
+ uprv_uca_setMaxExpansion(ce, 3, maxexpansion, status);
+ }
+ t --;
+ }
+ /* According to the docs, 99% of the time, the Jamo will not be special */
+ if (jamospecial) {
+ /* gets the max expansion in all unicode characters */
+ int count = maxjamoexpansion->position;
+ uint8_t maxTSize = (uint8_t)(maxjamoexpansion->maxLSize +
+ maxjamoexpansion->maxVSize +
+ maxjamoexpansion->maxTSize);
+ uint8_t maxVSize = (uint8_t)(maxjamoexpansion->maxLSize +
+ maxjamoexpansion->maxVSize);
+
+ while (count > 0) {
+ count --;
+ if (*(maxjamoexpansion->isV + count) == TRUE) {
uprv_uca_setMaxExpansion(
- *(maxjamoexpansion->endExpansionCE + count),
- maxVSize, maxexpansion, status);
- }
- else {
+ *(maxjamoexpansion->endExpansionCE + count),
+ maxVSize, maxexpansion, status);
+ }
+ else {
uprv_uca_setMaxExpansion(
- *(maxjamoexpansion->endExpansionCE + count),
- maxTSize, maxexpansion, status);
- }
- }
- }
+ *(maxjamoexpansion->endExpansionCE + count),
+ maxTSize, maxexpansion, status);
+ }
+ }
+ }
}
U_CDECL_BEGIN
static inline uint32_t U_CALLCONV
getFoldedValue(UNewTrie *trie, UChar32 start, int32_t offset)
{
- uint32_t value;
- uint32_t tag;
- UChar32 limit;
- UBool inBlockZero;
-
- limit=start+0x400;
- while(start<limit) {
- value=utrie_get32(trie, start, &inBlockZero);
- tag = getCETag(value);
- if(inBlockZero == TRUE) {
- start+=UTRIE_DATA_BLOCK_LENGTH;
- } else if(!(isSpecial(value) && (tag == IMPLICIT_TAG || tag == NOT_FOUND_TAG))) {
- /* These are values that are starting in either UCA (IMPLICIT_TAG) or in the
- * tailorings (NOT_FOUND_TAG). Presence of these tags means that there is
- * nothing in this position and that it should be skipped.
- */
+ uint32_t value;
+ uint32_t tag;
+ UChar32 limit;
+ UBool inBlockZero;
+
+ limit=start+0x400;
+ while(start<limit) {
+ value=utrie_get32(trie, start, &inBlockZero);
+ tag = getCETag(value);
+ if(inBlockZero == TRUE) {
+ start+=UTRIE_DATA_BLOCK_LENGTH;
+ } else if(!(isSpecial(value) && (tag == IMPLICIT_TAG || tag == NOT_FOUND_TAG))) {
+ /* These are values that are starting in either UCA (IMPLICIT_TAG) or in the
+ * tailorings (NOT_FOUND_TAG). Presence of these tags means that there is
+ * nothing in this position and that it should be skipped.
+ */
#ifdef UCOL_DEBUG
- static int32_t count = 1;
- fprintf(stdout, "%i, Folded %08X, value %08X\n", count++, start, value);
+ static int32_t count = 1;
+ fprintf(stdout, "%i, Folded %08X, value %08X\n", count++, start, value);
#endif
- return (uint32_t)(UCOL_SPECIAL_FLAG | (SURROGATE_TAG<<24) | offset);
- } else {
- ++start;
- }
- }
- return 0;
+ return (uint32_t)(UCOL_SPECIAL_FLAG | (SURROGATE_TAG<<24) | offset);
+ } else {
+ ++start;
+ }
+ }
+ return 0;
}
U_CDECL_END
#ifdef UCOL_DEBUG
// This is a debug function to print the contents of a trie.
// It is used in conjuction with the code around utrie_unserialize call
-void enumRange(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
- if(start<0x10000) {
- fprintf(stdout, "%08X, %08X, %08X\n", start, limit, value);
- } else {
- fprintf(stdout, "%08X=%04X %04X, %08X=%04X %04X, %08X\n", start, UTF16_LEAD(start), UTF16_TRAIL(start), limit, UTF16_LEAD(limit), UTF16_TRAIL(limit), value);
- }
+UBool enumRange(const void *context, UChar32 start, UChar32 limit, uint32_t value) {
+ if(start<0x10000) {
+ fprintf(stdout, "%08X, %08X, %08X\n", start, limit, value);
+ } else {
+ fprintf(stdout, "%08X=%04X %04X, %08X=%04X %04X, %08X\n", start, U16_LEAD(start), U16_TRAIL(start), limit, U16_LEAD(limit), U16_TRAIL(limit), value);
+ }
+ return TRUE;
}
int32_t
myGetFoldingOffset(uint32_t data) {
- if(data > UCOL_NOT_FOUND && getCETag(data) == SURROGATE_TAG) {
- return (data&0xFFFFFF);
- } else {
- return 0;
- }
+ if(data > UCOL_NOT_FOUND && getCETag(data) == SURROGATE_TAG) {
+ return (data&0xFFFFFF);
+ } else {
+ return 0;
+ }
}
#endif
/* the trie is compacted */
/* sets jamo expansions */
uprv_uca_getMaxExpansionJamo(mapping, maxexpansion, t->maxJamoExpansions,
- t->image->jamoSpecial, status);
+ t->image->jamoSpecial, status);
/*ucmpe32_compact(mapping);*/
/*UMemoryStream *ms = uprv_mstrm_openNew(8192);*/
/* TODO: LATIN1 array is now in the utrie - it should be removed from the calculation */
uint32_t toAllocate =(uint32_t)(headersize+
- paddedsize(expansions->position*sizeof(uint32_t))+
- paddedsize(mappingSize)+
- paddedsize(contractionsSize*(sizeof(UChar)+sizeof(uint32_t)))+
- //paddedsize(0x100*sizeof(uint32_t)) /* Latin1 is now included in the trie */
- /* maxexpansion array */
- + paddedsize(maxexpansion->position * sizeof(uint32_t)) +
- /* maxexpansion size array */
- paddedsize(maxexpansion->position * sizeof(uint8_t)) +
- paddedsize(UCOL_UNSAFECP_TABLE_SIZE) + /* Unsafe chars */
- paddedsize(UCOL_UNSAFECP_TABLE_SIZE)); /* Contraction Ending chars */
+ paddedsize(expansions->position*sizeof(uint32_t))+
+ paddedsize(mappingSize)+
+ paddedsize(contractionsSize*(sizeof(UChar)+sizeof(uint32_t)))+
+ //paddedsize(0x100*sizeof(uint32_t)) /* Latin1 is now included in the trie */
+ /* maxexpansion array */
+ + paddedsize(maxexpansion->position * sizeof(uint32_t)) +
+ /* maxexpansion size array */
+ paddedsize(maxexpansion->position * sizeof(uint8_t)) +
+ paddedsize(UCOL_UNSAFECP_TABLE_SIZE) + /* Unsafe chars */
+ paddedsize(UCOL_UNSAFECP_TABLE_SIZE)); /* Contraction Ending chars */
dataStart = (uint8_t *)uprv_malloc(toAllocate);
/* contractions block */
if(contractionsSize != 0) {
- /* copy contraction index */
- /*myData->contractionIndex = (UChar *)(dataStart+tableOffset);*/
- myData->contractionIndex = tableOffset;
- uprv_memcpy(dataStart+tableOffset, contractions->codePoints, contractionsSize*sizeof(UChar));
- tableOffset += (uint32_t)(paddedsize(contractionsSize*sizeof(UChar)));
-
- /* copy contraction collation elements */
- /*myData->contractionCEs = (uint32_t *)(dataStart+tableOffset);*/
- myData->contractionCEs = tableOffset;
- uprv_memcpy(dataStart+tableOffset, contractions->CEs, contractionsSize*sizeof(uint32_t));
- tableOffset += (uint32_t)(paddedsize(contractionsSize*sizeof(uint32_t)));
+ /* copy contraction index */
+ /*myData->contractionIndex = (UChar *)(dataStart+tableOffset);*/
+ myData->contractionIndex = tableOffset;
+ uprv_memcpy(dataStart+tableOffset, contractions->codePoints, contractionsSize*sizeof(UChar));
+ tableOffset += (uint32_t)(paddedsize(contractionsSize*sizeof(UChar)));
+
+ /* copy contraction collation elements */
+ /*myData->contractionCEs = (uint32_t *)(dataStart+tableOffset);*/
+ myData->contractionCEs = tableOffset;
+ uprv_memcpy(dataStart+tableOffset, contractions->CEs, contractionsSize*sizeof(uint32_t));
+ tableOffset += (uint32_t)(paddedsize(contractionsSize*sizeof(uint32_t)));
} else {
- myData->contractionIndex = 0;
- myData->contractionCEs = 0;
+ myData->contractionIndex = 0;
+ myData->contractionCEs = 0;
}
/* copy mapping table */
#ifdef UCOL_DEBUG
// This is debug code to dump the contents of the trie. It needs two functions defined above
{
- UTrie UCAt = { 0 };
- uint32_t trieWord;
- utrie_unserialize(&UCAt, dataStart+tableOffset, 9999999, status);
- UCAt.getFoldingOffset = myGetFoldingOffset;
- if(U_SUCCESS(*status)) {
- utrie_enum(&UCAt, NULL, enumRange, NULL);
- }
- trieWord = UTRIE_GET32_FROM_LEAD(UCAt, 0xDC01)
+ UTrie UCAt = { 0 };
+ uint32_t trieWord;
+ utrie_unserialize(&UCAt, dataStart+tableOffset, 9999999, status);
+ UCAt.getFoldingOffset = myGetFoldingOffset;
+ if(U_SUCCESS(*status)) {
+ utrie_enum(&UCAt, NULL, enumRange, NULL);
+ }
+ trieWord = UTRIE_GET32_FROM_LEAD(&UCAt, 0xDC01);
}
#endif
tableOffset += paddedsize(mappingSize);
/* copy max expansion table */
myData->endExpansionCE = tableOffset;
- myData->endExpansionCECount = maxexpansion->position;
+ myData->endExpansionCECount = maxexpansion->position - 1;
/* not copying the first element which is a dummy */
uprv_memcpy(dataStart + tableOffset, maxexpansion->endExpansionCE + 1,
- maxexpansion->position * sizeof(uint32_t));
- tableOffset += (uint32_t)(paddedsize(maxexpansion->position * sizeof(uint32_t)));
+ (maxexpansion->position - 1) * sizeof(uint32_t));
+ tableOffset += (uint32_t)(paddedsize((maxexpansion->position)* sizeof(uint32_t)));
myData->expansionCESize = tableOffset;
uprv_memcpy(dataStart + tableOffset, maxexpansion->expansionCESize + 1,
- maxexpansion->position * sizeof(uint8_t));
- tableOffset += (uint32_t)(paddedsize(maxexpansion->position * sizeof(uint8_t)));
+ (maxexpansion->position - 1) * sizeof(uint8_t));
+ tableOffset += (uint32_t)(paddedsize((maxexpansion->position)* sizeof(uint8_t)));
/* Unsafe chars table. Finish it off, then copy it. */
uprv_uca_unsafeCPAddCCNZ(t, status);
if (t->UCA != 0) { /* Or in unsafebits from UCA, making a combined table. */
- for (i=0; i<UCOL_UNSAFECP_TABLE_SIZE; i++) {
- t->unsafeCP[i] |= t->UCA->unsafeCP[i];
- }
+ for (i=0; i<UCOL_UNSAFECP_TABLE_SIZE; i++) {
+ t->unsafeCP[i] |= t->UCA->unsafeCP[i];
+ }
}
myData->unsafeCP = tableOffset;
uprv_memcpy(dataStart + tableOffset, t->unsafeCP, UCOL_UNSAFECP_TABLE_SIZE);
struct enumStruct {
- tempUCATable *t;
- UCollator *tempColl;
- UCollationElements* colEl;
- int32_t noOfClosures;
- UErrorCode *status;
+ tempUCATable *t;
+ UCollator *tempColl;
+ UCollationElements* colEl;
+ const Normalizer2Impl *nfcImpl;
+ UnicodeSet *closed;
+ int32_t noOfClosures;
+ UErrorCode *status;
};
U_CDECL_BEGIN
static UBool U_CALLCONV
_enumCategoryRangeClosureCategory(const void *context, UChar32 start, UChar32 limit, UCharCategory type) {
- UErrorCode *status = ((enumStruct *)context)->status;
- tempUCATable *t = ((enumStruct *)context)->t;
- UCollator *tempColl = ((enumStruct *)context)->tempColl;
- UCollationElements* colEl = ((enumStruct *)context)->colEl;
- UCAElements el;
- UChar decomp[256] = { 0 };
- int32_t noOfDec = 0;
-
- UChar32 u32 = 0;
- UChar comp[2];
- uint32_t len = 0;
-
- if (type != U_UNASSIGNED && type != U_PRIVATE_USE_CHAR) { // if the range is assigned - we might ommit more categories later
- for(u32 = start; u32 < limit; u32++) {
- noOfDec = unorm_getDecomposition(u32, FALSE, decomp, 256);
- //if((noOfDec = unorm_normalize(comp, len, UNORM_NFD, 0, decomp, 256, status)) > 1
- //|| (noOfDec == 1 && *decomp != (UChar)u32))
- if(noOfDec > 0) // if we're positive, that means there is no decomposition
- {
- len = 0;
- UTF_APPEND_CHAR_UNSAFE(comp, len, u32);
- if(ucol_strcoll(tempColl, comp, len, decomp, noOfDec) != UCOL_EQUAL) {
+ if (type != U_UNASSIGNED && type != U_PRIVATE_USE_CHAR) { // if the range is assigned - we might ommit more categories later
+ UErrorCode *status = ((enumStruct *)context)->status;
+ tempUCATable *t = ((enumStruct *)context)->t;
+ UCollator *tempColl = ((enumStruct *)context)->tempColl;
+ UCollationElements* colEl = ((enumStruct *)context)->colEl;
+ UCAElements el;
+ UChar decompBuffer[4];
+ const UChar *decomp;
+ int32_t noOfDec = 0;
+
+ UChar32 u32 = 0;
+ UChar comp[2];
+ uint32_t len = 0;
+
+ for(u32 = start; u32 < limit; u32++) {
+ decomp = ((enumStruct *)context)->nfcImpl->
+ getDecomposition(u32, decompBuffer, noOfDec);
+ //if((noOfDec = unorm_normalize(comp, len, UNORM_NFD, 0, decomp, 256, status)) > 1
+ //|| (noOfDec == 1 && *decomp != (UChar)u32))
+ if(decomp != NULL)
+ {
+ len = 0;
+ U16_APPEND_UNSAFE(comp, len, u32);
+ if(ucol_strcoll(tempColl, comp, len, decomp, noOfDec) != UCOL_EQUAL) {
#ifdef UCOL_DEBUG
- fprintf(stderr, "Closure: %08X -> ", u32);
- uint32_t i = 0;
- for(i = 0; i<noOfDec; i++) {
- fprintf(stderr, "%04X ", decomp[i]);
- }
- fprintf(stderr, "\n");
+ fprintf(stderr, "Closure: U+%04X -> ", u32);
+ UChar32 c;
+ int32_t i = 0;
+ while(i < noOfDec) {
+ U16_NEXT(decomp, i, noOfDec, c);
+ fprintf(stderr, "%04X ", c);
+ }
+ fprintf(stderr, "\n");
+ // print CEs for code point vs. decomposition
+ fprintf(stderr, "U+%04X CEs: ", u32);
+ UCollationElements *iter = ucol_openElements(tempColl, comp, len, status);
+ int32_t ce;
+ while((ce = ucol_next(iter, status)) != UCOL_NULLORDER) {
+ fprintf(stderr, "%08X ", ce);
+ }
+ fprintf(stderr, "\nDecomp CEs: ");
+ ucol_setText(iter, decomp, noOfDec, status);
+ while((ce = ucol_next(iter, status)) != UCOL_NULLORDER) {
+ fprintf(stderr, "%08X ", ce);
+ }
+ fprintf(stderr, "\n");
+ ucol_closeElements(iter);
#endif
- ((enumStruct *)context)->noOfClosures++;
- el.cPoints = decomp;
- el.cSize = noOfDec;
- el.noOfCEs = 0;
- el.prefix = el.prefixChars;
- el.prefixSize = 0;
-
- UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, &el);
- if(prefix == NULL) {
- el.cPoints = comp;
- el.cSize = len;
- el.prefix = el.prefixChars;
- el.prefixSize = 0;
- el.noOfCEs = 0;
- ucol_setText(colEl, decomp, noOfDec, status);
- while((el.CEs[el.noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
- el.noOfCEs++;
+ if(((enumStruct *)context)->closed != NULL) {
+ ((enumStruct *)context)->closed->add(u32);
+ }
+ ((enumStruct *)context)->noOfClosures++;
+ el.cPoints = (UChar *)decomp;
+ el.cSize = noOfDec;
+ el.noOfCEs = 0;
+ el.prefix = el.prefixChars;
+ el.prefixSize = 0;
+
+ UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, &el);
+ el.cPoints = comp;
+ el.cSize = len;
+ el.prefix = el.prefixChars;
+ el.prefixSize = 0;
+ if(prefix == NULL) {
+ el.noOfCEs = 0;
+ ucol_setText(colEl, decomp, noOfDec, status);
+ while((el.CEs[el.noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
+ el.noOfCEs++;
+ }
+ } else {
+ el.noOfCEs = 1;
+ el.CEs[0] = prefix->mapCE;
+ // This character uses a prefix. We have to add it
+ // to the unsafe table, as it decomposed form is already
+ // in. In Japanese, this happens for \u309e & \u30fe
+ // Since unsafeCPSet is static in ucol_elm, we are going
+ // to wrap it up in the uprv_uca_unsafeCPAddCCNZ function
+ }
+ uprv_uca_addAnElement(t, &el, status);
+ }
}
- } else {
- el.cPoints = comp;
- el.cSize = len;
- el.prefix = el.prefixChars;
- el.prefixSize = 0;
- el.noOfCEs = 1;
- el.CEs[0] = prefix->mapCE;
- // This character uses a prefix. We have to add it
- // to the unsafe table, as it decomposed form is already
- // in. In Japanese, this happens for \u309e & \u30fe
- // Since unsafeCPSet is static in ucol_elm, we are going
- // to wrap it up in the uprv_uca_unsafeCPAddCCNZ function
- }
- if(UCOL_ISTHAIPREVOWEL(el.cPoints[0])) {
- el.isThai = TRUE;
- } else {
- el.isThai = FALSE;
- }
-
- uprv_uca_addAnElement(t, &el, status);
- }
- }
- }
- }
- return TRUE;
+ }
+ }
+ return TRUE;
}
U_CDECL_END
-U_CAPI int32_t U_EXPORT2
-uprv_uca_canonicalClosure(tempUCATable *t, UErrorCode *status)
+static void
+uprv_uca_setMapCE(tempUCATable *t, UCAElements *element, UErrorCode *status) {
+ uint32_t expansion = 0;
+ int32_t j;
+
+ ExpansionTable *expansions = t->expansions;
+ if(element->noOfCEs == 2 // a two CE expansion
+ && isContinuation(element->CEs[1]) // which is a continuation
+ && (element->CEs[1] & (~(0xFF << 24 | UCOL_CONTINUATION_MARKER))) == 0 // that has only primaries in continuation,
+ && (((element->CEs[0]>>8) & 0xFF) == UCOL_BYTE_COMMON) // a common secondary
+ && ((element->CEs[0] & 0xFF) == UCOL_BYTE_COMMON) // and a common tertiary
+ ) {
+ element->mapCE = UCOL_SPECIAL_FLAG | (LONG_PRIMARY_TAG<<24) // a long primary special
+ | ((element->CEs[0]>>8) & 0xFFFF00) // first and second byte of primary
+ | ((element->CEs[1]>>24) & 0xFF); // third byte of primary
+ } else {
+ expansion = (uint32_t)(UCOL_SPECIAL_FLAG | (EXPANSION_TAG<<UCOL_TAG_SHIFT)
+ | (((uprv_uca_addExpansion(expansions, element->CEs[0], status)+(headersize>>2))<<4)
+ & 0xFFFFF0));
+
+ for(j = 1; j<(int32_t)element->noOfCEs; j++) {
+ uprv_uca_addExpansion(expansions, element->CEs[j], status);
+ }
+ if(element->noOfCEs <= 0xF) {
+ expansion |= element->noOfCEs;
+ } else {
+ uprv_uca_addExpansion(expansions, 0, status);
+ }
+ element->mapCE = expansion;
+ uprv_uca_setMaxExpansion(element->CEs[element->noOfCEs - 1],
+ (uint8_t)element->noOfCEs,
+ t->maxExpansions,
+ status);
+ }
+}
+
+static void
+uprv_uca_addFCD4AccentedContractions(tempUCATable *t,
+ UCollationElements* colEl,
+ UChar *data,
+ int32_t len,
+ UCAElements *el,
+ UErrorCode *status) {
+ UChar decomp[256], comp[256];
+ int32_t decLen, compLen;
+
+ decLen = unorm_normalize(data, len, UNORM_NFD, 0, decomp, 256, status);
+ compLen = unorm_normalize(data, len, UNORM_NFC, 0, comp, 256, status);
+ decomp[decLen] = comp[compLen] = 0;
+
+ el->cPoints = decomp;
+ el->cSize = decLen;
+ el->noOfCEs = 0;
+ el->prefixSize = 0;
+ el->prefix = el->prefixChars;
+
+ UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, el);
+ el->cPoints = comp;
+ el->cSize = compLen;
+ el->prefix = el->prefixChars;
+ el->prefixSize = 0;
+ if(prefix == NULL) {
+ el->noOfCEs = 0;
+ ucol_setText(colEl, decomp, decLen, status);
+ while((el->CEs[el->noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
+ el->noOfCEs++;
+ }
+ uprv_uca_setMapCE(t, el, status);
+ uprv_uca_addAnElement(t, el, status);
+ }
+ el->cPoints=NULL; /* don't leak reference to stack */
+}
+
+static void
+uprv_uca_addMultiCMContractions(tempUCATable *t,
+ UCollationElements* colEl,
+ tempTailorContext *c,
+ UCAElements *el,
+ UErrorCode *status) {
+ CombinClassTable *cmLookup = t->cmLookup;
+ UChar newDecomp[256];
+ int32_t maxComp, newDecLen;
+ const Normalizer2Impl *nfcImpl = Normalizer2Factory::getNFCImpl(*status);
+ if (U_FAILURE(*status)) {
+ return;
+ }
+ int16_t curClass = nfcImpl->getFCD16(c->tailoringCM) & 0xff;
+ CompData *precomp = c->precomp;
+ int32_t compLen = c->compLen;
+ UChar *comp = c->comp;
+ maxComp = c->precompLen;
+
+ for (int32_t j=0; j < maxComp; j++) {
+ int32_t count=0;
+ do {
+ if ( count == 0 ) { // Decompose the saved precomposed char.
+ UChar temp[2];
+ temp[0]=precomp[j].cp;
+ temp[1]=0;
+ newDecLen = unorm_normalize(temp, 1, UNORM_NFD, 0,
+ newDecomp, sizeof(newDecomp)/sizeof(UChar), status);
+ newDecomp[newDecLen++] = cmLookup->cPoints[c->cmPos];
+ }
+ else { // swap 2 combining marks when they are equal.
+ uprv_memcpy(newDecomp, c->decomp, sizeof(UChar)*(c->decompLen));
+ newDecLen = c->decompLen;
+ newDecomp[newDecLen++] = precomp[j].cClass;
+ }
+ newDecomp[newDecLen] = 0;
+ compLen = unorm_normalize(newDecomp, newDecLen, UNORM_NFC, 0,
+ comp, 256, status);
+ if (compLen==1) {
+ comp[compLen++] = newDecomp[newDecLen++] = c->tailoringCM;
+ comp[compLen] = newDecomp[newDecLen] = 0;
+ el->cPoints = newDecomp;
+ el->cSize = newDecLen;
+
+ UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, el);
+ el->cPoints = c->comp;
+ el->cSize = compLen;
+ el->prefix = el->prefixChars;
+ el->prefixSize = 0;
+ if(prefix == NULL) {
+ el->noOfCEs = 0;
+ ucol_setText(colEl, newDecomp, newDecLen, status);
+ while((el->CEs[el->noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
+ el->noOfCEs++;
+ }
+ uprv_uca_setMapCE(t, el, status);
+ uprv_uca_finalizeAddition(t, el, status);
+
+ // Save the current precomposed char and its class to find any
+ // other combining mark combinations.
+ precomp[c->precompLen].cp=comp[0];
+ precomp[c->precompLen].cClass = curClass;
+ c->precompLen++;
+ }
+ }
+ } while (++count<2 && (precomp[j].cClass == curClass));
+ }
+
+}
+
+static void
+uprv_uca_addTailCanonicalClosures(tempUCATable *t,
+ UCollationElements* colEl,
+ UChar baseCh,
+ UChar cMark,
+ UCAElements *el,
+ UErrorCode *status) {
+ CombinClassTable *cmLookup = t->cmLookup;
+ const Normalizer2Impl *nfcImpl = Normalizer2Factory::getNFCImpl(*status);
+ if (U_FAILURE(*status)) {
+ return;
+ }
+ int16_t maxIndex = nfcImpl->getFCD16(cMark) & 0xff;
+ UCAElements element;
+ uint16_t *index;
+ UChar decomp[256];
+ UChar comp[256];
+ CompData precomp[256]; // precomposed array
+ int32_t precompLen = 0; // count for precomp
+ int32_t i, len, decompLen, replacedPos;
+ tempTailorContext c;
+
+ if ( cmLookup == NULL ) {
+ return;
+ }
+ index = cmLookup->index;
+ int32_t cClass=nfcImpl->getFCD16(cMark) & 0xff;
+ maxIndex = (int32_t)index[(nfcImpl->getFCD16(cMark) & 0xff)-1];
+ c.comp = comp;
+ c.decomp = decomp;
+ c.precomp = precomp;
+ c.tailoringCM = cMark;
+
+ if (cClass>0) {
+ maxIndex = (int32_t)index[cClass-1];
+ }
+ else {
+ maxIndex=0;
+ }
+ decomp[0]=baseCh;
+ for ( i=0; i<maxIndex ; i++ ) {
+ decomp[1] = cmLookup->cPoints[i];
+ decomp[2]=0;
+ decompLen=2;
+ len = unorm_normalize(decomp, decompLen, UNORM_NFC, 0, comp, 256, status);
+ if (len==1) {
+ // Save the current precomposed char and its class to find any
+ // other combining mark combinations.
+ precomp[precompLen].cp=comp[0];
+ precomp[precompLen].cClass =
+ index[nfcImpl->getFCD16(decomp[1]) & 0xff];
+ precompLen++;
+ replacedPos=0;
+ for (decompLen=0; decompLen< (int32_t)el->cSize; decompLen++) {
+ decomp[decompLen] = el->cPoints[decompLen];
+ if (decomp[decompLen]==cMark) {
+ replacedPos = decompLen; // record the position for later use
+ }
+ }
+ if ( replacedPos != 0 ) {
+ decomp[replacedPos]=cmLookup->cPoints[i];
+ }
+ decomp[decompLen] = 0;
+ len = unorm_normalize(decomp, decompLen, UNORM_NFC, 0, comp, 256, status);
+ comp[len++] = decomp[decompLen++] = cMark;
+ comp[len] = decomp[decompLen] = 0;
+ element.cPoints = decomp;
+ element.cSize = decompLen;
+ element.noOfCEs = 0;
+ element.prefix = el->prefixChars;
+ element.prefixSize = 0;
+
+ UCAElements *prefix=(UCAElements *)uhash_get(t->prefixLookup, &element);
+ element.cPoints = comp;
+ element.cSize = len;
+ element.prefix = el->prefixChars;
+ element.prefixSize = 0;
+ if(prefix == NULL) {
+ element.noOfCEs = 0;
+ ucol_setText(colEl, decomp, decompLen, status);
+ while((element.CEs[element.noOfCEs] = ucol_next(colEl, status)) != (uint32_t)UCOL_NULLORDER) {
+ element.noOfCEs++;
+ }
+ uprv_uca_setMapCE(t, &element, status);
+ uprv_uca_finalizeAddition(t, &element, status);
+ }
+
+ // This is a fix for tailoring contractions with accented
+ // character at the end of contraction string.
+ if ((len>2) &&
+ (nfcImpl->getFCD16(comp[len-2]) & 0xff00)==0) {
+ uprv_uca_addFCD4AccentedContractions(t, colEl, comp, len, &element, status);
+ }
+
+ if (precompLen >1) {
+ c.compLen = len;
+ c.decompLen = decompLen;
+ c.precompLen = precompLen;
+ c.cmPos = i;
+ uprv_uca_addMultiCMContractions(t, colEl, &c, &element, status);
+ precompLen = c.precompLen;
+ }
+ }
+ }
+}
+
+U_CFUNC int32_t U_EXPORT2
+uprv_uca_canonicalClosure(tempUCATable *t,
+ UColTokenParser *src,
+ UnicodeSet *closed,
+ UErrorCode *status)
{
- enumStruct context;
- context.noOfClosures = 0;
- if(U_SUCCESS(*status)) {
+ enumStruct context;
+ context.closed = closed;
+ context.noOfClosures = 0;
+ UCAElements el;
+ UColToken *tok;
+ uint32_t i = 0, j = 0;
+ UChar baseChar, firstCM;
+ context.nfcImpl=Normalizer2Factory::getNFCImpl(*status);
+ if(U_FAILURE(*status)) {
+ return 0;
+ }
+
UCollator *tempColl = NULL;
tempUCATable *tempTable = uprv_uca_cloneTempTable(t, status);
+ // Check for null pointer
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
UCATableHeader *tempData = uprv_uca_assembleTable(tempTable, status);
tempColl = ucol_initCollator(tempData, 0, t->UCA, status);
- uprv_uca_closeTempTable(tempTable);
+ if ( tempTable->cmLookup != NULL ) {
+ t->cmLookup = tempTable->cmLookup; // copy over to t
+ tempTable->cmLookup = NULL;
+ }
+ uprv_uca_closeTempTable(tempTable);
if(U_SUCCESS(*status)) {
- tempColl->rb = NULL;
- tempColl->elements = NULL;
- tempColl->validLocale = NULL;
- tempColl->requestedLocale = NULL;
- tempColl->hasRealData = TRUE;
- tempColl->freeImageOnClose = TRUE;
+ tempColl->ucaRules = NULL;
+ tempColl->actualLocale = NULL;
+ tempColl->validLocale = NULL;
+ tempColl->requestedLocale = NULL;
+ tempColl->hasRealData = TRUE;
+ tempColl->freeImageOnClose = TRUE;
} else if(tempData != 0) {
- uprv_free(tempData);
+ uprv_free(tempData);
}
/* produce canonical closure */
UCollationElements* colEl = ucol_openElements(tempColl, NULL, 0, status);
-
+ // Check for null pointer
+ if (U_FAILURE(*status)) {
+ return 0;
+ }
context.t = t;
context.tempColl = tempColl;
context.colEl = colEl;
context.status = status;
u_enumCharTypes(_enumCategoryRangeClosureCategory, &context);
+ if ( (src==NULL) || !src->buildCCTabFlag ) {
+ ucol_closeElements(colEl);
+ ucol_close(tempColl);
+ return context.noOfClosures; // no extra contraction needed to add
+ }
+
+ for (i=0; i < src->resultLen; i++) {
+ baseChar = firstCM= (UChar)0;
+ tok = src->lh[i].first;
+ while (tok != NULL && U_SUCCESS(*status)) {
+ el.prefix = el.prefixChars;
+ el.cPoints = el.uchars;
+ if(tok->prefix != 0) {
+ el.prefixSize = tok->prefix>>24;
+ uprv_memcpy(el.prefix, src->source + (tok->prefix & 0x00FFFFFF), el.prefixSize*sizeof(UChar));
+
+ el.cSize = (tok->source >> 24)-(tok->prefix>>24);
+ uprv_memcpy(el.uchars, (tok->source & 0x00FFFFFF)+(tok->prefix>>24) + src->source, el.cSize*sizeof(UChar));
+ } else {
+ el.prefixSize = 0;
+ *el.prefix = 0;
+
+ el.cSize = (tok->source >> 24);
+ uprv_memcpy(el.uchars, (tok->source & 0x00FFFFFF) + src->source, el.cSize*sizeof(UChar));
+ }
+ if(src->UCA != NULL) {
+ for(j = 0; j<el.cSize; j++) {
+ int16_t fcd = context.nfcImpl->getFCD16(el.cPoints[j]);
+ if ( (fcd & 0xff) == 0 ) {
+ baseChar = el.cPoints[j]; // last base character
+ firstCM=0; // reset combining mark value
+ }
+ else {
+ if ( (baseChar!=0) && (firstCM==0) ) {
+ firstCM = el.cPoints[j]; // first combining mark
+ }
+ }
+ }
+ }
+ if ( (baseChar!= (UChar)0) && (firstCM != (UChar)0) ) {
+ // find all the canonical rules
+ uprv_uca_addTailCanonicalClosures(t, colEl, baseChar, firstCM, &el, status);
+ }
+ tok = tok->next;
+ }
+ }
ucol_closeElements(colEl);
ucol_close(tempColl);
- }
- return context.noOfClosures;
-}
-U_NAMESPACE_END
+ return context.noOfClosures;
+}
#endif /* #if !UCONFIG_NO_COLLATION */
-
-