mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-14 17:24:01 +00:00
ICU-1003 removing incremental compare API
X-SVN-Rev: 5021
This commit is contained in:
parent
9268bcb6a4
commit
a7268db185
6 changed files with 0 additions and 882 deletions
|
@ -73,9 +73,6 @@ const uint32_t tblcoll_STACK_BUFFER_LENGTH_ = 1024;
|
|||
*/
|
||||
#define STACK_BUFFER_LENGTH_ 1024
|
||||
|
||||
/* forward declarations ----------------------------------------------------- */
|
||||
|
||||
U_CAPI UChar forwardCharIteratorGlue(void *iterator);
|
||||
|
||||
/* RuleBasedCollator declaration ----------------------------------------- */
|
||||
|
||||
|
@ -574,14 +571,6 @@ Collator* RuleBasedCollator::safeClone(void)
|
|||
return result;
|
||||
}
|
||||
|
||||
Collator::EComparisonResult RuleBasedCollator::compare(
|
||||
ForwardCharacterIterator &source,
|
||||
ForwardCharacterIterator &target)
|
||||
{
|
||||
return getEComparisonResult(
|
||||
ucol_strcollinc(ucollator, forwardCharIteratorGlue, &source,
|
||||
forwardCharIteratorGlue, &target));
|
||||
}
|
||||
|
||||
int32_t RuleBasedCollator::getSortKey(const UnicodeString& source,
|
||||
uint8_t *result, int32_t resultLength)
|
||||
|
@ -790,13 +779,3 @@ const char* RuleBasedCollator::kFilenameSuffix = ".col";
|
|||
char RuleBasedCollator::fgClassID = 0;
|
||||
|
||||
/* other methods not belonging to any classes ------------------------------- */
|
||||
|
||||
U_CAPI UChar forwardCharIteratorGlue(void *iterator)
|
||||
{
|
||||
ForwardCharacterIterator *iter = ((ForwardCharacterIterator *)iterator);
|
||||
UChar result = iter->nextPostInc();
|
||||
if (result == ForwardCharacterIterator::DONE)
|
||||
return 0xFFFF;
|
||||
else
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -4877,478 +4877,6 @@ commonReturn:
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
void init_incrementalContext(const UCollator *coll, UCharForwardIterator *source, void *sourceContext, incrementalContext *s) {
|
||||
s->len = s->stringP = s->stackString ;
|
||||
s->capacity = s->stackString+UCOL_MAX_BUFFER;
|
||||
s->CEpos = s->toReturn = s->CEs;
|
||||
s->source = source;
|
||||
s->sourceContext = sourceContext;
|
||||
s->currentChar = 0xFFFF;
|
||||
s->lastChar = 0xFFFF;
|
||||
s->panic = FALSE;
|
||||
s->coll = coll;
|
||||
}
|
||||
|
||||
/* This is the incremental function */
|
||||
U_CAPI UCollationResult ucol_strcollinc(const UCollator *coll,
|
||||
UCharForwardIterator *source, void *sourceContext,
|
||||
UCharForwardIterator *target, void *targetContext)
|
||||
{
|
||||
incrementalContext sColl, tColl;
|
||||
|
||||
init_incrementalContext(coll, source, sourceContext, &sColl);
|
||||
init_incrementalContext(coll, target, targetContext, &tColl);
|
||||
|
||||
UCollationResult result = UCOL_EQUAL;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
if(coll->normalizationMode != UCOL_OFF) { /* run away screaming!!!! */
|
||||
return alternateIncrementalProcessing(coll, &sColl, &tColl);
|
||||
}
|
||||
|
||||
UColAttributeValue strength = coll->strength;
|
||||
UBool initialCheckSecTer = (strength >= UCOL_SECONDARY);
|
||||
|
||||
UBool checkSecTer = initialCheckSecTer;
|
||||
UBool checkTertiary = (strength >= UCOL_TERTIARY);
|
||||
UBool checkQuad = (strength >= UCOL_QUATERNARY);
|
||||
UBool checkIdent = (strength == UCOL_IDENTICAL);
|
||||
UBool checkCase = (coll->caseLevel == UCOL_ON);
|
||||
UBool isFrenchSec = (coll->frenchCollation == UCOL_ON) && checkSecTer;
|
||||
UBool shifted = (coll->alternateHandling == UCOL_SHIFTED);
|
||||
UBool qShifted = shifted && checkQuad;
|
||||
|
||||
uint32_t sCEsArray[512], tCEsArray[512];
|
||||
uint32_t *sCEs = sCEsArray, *tCEs = tCEsArray;
|
||||
uint32_t *sCEend = sCEs+512, *tCEend = tCEs+512;
|
||||
uint8_t caseSwitch = coll->caseSwitch;
|
||||
uint8_t tertiaryMask = coll->tertiaryMask;
|
||||
|
||||
uint32_t LVT = (shifted)?((coll->variableMax1)<<24 | (coll->variableMax2)<<16):0;
|
||||
|
||||
uint32_t secS = 0, secT = 0;
|
||||
|
||||
uint32_t sOrder=0, tOrder=0;
|
||||
if(!shifted) {
|
||||
for(;;) {
|
||||
if(sCEs == sCEend || tCEs == tCEend) {
|
||||
return alternateIncrementalProcessing(coll, &sColl, &tColl);
|
||||
}
|
||||
|
||||
/* Get the next collation element in each of the strings, unless */
|
||||
/* we've been requested to skip it. */
|
||||
while(sOrder == 0) {
|
||||
sOrder = ucol_getIncrementalCE(coll, &sColl, &status);
|
||||
sOrder ^= caseSwitch;
|
||||
*(sCEs++) = sOrder;
|
||||
sOrder &= UCOL_PRIMARYMASK;
|
||||
}
|
||||
|
||||
while(tOrder == 0) {
|
||||
tOrder = ucol_getIncrementalCE(coll, &tColl, &status);
|
||||
tOrder ^= caseSwitch;
|
||||
*(tCEs++) = tOrder;
|
||||
tOrder &= UCOL_PRIMARYMASK;
|
||||
}
|
||||
|
||||
if((sOrder == (UCOL_NO_MORE_CES & UCOL_PRIMARYORDERMASK) && sColl.panic == TRUE) ||
|
||||
(tOrder == (UCOL_NO_MORE_CES & UCOL_PRIMARYORDERMASK) && tColl.panic == TRUE)) {
|
||||
return alternateIncrementalProcessing(coll, &sColl, &tColl);
|
||||
}
|
||||
|
||||
if(sOrder == tOrder) {
|
||||
if(sOrder == (UCOL_NO_MORE_CES & UCOL_PRIMARYORDERMASK)) {
|
||||
|
||||
break;
|
||||
} else {
|
||||
sOrder = 0; tOrder = 0;
|
||||
continue;
|
||||
}
|
||||
} else if(sOrder < tOrder) {
|
||||
return UCOL_LESS;
|
||||
} else {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
} /* no primary difference... do the rest from the buffers */
|
||||
} else { /* shifted - do a slightly more complicated processing */
|
||||
for(;;) {
|
||||
UBool sInShifted = FALSE;
|
||||
UBool tInShifted = FALSE;
|
||||
|
||||
if(sCEs == sCEend || tCEs == tCEend) {
|
||||
return alternateIncrementalProcessing(coll, &sColl, &tColl);
|
||||
}
|
||||
|
||||
/* This is where abridged version for shifted should go */
|
||||
for(;;) {
|
||||
sOrder = ucol_getIncrementalCE(coll, &sColl, &status);
|
||||
if(sOrder == UCOL_NO_MORE_CES) {
|
||||
if(sColl.panic == TRUE) {
|
||||
return alternateIncrementalProcessing(coll, &sColl, &tColl);
|
||||
}
|
||||
*(sCEs++) = sOrder;
|
||||
break;
|
||||
} else if(sOrder == 0) {
|
||||
continue;
|
||||
} else if(isContinuation(sOrder)) {
|
||||
if((sOrder & UCOL_PRIMARYMASK) > 0) { /* There is primary value */
|
||||
if(sInShifted) {
|
||||
sOrder &= UCOL_PRIMARYMASK;
|
||||
*(sCEs++) = sOrder;
|
||||
continue;
|
||||
} else {
|
||||
sOrder ^= caseSwitch;
|
||||
*(sCEs++) = sOrder;
|
||||
break;
|
||||
}
|
||||
} else { /* Just lower level values */
|
||||
if(sInShifted) {
|
||||
continue;
|
||||
} else {
|
||||
sOrder ^= caseSwitch;
|
||||
*(sCEs++) = sOrder;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else { /* regular */
|
||||
if(sOrder > LVT) {
|
||||
*(sCEs++) = sOrder;
|
||||
break;
|
||||
} else {
|
||||
if((sOrder & UCOL_PRIMARYMASK) > 0) {
|
||||
sInShifted = TRUE;
|
||||
sOrder &= UCOL_PRIMARYMASK;
|
||||
*(sCEs++) = sOrder;
|
||||
continue;
|
||||
} else {
|
||||
sOrder ^= caseSwitch;
|
||||
*(sCEs++) = sOrder;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sOrder &= UCOL_PRIMARYMASK;
|
||||
sInShifted = FALSE;
|
||||
|
||||
for(;;) {
|
||||
tOrder = ucol_getIncrementalCE(coll, &tColl, &status);
|
||||
if(tOrder == UCOL_NO_MORE_CES) {
|
||||
if(tColl.panic == TRUE) {
|
||||
return alternateIncrementalProcessing(coll, &sColl, &tColl);
|
||||
}
|
||||
*(tCEs++) = tOrder;
|
||||
break;
|
||||
} else if(tOrder == 0) {
|
||||
continue;
|
||||
} else if(isContinuation(tOrder)) {
|
||||
if((tOrder & UCOL_PRIMARYMASK) > 0) { /* There is primary value */
|
||||
if(tInShifted) {
|
||||
tOrder &= UCOL_PRIMARYMASK;
|
||||
*(tCEs++) = tOrder;
|
||||
continue;
|
||||
} else {
|
||||
tOrder ^= caseSwitch;
|
||||
*(tCEs++) = tOrder;
|
||||
break;
|
||||
}
|
||||
} else { /* Just lower level values */
|
||||
if(tInShifted) {
|
||||
continue;
|
||||
} else {
|
||||
tOrder ^= caseSwitch;
|
||||
*(tCEs++) = tOrder;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else { /* regular */
|
||||
if(tOrder > LVT) {
|
||||
*(tCEs++) = tOrder;
|
||||
break;
|
||||
} else {
|
||||
if((tOrder & UCOL_PRIMARYMASK) > 0) {
|
||||
tInShifted = TRUE;
|
||||
tOrder &= UCOL_PRIMARYMASK;
|
||||
*(tCEs++) = tOrder;
|
||||
continue;
|
||||
} else {
|
||||
tOrder ^= caseSwitch;
|
||||
*(tCEs++) = tOrder;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tOrder &= UCOL_PRIMARYMASK;
|
||||
tInShifted = FALSE;
|
||||
|
||||
if(sOrder == tOrder) {
|
||||
if(sOrder == UCOL_NO_MORE_CES_PRIMARY) {
|
||||
break;
|
||||
} else {
|
||||
sOrder = 0; tOrder = 0;
|
||||
continue;
|
||||
}
|
||||
} else if(sOrder < tOrder) {
|
||||
return UCOL_LESS;
|
||||
} else {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
} /* no primary difference... do the rest from the buffers */
|
||||
}
|
||||
|
||||
/* now, we're gonna reexamine collected CEs */
|
||||
sCEend = sCEs;
|
||||
tCEend = tCEs;
|
||||
|
||||
/* This is the secondary level of comparison */
|
||||
if(checkSecTer) {
|
||||
if(!isFrenchSec) { /* normal */
|
||||
sCEs = sCEsArray;
|
||||
tCEs = tCEsArray;
|
||||
for(;;) {
|
||||
while (secS == 0) {
|
||||
secS = *(sCEs++) & UCOL_SECONDARYMASK;
|
||||
}
|
||||
|
||||
while(secT == 0) {
|
||||
secT = *(tCEs++) & UCOL_SECONDARYMASK;
|
||||
}
|
||||
|
||||
if(secS == secT) {
|
||||
if(secS == UCOL_NO_MORE_CES_SECONDARY) {
|
||||
break;
|
||||
} else {
|
||||
secS = 0; secT = 0;
|
||||
continue;
|
||||
}
|
||||
} else if(secS < secT) {
|
||||
return UCOL_LESS;
|
||||
} else {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
}
|
||||
} else { /* do the French */
|
||||
uint32_t *sCESave = NULL;
|
||||
uint32_t *tCESave = NULL;
|
||||
sCEs = sCEend-2; /* this could also be sCEs-- if needs to be optimized */
|
||||
tCEs = tCEend-2;
|
||||
for(;;) {
|
||||
while (secS == 0 && sCEs >= sCEsArray) {
|
||||
if(sCESave == 0) {
|
||||
secS = *(sCEs--) & 0xFF80;
|
||||
if(isContinuation(secS)) {
|
||||
while(isContinuation(secS = *(sCEs--) & 0xFF80));
|
||||
/* after this, secS has the start of continuation, and sCEs points before that */
|
||||
sCESave = sCEs; /* we save it, so that we know where to come back AND that we need to go forward */
|
||||
sCEs+=2; /* need to point to the first continuation CP */
|
||||
/* However, now you can just continue doing stuff */
|
||||
}
|
||||
} else {
|
||||
secS = *(sCEs++) & 0xFF80;
|
||||
if(!isContinuation(secS)) { /* This means we have finished with this cont */
|
||||
sCEs = sCESave; /* reset the pointer to before continuation */
|
||||
sCESave = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
secS &= UCOL_SECONDARYMASK; /* remove the continuation bit */
|
||||
}
|
||||
|
||||
while(secT == 0 && tCEs >= tCEsArray) {
|
||||
if(tCESave == 0) {
|
||||
secT = *(tCEs--) & 0xFF80;
|
||||
if(isContinuation(secT)) {
|
||||
while(isContinuation(secT = *(tCEs--) & 0xFF80));
|
||||
/* after this, secS has the start of continuation, and sCEs points before that */
|
||||
tCESave = tCEs; /* we save it, so that we know where to come back AND that we need to go forward */
|
||||
tCEs+=2; /* need to point to the first continuation CP */
|
||||
/* However, now you can just continue doing stuff */
|
||||
}
|
||||
} else {
|
||||
secT = *(tCEs++) & 0xFF80;
|
||||
if(!isContinuation(secT)) { /* This means we have finished with this cont */
|
||||
tCEs = tCESave; /* reset the pointer to before continuation */
|
||||
tCESave = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
secT &= UCOL_SECONDARYMASK; /* remove the continuation bit */
|
||||
}
|
||||
|
||||
if(secS == secT) {
|
||||
if(secS == UCOL_NO_MORE_CES_SECONDARY || (sCEs < sCEsArray && tCEs < tCEsArray)) {
|
||||
break;
|
||||
} else {
|
||||
secS = 0; secT = 0;
|
||||
continue;
|
||||
}
|
||||
} else if(secS < secT) {
|
||||
return UCOL_LESS;
|
||||
} else {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* doing the case bit */
|
||||
if(checkCase) {
|
||||
sCEs = sCEsArray;
|
||||
tCEs = tCEsArray;
|
||||
for(;;) {
|
||||
while((secS & UCOL_REMOVE_CASE) == 0) {
|
||||
if(!isContinuation(*sCEs++)) {
|
||||
secS =*(sCEs-1) & UCOL_TERT_CASE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
while((secT & UCOL_REMOVE_CASE) == 0) {
|
||||
if(!isContinuation(*tCEs++)) {
|
||||
secT = *(tCEs-1) & UCOL_TERT_CASE_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
if((secS & UCOL_CASE_BIT_MASK) < (secT & UCOL_CASE_BIT_MASK)) {
|
||||
return UCOL_LESS;
|
||||
} else if((secS & UCOL_CASE_BIT_MASK) > (secT & UCOL_CASE_BIT_MASK)) {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
|
||||
if((secS & UCOL_REMOVE_CASE) == UCOL_NO_MORE_CES_TERTIARY
|
||||
|| (secT & UCOL_REMOVE_CASE) == UCOL_NO_MORE_CES_TERTIARY ) {
|
||||
break;
|
||||
} else {
|
||||
secS = 0;
|
||||
secT = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Tertiary level */
|
||||
if(checkTertiary) {
|
||||
secS = 0;
|
||||
secT = 0;
|
||||
sCEs = sCEsArray;
|
||||
tCEs = tCEsArray;
|
||||
for(;;) {
|
||||
while((secS & UCOL_REMOVE_CASE) == 0) {
|
||||
secS = *(sCEs++) & tertiaryMask;
|
||||
}
|
||||
|
||||
while((secT & UCOL_REMOVE_CASE) == 0) {
|
||||
secT = *(tCEs++) & tertiaryMask;
|
||||
}
|
||||
|
||||
if(secS == secT) {
|
||||
if((secS & UCOL_REMOVE_CASE) == 1) {
|
||||
break;
|
||||
} else {
|
||||
secS = 0; secT = 0;
|
||||
continue;
|
||||
}
|
||||
} else if(secS < secT) {
|
||||
return UCOL_LESS;
|
||||
} else {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(qShifted) {
|
||||
UBool sInShifted = TRUE;
|
||||
UBool tInShifted = TRUE;
|
||||
secS = 0;
|
||||
secT = 0;
|
||||
sCEs = sCEsArray;
|
||||
tCEs = tCEsArray;
|
||||
for(;;) {
|
||||
while(secS == 0 && secS != UCOL_NO_MORE_CES || (isContinuation(secS) && !sInShifted)) {
|
||||
secS = *(sCEs++);
|
||||
if(isContinuation(secS) && !sInShifted) {
|
||||
continue;
|
||||
}
|
||||
if(secS > LVT || (secS & UCOL_PRIMARYMASK) == 0) {
|
||||
secS = UCOL_PRIMARYMASK;
|
||||
sInShifted = FALSE;
|
||||
} else {
|
||||
sInShifted = TRUE;
|
||||
}
|
||||
}
|
||||
secS &= UCOL_PRIMARYMASK;
|
||||
|
||||
|
||||
while(secT == 0 && secT != UCOL_NO_MORE_CES || (isContinuation(secT) && !tInShifted)) {
|
||||
secT = *(tCEs++);
|
||||
if(isContinuation(secT) && !tInShifted) {
|
||||
continue;
|
||||
}
|
||||
if(secT > LVT || (secT & UCOL_PRIMARYMASK) == 0) {
|
||||
secT = UCOL_PRIMARYMASK;
|
||||
tInShifted = FALSE;
|
||||
} else {
|
||||
tInShifted = TRUE;
|
||||
}
|
||||
}
|
||||
secT &= UCOL_PRIMARYMASK;
|
||||
|
||||
if(secS == secT) {
|
||||
if(secS == UCOL_NO_MORE_CES_PRIMARY) {
|
||||
break;
|
||||
} else {
|
||||
secS = 0; secT = 0;
|
||||
continue;
|
||||
}
|
||||
} else if(secS < secT) {
|
||||
return UCOL_LESS;
|
||||
} else {
|
||||
return UCOL_GREATER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* For IDENTICAL comparisons, we use a bitwise character comparison */
|
||||
/* as a tiebreaker if all else is equal */
|
||||
/* NOTE: The java code compares result with 0, and */
|
||||
/* puts the result of the string comparison directly into result */
|
||||
/* if (result == UCOL_EQUAL && strength == UCOL_IDENTICAL) */
|
||||
if(checkIdent)
|
||||
{
|
||||
UnicodeString sourceDecomp, targetDecomp;
|
||||
|
||||
int8_t comparison;
|
||||
|
||||
/* synwee : implemented in c++ since normalizer is implemented there */
|
||||
Normalizer::EMode mode = Normalizer::getNormalizerEMode(
|
||||
ucol_getNormalization(coll), status);
|
||||
|
||||
Normalizer::normalize(UnicodeString(sColl.stringP, sColl.len-sColl.stringP-1),
|
||||
mode, 0, sourceDecomp, status);
|
||||
|
||||
Normalizer::normalize(UnicodeString(tColl.stringP, tColl.len-tColl.stringP-1),
|
||||
mode, 0, targetDecomp, status);
|
||||
|
||||
comparison = sourceDecomp.compare(targetDecomp);
|
||||
|
||||
if (comparison < 0)
|
||||
{
|
||||
result = UCOL_LESS;
|
||||
}
|
||||
else if (comparison == 0)
|
||||
{
|
||||
result = UCOL_EQUAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = UCOL_GREATER;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* convenience function for comparing strings */
|
||||
U_CAPI UBool
|
||||
ucol_greater( const UCollator *coll,
|
||||
|
@ -5384,316 +4912,3 @@ ucol_equal( const UCollator *coll,
|
|||
return (ucol_strcoll(coll, source, sourceLength, target, targetLength)
|
||||
== UCOL_EQUAL);
|
||||
}
|
||||
|
||||
|
||||
int32_t ucol_getIncrementalCE(const UCollator *coll, incrementalContext *ctx, UErrorCode *status) {
|
||||
uint32_t order;
|
||||
if (ctx->CEpos > ctx->toReturn) { /* Are there any CEs from previous expansions? */
|
||||
order = *(ctx->toReturn++); /* if so, return them */
|
||||
if(ctx->CEpos == ctx->toReturn) {
|
||||
ctx->CEpos = ctx->toReturn = ctx->CEs;
|
||||
}
|
||||
} else { /* This is the real business now */
|
||||
if(ctx->lastChar == 0xFFFF) {
|
||||
ctx->currentChar = ctx->source(ctx->sourceContext);
|
||||
incctx_appendChar(ctx, ctx->currentChar);
|
||||
if(ctx->currentChar == 0xFFFF) {
|
||||
return UCOL_NO_MORE_CES;
|
||||
}
|
||||
} else {
|
||||
ctx->currentChar = ctx->lastChar;
|
||||
ctx->lastChar = 0xFFFF;
|
||||
}
|
||||
|
||||
UChar ch = ctx->currentChar;
|
||||
if(ch <= 0xFF) { /* if it's Latin One, we'll try to fast track it */
|
||||
order = coll->latinOneMapping[ch]; /* by looking in up in an array */
|
||||
} else { /* otherwise, */
|
||||
order = ucmp32_get(coll->mapping, ch); /* we'll go for slightly slower trie */
|
||||
}
|
||||
if(order >= UCOL_NOT_FOUND) { /* if a CE is special */
|
||||
order = ucol_getIncrementalSpecialCE(coll, order, ctx, status); /* and try to get the special CE */
|
||||
if(order == UCOL_NOT_FOUND) { /* We couldn't find a good CE in the tailoring */
|
||||
order = ucol_getIncrementalUCA(ch, ctx, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* This means that contraction should spit back the last codepoint eaten! */
|
||||
return order; /* return the CE */
|
||||
}
|
||||
|
||||
/* This function tries to get a CE from UCA, which should be always around */
|
||||
/* UChar is passed in in order to speed things up */
|
||||
/* here is also the generation of implicit CEs */
|
||||
uint32_t ucol_getIncrementalUCA(UChar ch, incrementalContext *collationSource, UErrorCode *status) {
|
||||
uint32_t order;
|
||||
if(ch < 0xFF) { /* so we'll try to find it in the UCA */
|
||||
order = UCA->latinOneMapping[ch];
|
||||
} else {
|
||||
order = ucmp32_get(UCA->mapping, ch);
|
||||
}
|
||||
if(order >= UCOL_NOT_FOUND) { /* UCA also gives us a special CE */
|
||||
order = ucol_getIncrementalSpecialCE(UCA, order, collationSource, status);
|
||||
}
|
||||
if(order == UCOL_NOT_FOUND) { /* This is where we have to resort to algorithmical generation */
|
||||
/* We have to check if ch is possibly a first surrogate - then we need to take the next code unit */
|
||||
/* and make a bigger CE */
|
||||
const uint32_t
|
||||
SBase = 0xAC00, LBase = 0x1100, VBase = 0x1161, TBase = 0x11A7,
|
||||
LCount = 19, VCount = 21, TCount = 28,
|
||||
NCount = VCount * TCount, // 588
|
||||
SCount = LCount * NCount; // 11172
|
||||
//LLimit = LBase + LCount, // 1113
|
||||
//VLimit = VBase + VCount, // 1176
|
||||
//TLimit = TBase + TCount, // 11C3
|
||||
//SLimit = SBase + SCount; // D7A4
|
||||
|
||||
// once we have failed to find a match for codepoint cp, and are in the implicit code.
|
||||
|
||||
uint32_t L = ch - SBase;
|
||||
//if (ch < SLimit) { // since it is unsigned, catchs zero case too
|
||||
if (L < SCount) { // since it is unsigned, catchs zero case too
|
||||
|
||||
// divide into pieces
|
||||
|
||||
uint32_t T = L % TCount; // we do it in this order since some compilers can do % and / in one operation
|
||||
L /= TCount;
|
||||
uint32_t V = L % VCount;
|
||||
L /= VCount;
|
||||
|
||||
// offset them
|
||||
|
||||
L += LBase;
|
||||
V += VBase;
|
||||
T += TBase;
|
||||
|
||||
// return the first CE, but first put the rest into the expansion buffer
|
||||
if (!collationSource->coll->image->jamoSpecial) { // FAST PATH
|
||||
|
||||
*(collationSource->CEpos++) = ucmp32_get(UCA->mapping, V);
|
||||
if (T != TBase) {
|
||||
*(collationSource->CEpos++) = ucmp32_get(UCA->mapping, T);
|
||||
}
|
||||
|
||||
return ucmp32_get(UCA->mapping, L); // return first one
|
||||
|
||||
} else { // Jamo is Special
|
||||
collIterate jamos;
|
||||
UChar jamoString[3];
|
||||
uint32_t CE = UCOL_NOT_FOUND;
|
||||
const UCollator *collator = collationSource->coll;
|
||||
jamoString[0] = (UChar)L;
|
||||
jamoString[1] = (UChar)V;
|
||||
if (T != TBase) {
|
||||
jamoString[2] = (UChar)T;
|
||||
IInit_collIterate(collator, jamoString, 3, &jamos);
|
||||
} else {
|
||||
IInit_collIterate(collator, jamoString, 2, &jamos);
|
||||
}
|
||||
|
||||
CE = ucol_IGetNextCE(collator, &jamos, status);
|
||||
|
||||
while(CE != UCOL_NO_MORE_CES) {
|
||||
*(collationSource->CEpos++) = CE;
|
||||
CE = ucol_IGetNextCE(collator, &jamos, status);
|
||||
}
|
||||
return *(collationSource->toReturn++);
|
||||
|
||||
/*
|
||||
ucol_getJamoCEs(collationSource->coll, L, &collationSource->CEpos);
|
||||
ucol_getJamoCEs(collationSource->coll, V, &collationSource->CEpos);
|
||||
if (T != TBase) {
|
||||
ucol_getJamoCEs(collationSource->coll, T, &collationSource->CEpos);
|
||||
}
|
||||
return *(collationSource->toReturn++);
|
||||
*/
|
||||
|
||||
/*
|
||||
// do recursive processing of L, V, and T with fetchCE (but T only if not equal to TBase!!)
|
||||
// Since fetchCE returns a CE, and (potentially) stuffs items into the ce buffer,
|
||||
// this is how it is done.
|
||||
|
||||
int firstCE = fetchCE(L, ...);
|
||||
int* lastExpansion = expansionBufferEnd++; // set pointer, leave gap!
|
||||
*lastExpansion = fetchCE(V,...);
|
||||
if (T != TBase) {
|
||||
lastExpansion = expansionBufferEnd++; // set pointer, leave gap!
|
||||
*lastExpansion = fetchCE(T,...);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
collationSource->lastChar = collationSource->source(collationSource->sourceContext);
|
||||
incctx_appendChar(collationSource, collationSource->lastChar);
|
||||
|
||||
if(UTF_IS_FIRST_SURROGATE(ch)) {
|
||||
if( (collationSource->lastChar != 0xFFFF) &&
|
||||
UTF_IS_SECOND_SURROGATE((collationSource->lastChar))) {
|
||||
//uint32_t cp = (((ch)<<10UL)+(collationSource->lastChar)-((0xd800<<10UL)+0xdc00));
|
||||
uint32_t cp = ((((uint32_t)ch)<<10UL)+(collationSource->lastChar)-(((uint32_t)0xd800<<10UL)+0xdc00-0x10000));
|
||||
collationSource->lastChar = 0xFFFF; /*used up*/
|
||||
if ((cp & 0xFFFE) == 0xFFFE || (0xD800 <= cp && cp <= 0xDC00)) {
|
||||
return 0; /* illegal code value, use completely ignoreable! */
|
||||
}
|
||||
/* This is a code point minus 0x10000, that's what algorithm requires */
|
||||
order = 0xE0010303 | (cp & 0xFFE00) << 8;
|
||||
|
||||
*(collationSource->CEpos++) = 0x80200080 | (cp & 0x001FF) << 22;
|
||||
} else {
|
||||
return 0; /* completely ignorable */
|
||||
}
|
||||
} else {
|
||||
/* otherwise */
|
||||
if(UTF_IS_SECOND_SURROGATE((ch)) || (ch & 0xFFFE) == 0xFFFE) {
|
||||
return 0; /* completely ignorable */
|
||||
}
|
||||
/* Make up an artifical CE from code point as per UCA */
|
||||
order = 0xD0800303 | (ch & 0xF000) << 12 | (ch & 0x0FE0) << 11;
|
||||
*(collationSource->CEpos++) = 0x04000080 | (ch & 0x001F) << 27;
|
||||
}
|
||||
}
|
||||
return order; /* return the CE */
|
||||
}
|
||||
|
||||
|
||||
int32_t ucol_getIncrementalSpecialCE(const UCollator *coll, uint32_t CE, incrementalContext *source, UErrorCode *status) {
|
||||
uint32_t i = 0; /* general counter */
|
||||
|
||||
if(U_FAILURE(*status)) return -1;
|
||||
|
||||
for(;;) {
|
||||
const uint32_t *CEOffset = NULL;
|
||||
const UChar *UCharOffset = NULL;
|
||||
UChar schar, tchar;
|
||||
uint32_t size = 0;
|
||||
switch(getCETag(CE)) {
|
||||
case NOT_FOUND_TAG:
|
||||
/* This one is not found, and we'll let somebody else bother about it... no more games */
|
||||
return CE;
|
||||
case SURROGATE_TAG:
|
||||
/* pending surrogate discussion with Markus and Mark */
|
||||
return UCOL_NOT_FOUND;
|
||||
case THAI_TAG:
|
||||
/* Thai/Lao reordering */
|
||||
source->panic = TRUE;
|
||||
return UCOL_NO_MORE_CES;
|
||||
case CONTRACTION_TAG:
|
||||
/* This should handle contractions */
|
||||
for(;;) {
|
||||
/* First we position ourselves at the begining of contraction sequence */
|
||||
const UChar *ContractionStart = UCharOffset = (UChar *)coll->image+getContractOffset(CE);
|
||||
|
||||
/* we need to convey the notion of having a backward search - most probably through the context object */
|
||||
/* if (backwardsSearch) offset += contractionUChars[(int16_t)offset]; else UCharOffset++; */
|
||||
schar = source->lastChar = source->source(source->sourceContext);
|
||||
incctx_appendChar(source, source->lastChar);
|
||||
if (schar == 0xFFFF) { /* this is the end of string */
|
||||
CE = *(coll->contractionCEs + (UCharOffset - coll->contractionIndex)); /* So we'll pick whatever we have at the point... */
|
||||
//! source->pos--; /* I think, since we'll advance in the getCE */
|
||||
break;
|
||||
}
|
||||
UCharOffset++; /* skip the backward offset, see above */
|
||||
//! schar = *(++source->pos);
|
||||
while(schar > (tchar = *UCharOffset)) { /* since the contraction codepoints should be ordered, we skip all that are smaller */
|
||||
UCharOffset++;
|
||||
}
|
||||
if(schar != tchar) { /* we didn't find the correct codepoint. We can use either the first or the last CE */
|
||||
if(tchar != 0xFFFF) {
|
||||
UCharOffset = ContractionStart; /* We're not at the end, bailed out in the middle. Better use starting CE */
|
||||
}
|
||||
//! source->pos--; /* Spit out the last char of the string, wasn't tasty enough */
|
||||
} else {
|
||||
source->lastChar = 0xFFFF;
|
||||
}
|
||||
CE = *(coll->contractionCEs + (UCharOffset - coll->contractionIndex));
|
||||
/*
|
||||
if(!isContraction(CE)) {
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if(isContraction(CE)) { /* fix for the bug. Other places need to be checked */
|
||||
/* this is contraction, and we will continue. However, we can fail along the */
|
||||
/* th road, which means that we have part of contraction correct */
|
||||
source->panic = TRUE;
|
||||
return UCOL_NO_MORE_CES;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXPANSION_TAG:
|
||||
/* This should handle expansion. */
|
||||
/* NOTE: we can encounter both continuations and expansions in an expansion! */
|
||||
/* I have to decide where continuations are going to be dealt with */
|
||||
CEOffset = (uint32_t *)coll->image+getExpansionOffset(CE); /* find the offset to expansion table */
|
||||
size = getExpansionCount(CE);
|
||||
CE = *CEOffset++;
|
||||
if(size != 0) { /* if there are less than 16 elements in expansion, we don't terminate */
|
||||
for(i = 1; i<size; i++) {
|
||||
*(source->CEpos++) = *CEOffset++;
|
||||
}
|
||||
} else { /* else, we do */
|
||||
while(*CEOffset != 0) {
|
||||
*(source->CEpos++) = *CEOffset++;
|
||||
}
|
||||
}
|
||||
/*source->toReturn++;*/
|
||||
return CE;
|
||||
case CHARSET_TAG:
|
||||
/* probably after 1.8 */
|
||||
return UCOL_NOT_FOUND;
|
||||
default:
|
||||
*status = U_INTERNAL_PROGRAM_ERROR;
|
||||
CE=0;
|
||||
break;
|
||||
}
|
||||
if (CE <= UCOL_NOT_FOUND) break;
|
||||
}
|
||||
return CE;
|
||||
|
||||
}
|
||||
|
||||
void incctx_cleanUpContext(incrementalContext *ctx) {
|
||||
if(ctx->stringP != ctx->stackString) {
|
||||
uprv_free(ctx->stringP);
|
||||
}
|
||||
}
|
||||
|
||||
UChar incctx_appendChar(incrementalContext *ctx, UChar c) {
|
||||
if(ctx->len == ctx->capacity) { /* bother, said Pooh, we need to reallocate */
|
||||
UChar *newStuff;
|
||||
if(ctx->stringP == ctx->stackString) { /* we haven't allocated before, need to allocate */
|
||||
newStuff = (UChar *)uprv_malloc(2*(ctx->capacity - ctx->stringP)*sizeof(UChar));
|
||||
if(newStuff == NULL) {
|
||||
/*freak out*/
|
||||
}
|
||||
uprv_memcpy(newStuff, ctx->stringP, (ctx->capacity - ctx->stringP)*sizeof(UChar));
|
||||
} else { /* we have already allocated, need to reallocate */
|
||||
newStuff = (UChar *)uprv_realloc(ctx->stringP, 2*(ctx->capacity - ctx->stringP)*sizeof(UChar));
|
||||
if(newStuff == NULL) {
|
||||
/*freak out*/
|
||||
}
|
||||
}
|
||||
ctx->len=newStuff+(ctx->len - ctx->stringP);
|
||||
ctx->capacity = newStuff+2*(ctx->capacity - ctx->stringP);
|
||||
ctx->stringP = newStuff;
|
||||
}
|
||||
*(ctx->len++) = c;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UCollationResult alternateIncrementalProcessing(const UCollator *coll, incrementalContext *srcCtx, incrementalContext *trgCtx) {
|
||||
if(srcCtx->stringP == srcCtx->len || *(srcCtx->len-1) != 0xFFFF) {
|
||||
while(incctx_appendChar(srcCtx, srcCtx->source(srcCtx->sourceContext)) != 0xFFFF);
|
||||
}
|
||||
if(trgCtx->stringP == trgCtx->len || *(trgCtx->len-1) != 0xFFFF) {
|
||||
while(incctx_appendChar(trgCtx, trgCtx->source(trgCtx->sourceContext)) != 0xFFFF);
|
||||
}
|
||||
UCollationResult result = ucol_strcoll(coll, srcCtx->stringP, srcCtx->len-srcCtx->stringP-1, trgCtx->stringP, trgCtx->len-trgCtx->stringP-1);
|
||||
incctx_cleanUpContext(srcCtx);
|
||||
incctx_cleanUpContext(trgCtx);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -149,22 +149,6 @@ struct UCollationElements
|
|||
UBool isWritable;
|
||||
};
|
||||
|
||||
struct incrementalContext {
|
||||
UCharForwardIterator *source;
|
||||
void *sourceContext;
|
||||
UChar currentChar;
|
||||
UChar lastChar;
|
||||
UChar stackString[UCOL_MAX_BUFFER]; /* Original string */
|
||||
UChar *stringP; /* This is position in the string */
|
||||
UChar *len; /* Original string length */
|
||||
UChar *capacity; /* This is capacity */
|
||||
uint32_t *toReturn; /* This is the CE from CEs buffer that should be returned */
|
||||
uint32_t *CEpos; /* This is the position to which we have stored processed CEs */
|
||||
uint32_t CEs[UCOL_EXPAND_CE_BUFFER_SIZE]; /* This is where we store CEs */
|
||||
UBool panic; /* can't handle it any more - we have to call the cavalry */
|
||||
const UCollator *coll;
|
||||
};
|
||||
|
||||
|
||||
#define UCOL_LEVELTERMINATOR 1
|
||||
|
||||
|
@ -303,9 +287,6 @@ U_CAPI uint32_t U_EXPORT2 ucol_getPrevCE(const UCollator *coll,
|
|||
uint32_t ucol_getNextUCA(UChar ch, collIterate *collationSource, UErrorCode *status);
|
||||
uint32_t ucol_getPrevUCA(UChar ch, collIterate *collationSource, UErrorCode *status);
|
||||
|
||||
void incctx_cleanUpContext(incrementalContext *ctx);
|
||||
UChar incctx_appendChar(incrementalContext *ctx, UChar c);
|
||||
|
||||
/* function used by C++ getCollationKey to prevent restarting the calculation */
|
||||
U_CFUNC uint8_t *ucol_getSortKeyWithAllocation(const UCollator *coll,
|
||||
const UChar *source,
|
||||
|
@ -602,19 +583,13 @@ struct UCollator {
|
|||
};
|
||||
|
||||
/* various internal functions */
|
||||
void init_incrementalContext(UCollator *coll, UCharForwardIterator *source, void *sourceContext, incrementalContext *s);
|
||||
int32_t ucol_getIncrementalCE(const UCollator *coll, incrementalContext *ctx, UErrorCode *status);
|
||||
void incctx_cleanUpContext(incrementalContext *ctx);
|
||||
UChar incctx_appendChar(incrementalContext *ctx, UChar c);
|
||||
UCollationResult alternateIncrementalProcessing(const UCollator *coll, incrementalContext *srcCtx, incrementalContext *trgCtx);
|
||||
void ucol_initUCA(UErrorCode *status);
|
||||
|
||||
UCollator* ucol_initCollator(const UCATableHeader *image, UCollator *fillIn, UErrorCode *status);
|
||||
void ucol_setOptionsFromHeader(UCollator* result, UColOptionSet * opts, UErrorCode *status);
|
||||
void ucol_putOptionsToHeader(UCollator* result, UColOptionSet * opts, UErrorCode *status);
|
||||
|
||||
uint32_t ucol_getIncrementalUCA(UChar ch, incrementalContext *collationSource, UErrorCode *status);
|
||||
int32_t ucol_getIncrementalSpecialCE(const UCollator *coll, uint32_t CE, incrementalContext *ctx, UErrorCode *status);
|
||||
void ucol_updateInternalState(UCollator *coll);
|
||||
|
||||
U_CAPI uint32_t U_EXPORT2 ucol_getFirstCE(const UCollator *coll, UChar u, UErrorCode *status);
|
||||
|
|
|
@ -636,21 +636,6 @@ public:
|
|||
*/
|
||||
virtual Collator* safeClone(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* String compare that uses user supplied character iteration.
|
||||
* The idea is to prevent users from having to convert the whole string into
|
||||
* UChar's before comparing since sometimes strings differ on first couple of
|
||||
* characters.
|
||||
* @param coll Collator to be used for comparing
|
||||
* @param source pointer to function for iterating over the first string
|
||||
* @param target pointer to function for iterating over the second string
|
||||
* @return The result of comparing the strings; one of UCOL_EQUAL,
|
||||
* UCOL_GREATER, UCOL_LESS
|
||||
*/
|
||||
virtual EComparisonResult compare(ForwardCharacterIterator &source,
|
||||
ForwardCharacterIterator &target) = 0;
|
||||
|
||||
/**
|
||||
* Get the sort key as an array of bytes from an UnicodeString.
|
||||
* Sort key byte arrays are zero-terminated and can be compared using
|
||||
|
|
|
@ -666,20 +666,6 @@ public:
|
|||
*/
|
||||
virtual Collator* safeClone(void);
|
||||
|
||||
/**
|
||||
* String compare that uses user supplied character iteration. The idea is
|
||||
* to prevent users from having to convert the whole string into UChar's
|
||||
* before comparing since sometimes strings differ on first couple of
|
||||
* characters.
|
||||
* @param coll Collator to be used for comparing
|
||||
* @param source pointer to function for iterating over the first string
|
||||
* @param target pointer to function for iterating over the second string
|
||||
* @return The result of comparing the strings; one of UCOL_EQUAL,
|
||||
* UCOL_GREATER, UCOL_LESS
|
||||
*/
|
||||
virtual EComparisonResult compare(ForwardCharacterIterator &source,
|
||||
ForwardCharacterIterator &target);
|
||||
|
||||
/**
|
||||
* Get the sort key as an array of bytes from an UnicodeString.
|
||||
* @param source string to be processed.
|
||||
|
|
|
@ -580,28 +580,6 @@ U_CAPI UCollator * ucol_safeClone(
|
|||
|
||||
#define U_COL_SAFECLONE_BUFFERSIZE 384
|
||||
|
||||
/* declaration for forward iterating function */
|
||||
U_CDECL_BEGIN
|
||||
typedef UChar UCharForwardIterator(void *context);
|
||||
U_CDECL_END
|
||||
|
||||
/**
|
||||
* String compare that uses user supplied character iteration.
|
||||
* The idea is to prevent users from having to convert the whole string into UChar's before comparing
|
||||
* since sometimes strings differ on first couple of characters.
|
||||
* @param coll collator to be used for comparing
|
||||
* @param source pointer to function for iterating over the first string
|
||||
* @param sourceContext data to be passed to the first iterating function.
|
||||
* @param target pointer to function for iterating over the second string
|
||||
* @param targetContext data to be passed to the second iterating function.
|
||||
* @return The result of comparing the strings; one of UCOL_EQUAL,
|
||||
* UCOL_GREATER, UCOL_LESS
|
||||
* @deprecated will be removed in ICU 2.0. Do not use, not synchronized with the rest of the framework.
|
||||
*/
|
||||
U_CAPI UCollationResult ucol_strcollinc(const UCollator *coll,
|
||||
UCharForwardIterator *source, void *sourceContext,
|
||||
UCharForwardIterator *target, void *targetContext);
|
||||
|
||||
/**
|
||||
* Returns current rules. Delta defines whether full rules are returned or just the tailoring.
|
||||
* Returns number of UChars needed to store rules. If buffer is NULL or bufferLen is not enough
|
||||
|
|
Loading…
Add table
Reference in a new issue