1999-08-16 21:50:52 +00:00
|
|
|
|
/*
|
1999-11-22 20:25:35 +00:00
|
|
|
|
*******************************************************************************
|
2001-03-21 20:31:13 +00:00
|
|
|
|
* Copyright (C) 1996-2001, International Business Machines Corporation and *
|
1999-11-22 20:25:35 +00:00
|
|
|
|
* others. All Rights Reserved. *
|
|
|
|
|
*******************************************************************************
|
1999-08-16 21:50:52 +00:00
|
|
|
|
*/
|
2001-01-18 00:23:29 +00:00
|
|
|
|
|
|
|
|
|
/*
|
2001-01-30 18:52:58 +00:00
|
|
|
|
* File coleitr.cpp
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* Created by: Helena Shih
|
|
|
|
|
*
|
|
|
|
|
* Modification History:
|
|
|
|
|
*
|
2001-02-20 00:26:50 +00:00
|
|
|
|
* Date Name Description
|
2001-01-30 18:52:58 +00:00
|
|
|
|
*
|
2001-02-20 00:26:50 +00:00
|
|
|
|
* 6/23/97 helena Adding comments to make code more readable.
|
|
|
|
|
* 08/03/98 erm Synched with 1.2 version of CollationElementIterator.java
|
|
|
|
|
* 12/10/99 aliu Ported Thai collation support from Java.
|
|
|
|
|
* 01/25/01 swquek Modified to a C++ wrapper calling C APIs (ucoliter.h)
|
|
|
|
|
* 02/19/01 swquek Removed CollationElementsIterator() since it is
|
|
|
|
|
* private constructor and no calls are made to it
|
2001-01-18 00:23:29 +00:00
|
|
|
|
*/
|
|
|
|
|
|
1999-12-28 23:57:50 +00:00
|
|
|
|
#include "unicode/coleitr.h"
|
2001-03-08 17:40:42 +00:00
|
|
|
|
#include "ucol_imp.h"
|
2001-02-20 00:26:50 +00:00
|
|
|
|
#include "cmemory.h"
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
1999-12-10 18:53:45 +00:00
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/* Constants --------------------------------------------------------------- */
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/* synwee : public can't remove */
|
1999-08-16 21:50:52 +00:00
|
|
|
|
int32_t const CollationElementIterator::NULLORDER = 0xffffffff;
|
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/* CollationElementIterator public constructor/destructor ------------------ */
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
CollationElementIterator::CollationElementIterator(
|
2001-02-20 00:26:50 +00:00
|
|
|
|
const CollationElementIterator& other)
|
|
|
|
|
: isDataOwned_(TRUE)
|
2001-01-18 00:23:29 +00:00
|
|
|
|
{
|
2001-03-15 02:54:01 +00:00
|
|
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
|
|
|
m_data_ = ucol_openElements(other.m_data_->iteratordata_.coll, NULL, 0, &status);
|
2001-01-18 00:23:29 +00:00
|
|
|
|
*this = other;
|
|
|
|
|
}
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
CollationElementIterator::~CollationElementIterator()
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-03-15 02:54:01 +00:00
|
|
|
|
if (isDataOwned_) {
|
2001-02-21 01:58:55 +00:00
|
|
|
|
ucol_closeElements(m_data_);
|
2001-03-15 02:54:01 +00:00
|
|
|
|
}
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/* CollationElementIterator public methods --------------------------------- */
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
UTextOffset CollationElementIterator::getOffset() const
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-02-20 00:26:50 +00:00
|
|
|
|
return ucol_getOffset(m_data_);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get the ordering priority of the next character in the string.
|
2001-02-21 01:58:55 +00:00
|
|
|
|
* @return the next character's ordering. Returns NULLORDER if an error has
|
2001-02-22 23:16:06 +00:00
|
|
|
|
* occured or if the end of string has been reached
|
2001-01-18 00:23:29 +00:00
|
|
|
|
*/
|
|
|
|
|
int32_t CollationElementIterator::next(UErrorCode& status)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-02-20 00:26:50 +00:00
|
|
|
|
return ucol_next(m_data_, &status);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
UBool CollationElementIterator::operator!=(
|
2001-02-20 00:26:50 +00:00
|
|
|
|
const CollationElementIterator& other) const
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
return !(*this == other);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
UBool CollationElementIterator::operator==(
|
|
|
|
|
const CollationElementIterator& that) const
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if (this == &that)
|
|
|
|
|
return TRUE;
|
2001-02-20 00:26:50 +00:00
|
|
|
|
|
2001-03-15 02:54:01 +00:00
|
|
|
|
if (m_data_ == that.m_data_)
|
|
|
|
|
return TRUE;
|
2001-02-20 00:26:50 +00:00
|
|
|
|
|
2001-03-15 02:54:01 +00:00
|
|
|
|
return (this->m_data_->normalization_ == that.m_data_->normalization_ &&
|
|
|
|
|
this->m_data_->length_ == that.m_data_->length_ &&
|
|
|
|
|
this->m_data_->reset_ == that.m_data_->reset_ &&
|
|
|
|
|
uprv_memcmp(this->m_data_->iteratordata_.string,
|
|
|
|
|
that.m_data_->iteratordata_.string,
|
|
|
|
|
this->m_data_->length_) == 0 &&
|
|
|
|
|
this->getOffset() == that.getOffset() &&
|
|
|
|
|
this->m_data_->iteratordata_.isThai == that.m_data_->iteratordata_.isThai &&
|
|
|
|
|
this->m_data_->iteratordata_.coll == that.m_data_->iteratordata_.coll);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get the ordering priority of the previous collation element in the string.
|
|
|
|
|
* @param status the error code status.
|
2001-02-21 01:58:55 +00:00
|
|
|
|
* @return the previous element's ordering. Returns NULLORDER if an error has
|
2001-02-22 23:16:06 +00:00
|
|
|
|
* occured or if the start of string has been reached.
|
2001-01-18 00:23:29 +00:00
|
|
|
|
*/
|
|
|
|
|
int32_t CollationElementIterator::previous(UErrorCode& status)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-02-20 00:26:50 +00:00
|
|
|
|
return ucol_previous(m_data_, &status);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2001-01-18 00:23:29 +00:00
|
|
|
|
* Resets the cursor to the beginning of the string.
|
|
|
|
|
*/
|
|
|
|
|
void CollationElementIterator::reset()
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-02-20 00:26:50 +00:00
|
|
|
|
ucol_reset(m_data_);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
void CollationElementIterator::setOffset(UTextOffset newOffset,
|
|
|
|
|
UErrorCode& status)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-02-20 00:26:50 +00:00
|
|
|
|
ucol_setOffset(m_data_, newOffset, &status);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets the source to the new source string.
|
|
|
|
|
*/
|
|
|
|
|
void CollationElementIterator::setText(const UnicodeString& source,
|
|
|
|
|
UErrorCode& status)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if (U_FAILURE(status))
|
|
|
|
|
return;
|
2001-02-20 00:26:50 +00:00
|
|
|
|
int32_t length = source.length();
|
|
|
|
|
UChar *string = new UChar[length];
|
|
|
|
|
source.extract(0, length, string);
|
|
|
|
|
|
|
|
|
|
m_data_->length_ = length;
|
|
|
|
|
|
|
|
|
|
if (m_data_->iteratordata_.isWritable &&
|
|
|
|
|
m_data_->iteratordata_.string != NULL)
|
|
|
|
|
uprv_free(m_data_->iteratordata_.string);
|
2001-03-15 02:54:01 +00:00
|
|
|
|
init_collIterate(m_data_->iteratordata_.coll, string, length, &m_data_->iteratordata_, TRUE);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
// Sets the source to the new character iterator.
|
|
|
|
|
void CollationElementIterator::setText(CharacterIterator& source,
|
|
|
|
|
UErrorCode& status)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if (U_FAILURE(status))
|
|
|
|
|
return;
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
int32_t length = source.getLength();
|
|
|
|
|
UChar *buffer = new UChar[length];
|
|
|
|
|
/*
|
|
|
|
|
Using this constructor will prevent buffer from being removed when
|
|
|
|
|
string gets removed
|
|
|
|
|
*/
|
2001-02-21 01:58:55 +00:00
|
|
|
|
UnicodeString string;
|
2001-02-20 00:26:50 +00:00
|
|
|
|
source.getText(string);
|
|
|
|
|
string.extract(0, length, buffer);
|
|
|
|
|
m_data_->length_ = length;
|
|
|
|
|
|
|
|
|
|
if (m_data_->iteratordata_.isWritable &&
|
|
|
|
|
m_data_->iteratordata_.string != NULL)
|
|
|
|
|
uprv_free(m_data_->iteratordata_.string);
|
2001-03-15 02:54:01 +00:00
|
|
|
|
init_collIterate(m_data_->iteratordata_.coll, buffer, length, &m_data_->iteratordata_, TRUE);
|
2001-01-18 00:23:29 +00:00
|
|
|
|
}
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
int32_t CollationElementIterator::strengthOrder(int32_t order) const
|
|
|
|
|
{
|
2001-03-15 02:54:01 +00:00
|
|
|
|
UCollationStrength s = ucol_getStrength(m_data_->iteratordata_.coll);
|
2001-01-18 00:23:29 +00:00
|
|
|
|
// Mask off the unwanted differences.
|
2001-02-20 00:26:50 +00:00
|
|
|
|
if (s == UCOL_PRIMARY)
|
2001-01-18 00:23:29 +00:00
|
|
|
|
order &= RuleBasedCollator::PRIMARYDIFFERENCEONLY;
|
|
|
|
|
else
|
2001-02-20 00:26:50 +00:00
|
|
|
|
if (s == UCOL_SECONDARY)
|
2001-01-18 00:23:29 +00:00
|
|
|
|
order &= RuleBasedCollator::SECONDARYDIFFERENCEONLY;
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
return order;
|
|
|
|
|
}
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/* CollationElementIterator private constructors/destructors --------------- */
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/*
|
|
|
|
|
This private method will never be called, but it makes the linker happy
|
|
|
|
|
CollationElementIterator::CollationElementIterator() : m_data_(0)
|
2001-01-18 00:23:29 +00:00
|
|
|
|
{
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
2001-02-20 00:26:50 +00:00
|
|
|
|
*/
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
CollationElementIterator::CollationElementIterator(
|
2001-02-20 00:26:50 +00:00
|
|
|
|
const RuleBasedCollator* order)
|
|
|
|
|
: isDataOwned_(TRUE)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-02-20 00:26:50 +00:00
|
|
|
|
UErrorCode status = U_ZERO_ERROR;
|
|
|
|
|
m_data_ = ucol_openElements(order->ucollator, NULL, 0, &status);
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* This is the "real" constructor for this class; it constructs an iterator
|
|
|
|
|
* over the source text using the specified collator
|
|
|
|
|
*/
|
|
|
|
|
CollationElementIterator::CollationElementIterator(
|
2001-02-21 01:58:55 +00:00
|
|
|
|
const UnicodeString& sourceText,
|
|
|
|
|
const RuleBasedCollator* order,
|
|
|
|
|
UErrorCode& status)
|
|
|
|
|
: isDataOwned_(TRUE)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if (U_FAILURE(status))
|
|
|
|
|
return;
|
2001-02-20 00:26:50 +00:00
|
|
|
|
|
2001-02-21 01:58:55 +00:00
|
|
|
|
int32_t length = sourceText.length();
|
|
|
|
|
UChar *string = new UChar[length];
|
|
|
|
|
/*
|
|
|
|
|
Using this constructor will prevent buffer from being removed when
|
|
|
|
|
string gets removed
|
|
|
|
|
*/
|
|
|
|
|
sourceText.extract(0, length, string);
|
|
|
|
|
|
|
|
|
|
m_data_ = ucol_openElements(order->ucollator, string, length, &status);
|
|
|
|
|
m_data_->iteratordata_.isWritable = TRUE;
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* This is the "real" constructor for this class; it constructs an iterator over
|
|
|
|
|
* the source text using the specified collator
|
|
|
|
|
*/
|
|
|
|
|
CollationElementIterator::CollationElementIterator(
|
2001-02-20 00:26:50 +00:00
|
|
|
|
const CharacterIterator& sourceText,
|
|
|
|
|
const RuleBasedCollator* order,
|
|
|
|
|
UErrorCode& status)
|
|
|
|
|
: isDataOwned_(TRUE)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if (U_FAILURE(status))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
// **** should I just drop this test? ****
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/*
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if ( sourceText.endIndex() != 0 )
|
|
|
|
|
{
|
|
|
|
|
// A CollationElementIterator is really a two-layered beast.
|
|
|
|
|
// Internally it uses a Normalizer to munge the source text into a form
|
|
|
|
|
// where all "composed" Unicode characters (such as <20>) are split into a
|
|
|
|
|
// normal character and a combining accent character.
|
|
|
|
|
// Afterward, CollationElementIterator does its own processing to handle
|
|
|
|
|
// expanding and contracting collation sequences, ignorables, and so on.
|
|
|
|
|
|
|
|
|
|
Normalizer::EMode decomp = order->getStrength() == Collator::IDENTICAL
|
|
|
|
|
? Normalizer::NO_OP : order->getDecomposition();
|
|
|
|
|
|
|
|
|
|
text = new Normalizer(sourceText, decomp);
|
|
|
|
|
if (text == NULL)
|
|
|
|
|
status = U_MEMORY_ALLOCATION_ERROR;
|
|
|
|
|
}
|
2001-02-20 00:26:50 +00:00
|
|
|
|
*/
|
|
|
|
|
int32_t length = sourceText.getLength();
|
|
|
|
|
UChar *buffer = new UChar[length];
|
|
|
|
|
/*
|
|
|
|
|
Using this constructor will prevent buffer from being removed when
|
|
|
|
|
string gets removed
|
|
|
|
|
*/
|
|
|
|
|
UnicodeString string(buffer, length, length);
|
2001-02-21 01:58:55 +00:00
|
|
|
|
((CharacterIterator &)sourceText).getText(string);
|
2001-02-20 00:26:50 +00:00
|
|
|
|
string.extract(0, length, buffer);
|
|
|
|
|
|
2001-02-21 01:58:55 +00:00
|
|
|
|
m_data_ = ucol_openElements(order->ucollator, buffer, length, &status);
|
|
|
|
|
m_data_->iteratordata_.isWritable = TRUE;
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-20 00:26:50 +00:00
|
|
|
|
/* CollationElementIterator private methods -------------------------------- */
|
2001-01-18 00:23:29 +00:00
|
|
|
|
|
|
|
|
|
const CollationElementIterator& CollationElementIterator::operator=(
|
2001-02-20 00:26:50 +00:00
|
|
|
|
const CollationElementIterator& other)
|
1999-08-16 21:50:52 +00:00
|
|
|
|
{
|
2001-01-18 00:23:29 +00:00
|
|
|
|
if (this != &other)
|
|
|
|
|
{
|
2001-03-15 02:54:01 +00:00
|
|
|
|
this->m_data_->normalization_ = other.m_data_->normalization_;
|
|
|
|
|
this->m_data_->length_ = other.m_data_->length_;
|
|
|
|
|
this->m_data_->reset_ = other.m_data_->reset_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this->m_data_->iteratordata_.string = other.m_data_->iteratordata_.string;
|
|
|
|
|
this->m_data_->iteratordata_.start = other.m_data_->iteratordata_.start;
|
|
|
|
|
this->m_data_->iteratordata_.len = other.m_data_->iteratordata_.len;
|
|
|
|
|
this->m_data_->iteratordata_.pos = other.m_data_->iteratordata_.pos;
|
|
|
|
|
this->m_data_->iteratordata_.toReturn = other.m_data_->iteratordata_.CEs +
|
|
|
|
|
(other.m_data_->iteratordata_.toReturn - other.m_data_->iteratordata_.CEs);
|
|
|
|
|
this->m_data_->iteratordata_.CEpos = other.m_data_->iteratordata_.CEs +
|
|
|
|
|
(other.m_data_->iteratordata_.CEpos - other.m_data_->iteratordata_.CEs);
|
|
|
|
|
uprv_memcpy(this->m_data_->iteratordata_.CEs, other.m_data_->iteratordata_.CEs,
|
|
|
|
|
UCOL_EXPAND_CE_BUFFER_SIZE * sizeof(uint32_t));
|
|
|
|
|
this->m_data_->iteratordata_.isThai = other.m_data_->iteratordata_.isThai;
|
|
|
|
|
this->m_data_->iteratordata_.isWritable = other.m_data_->iteratordata_.isWritable;
|
|
|
|
|
|
|
|
|
|
uprv_memcpy(this->m_data_->iteratordata_.stackWritableBuffer,
|
|
|
|
|
other.m_data_->iteratordata_.stackWritableBuffer,
|
|
|
|
|
UCOL_WRITABLE_BUFFER_SIZE * sizeof(UChar));
|
|
|
|
|
/* writablebuffer is not used at the moment, not used */
|
|
|
|
|
this->m_data_->iteratordata_.coll = other.m_data_->iteratordata_.coll;
|
2001-02-21 01:58:55 +00:00
|
|
|
|
this->isDataOwned_ = FALSE;
|
2001-01-18 00:23:29 +00:00
|
|
|
|
}
|
1999-08-16 21:50:52 +00:00
|
|
|
|
|
2001-01-18 00:23:29 +00:00
|
|
|
|
return *this;
|
1999-08-16 21:50:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|