scuffed-code/icu4c/source/i18n/ucoleitr.cpp
Syn Wee Quek ec4c07eeb0 ICU-861
Updated backwards collation element iterator codes.

X-SVN-Rev: 3760
2001-02-23 23:36:42 +00:00

277 lines
8.5 KiB
C++

/*
******************************************************************************
* Copyright (C) 2001, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
*
* File ucoleitr.cpp
*
* Modification History:
*
* Date Name Description
* 02/15/2001 synwee Modified all methods to process its own function
* instead of calling the equivalent c++ api (coleitr.h)
******************************************************************************/
#include "unicode/ucoleitr.h"
#include "unicode/ustring.h"
#include "unicode/sortkey.h"
#include "ucolimp.h"
#include "cmemory.h"
#define BUFFER_LENGTH 100
typedef struct collIterate collIterator;
/* public methods ---------------------------------------------------- */
/**
* Since this is going to be deprecated, I'll leave it as it is
*/
U_CAPI int32_t
ucol_keyHashCode(const uint8_t *key,
int32_t length)
{
CollationKey newKey(key, length);
return newKey.hashCode();
}
UCollationElements*
ucol_openElements(const UCollator *coll,
const UChar *text,
int32_t textLength,
UErrorCode *status)
{
UCollationElements *result;
if (U_FAILURE(*status))
return NULL;
result = (UCollationElements *)uprv_malloc(sizeof(UCollationElements));
result->collator_ = coll;
/* gets the correct length of the null-terminated string */
if (textLength == -1)
textLength = u_strlen(text);
result->length_ = textLength;
result->reset_ = TRUE;
init_collIterate(text, textLength, &result->iteratordata_, FALSE);
return result;
}
U_CAPI void
ucol_closeElements(UCollationElements *elems)
{
collIterate *ci = &elems->iteratordata_;
if (ci->writableBuffer != ci->stackWritableBuffer)
uprv_free(ci->writableBuffer);
if (elems->iteratordata_.isWritable && elems->iteratordata_.string != NULL)
uprv_free(elems->iteratordata_.string);
uprv_free(elems);
}
U_CAPI void
ucol_reset(UCollationElements *elems)
{
collIterate *ci = &(elems->iteratordata_);
elems->reset_ = TRUE;
ci->pos = ci->string;
ci->len = ci->string + elems->length_;
ci->CEpos = ci->toReturn = ci->CEs;
/*
problem here, that means we'll have to keep calculating the new thai set
whenever we reset. maybe getSpecialCE should just do up the whole string
instead of only a substring of it.
*/
ci->isThai = TRUE;
if (ci->stackWritableBuffer != ci->writableBuffer)
{
uprv_free(ci->writableBuffer);
ci->writableBuffer = ci->stackWritableBuffer;
}
}
U_CAPI int32_t
ucol_next(UCollationElements *elems,
UErrorCode *status)
{
int32_t result;
if (U_FAILURE(*status))
return UCOL_NULLORDER;
elems->reset_ = FALSE;
UCOL_GETNEXTCE(result, elems->collator_, elems->iteratordata_, status);
/*
if ((elems->iteratordata_).CEpos > (elems->iteratordata_).toReturn)
{
result = *((elems->iteratordata_).toReturn++);
if ((elems->iteratordata_).CEpos == (elems->iteratordata_).toReturn)
(elems->iteratordata_).CEpos = (elems->iteratordata_).toReturn =
(elems->iteratordata_).CEs;
}
else
if ((elems->iteratordata_).pos < (elems->iteratordata_).len)
{
UChar ch = *(elems->iteratordata_).pos++;
if (ch <= 0xFF)
(result) = (elems->collator_)->latinOneMapping[ch];
else
(result) = ucmp32_get((elems->collator_)->mapping, ch);
if((result) >= UCOL_NOT_FOUND)
{
(result) = getSpecialCE((elems->collator_), (result),
&(elems->iteratordata_), (status));
if ((result) == UCOL_NOT_FOUND)
(result) = ucol_getNextUCA(ch, &(elems->iteratordata_), (status));
}
}
else
(result) = UCOL_NO_MORE_CES;
*/
if (result == UCOL_NO_MORE_CES)
result = UCOL_NULLORDER;
return result;
}
U_CAPI int32_t
ucol_previous(UCollationElements *elems,
UErrorCode *status)
{
if(U_FAILURE(*status))
return UCOL_NULLORDER;
else
{
int32_t result;
if (elems->reset_ &&
(elems->iteratordata_.pos == elems->iteratordata_.string))
elems->iteratordata_.pos = elems->iteratordata_.len;
elems->reset_ = FALSE;
UCOL_GETPREVCE(result, elems->collator_, elems->iteratordata_,
elems->length_, status);
/* synwee : to be removed, only for testing */
/*
const UCollator *coll = elems->collator_;
collIterate *data = &(elems->iteratordata_);
int32_t length = elems->length_;
if (data->CEpos > data->CEs)
{
data->toReturn --;
(result) = *(data->toReturn);
if (data->CEs == data->toReturn)
data->CEpos = data->toReturn = data->CEs;
}
else
{
if (data->pos == data->string || data->pos == data->writableBuffer)
(result) = UCOL_NO_MORE_CES;
else
{
data->pos --;
UChar ch = *(data->pos);
if (ch <= 0xFF)
(result) = (coll)->latinOneMapping[ch];
else
(result) = ucmp32_get((coll)->mapping, ch);
if ((result) >= UCOL_NOT_FOUND)
{
(result) = getSpecialPrevCE(coll, result, data, length, status);
if ((result) == UCOL_NOT_FOUND)
(result) = ucol_getPrevUCA(ch, data, length, status);
}
}
}
*/
if (result == UCOL_NO_MORE_CES)
result = UCOL_NULLORDER;
return result;
}
}
U_CAPI int32_t
ucol_getMaxExpansion(const UCollationElements *elems,
int32_t order)
{
/*
synwee : requested this implementation from vladimir, need discussion. so
hang on.
*/
/* return ((CollationElementIterator*)elems)->getMaxExpansion(order); */
return -1;
}
U_CAPI void
ucol_setText( UCollationElements *elems,
const UChar *text,
int32_t textLength,
UErrorCode *status)
{
if (U_FAILURE(*status))
return;
/* gets the correct length of the null-terminated string */
if (textLength == -1)
textLength = u_strlen(text);
elems->length_ = textLength;
if (elems->iteratordata_.isWritable && elems->iteratordata_.string != NULL)
uprv_free(elems->iteratordata_.string);
init_collIterate(text, textLength, &elems->iteratordata_, FALSE);
}
U_CAPI UTextOffset
ucol_getOffset(const UCollationElements *elems)
{
/* return ((CollationElementIterator*)elems)->getOffset(); */
const collIterate *ci = &(elems->iteratordata_);
if (ci->isThai == TRUE)
return ci->pos - ci->string;
return ci->pos - ci->writableBuffer;
}
U_CAPI void
ucol_setOffset(UCollationElements *elems,
UTextOffset offset,
UErrorCode *status)
{
if (U_FAILURE(*status))
return;
collIterate *ci = &(elems->iteratordata_);
ci->pos = ci->string + offset;
ci->CEpos = ci->toReturn = ci->CEs;
/*
problem here, that means we'll have to keep calculating the new thai set
whenever we reset. maybe getSpecialCE should just do up the whole string
instead of only a substring of it.
*/
ci->isThai = TRUE;
if (ci->stackWritableBuffer != ci->writableBuffer)
{
uprv_free(ci->writableBuffer);
ci->writableBuffer = ci->stackWritableBuffer;
}
}