ICU-1003 removing incremental compare API

X-SVN-Rev: 5021
This commit is contained in:
Vladimir Weinstein 2001-06-19 21:18:41 +00:00
parent 9268bcb6a4
commit a7268db185
6 changed files with 0 additions and 882 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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.

View file

@ -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