X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..4388f060552cc537e71e957d32f35e9d75a61233:/icuSources/i18n/coleitr.cpp diff --git a/icuSources/i18n/coleitr.cpp b/icuSources/i18n/coleitr.cpp index cd91b8e3..7db3e5f7 100644 --- a/icuSources/i18n/coleitr.cpp +++ b/icuSources/i18n/coleitr.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 1996-2001, International Business Machines Corporation and * +* Copyright (C) 1996-2011, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -31,6 +31,7 @@ #include "unicode/coleitr.h" #include "unicode/ustring.h" #include "ucol_imp.h" +#include "uassert.h" #include "cmemory.h" @@ -38,10 +39,7 @@ U_NAMESPACE_BEGIN -const char CollationElementIterator::fgClassID=0; - -/* synwee : public can't remove */ -int32_t const CollationElementIterator::NULLORDER = 0xffffffff; +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CollationElementIterator) /* CollationElementIterator public constructor/destructor ------------------ */ @@ -49,25 +47,25 @@ CollationElementIterator::CollationElementIterator( const CollationElementIterator& other) : UObject(other), isDataOwned_(TRUE) { - UErrorCode status = U_ZERO_ERROR; - m_data_ = ucol_openElements(other.m_data_->iteratordata_.coll, NULL, 0, - &status); + UErrorCode status = U_ZERO_ERROR; + m_data_ = ucol_openElements(other.m_data_->iteratordata_.coll, NULL, 0, + &status); - *this = other; + *this = other; } CollationElementIterator::~CollationElementIterator() { - if (isDataOwned_) { - ucol_closeElements(m_data_); - } + if (isDataOwned_) { + ucol_closeElements(m_data_); + } } /* CollationElementIterator public methods --------------------------------- */ int32_t CollationElementIterator::getOffset() const { - return ucol_getOffset(m_data_); + return ucol_getOffset(m_data_); } /** @@ -77,29 +75,24 @@ int32_t CollationElementIterator::getOffset() const */ int32_t CollationElementIterator::next(UErrorCode& status) { - return ucol_next(m_data_, &status); + return ucol_next(m_data_, &status); } UBool CollationElementIterator::operator!=( const CollationElementIterator& other) const { - return !(*this == other); + return !(*this == other); } UBool CollationElementIterator::operator==( const CollationElementIterator& that) const { - if (this == &that) { - return TRUE; - } - - if (m_data_ == that.m_data_) { + if (this == &that || m_data_ == that.m_data_) { return TRUE; } // option comparison - if (!(m_data_->reset_ == that.m_data_->reset_ - && m_data_->iteratordata_.coll == that.m_data_->iteratordata_.coll)) + if (m_data_->iteratordata_.coll != that.m_data_->iteratordata_.coll) { return FALSE; } @@ -107,10 +100,8 @@ UBool CollationElementIterator::operator==( // the constructor and setText always sets a length // and we only compare the string not the contents of the normalization // buffer - int thislength = m_data_->iteratordata_.endp - - m_data_->iteratordata_.string; - int thatlength = that.m_data_->iteratordata_.endp - - that.m_data_->iteratordata_.string; + int thislength = (int)(m_data_->iteratordata_.endp - m_data_->iteratordata_.string); + int thatlength = (int)(that.m_data_->iteratordata_.endp - that.m_data_->iteratordata_.string); if (thislength != thatlength) { return FALSE; @@ -127,19 +118,19 @@ UBool CollationElementIterator::operator==( // checking normalization buffer if ((m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) == 0) { - if ((m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) != 0) { + if ((that.m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) != 0) { return FALSE; } // both are in the normalization buffer if (m_data_->iteratordata_.pos - - m_data_->iteratordata_.writableBuffer + - m_data_->iteratordata_.writableBuffer.getBuffer() != that.m_data_->iteratordata_.pos - - that.m_data_->iteratordata_.writableBuffer) { + - that.m_data_->iteratordata_.writableBuffer.getBuffer()) { // not in the same position in the normalization buffer return FALSE; } } - else if ((m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) == 0) { + else if ((that.m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) == 0) { return FALSE; } // checking ce position @@ -156,7 +147,7 @@ UBool CollationElementIterator::operator==( */ int32_t CollationElementIterator::previous(UErrorCode& status) { - return ucol_previous(m_data_, &status); + return ucol_previous(m_data_, &status); } /** @@ -164,13 +155,13 @@ int32_t CollationElementIterator::previous(UErrorCode& status) */ void CollationElementIterator::reset() { - ucol_reset(m_data_); + ucol_reset(m_data_); } void CollationElementIterator::setOffset(int32_t newOffset, UErrorCode& status) { - ucol_setOffset(m_data_, newOffset, &status); + ucol_setOffset(m_data_, newOffset, &status); } /** @@ -179,96 +170,100 @@ void CollationElementIterator::setOffset(int32_t newOffset, void CollationElementIterator::setText(const UnicodeString& source, UErrorCode& status) { - if (U_FAILURE(status)) { - return; - } - - int32_t length = source.length(); - UChar *string = NULL; - if (m_data_->isWritable && m_data_->iteratordata_.string != NULL) { - uprv_free(m_data_->iteratordata_.string); - } - m_data_->isWritable = TRUE; - if (length > 0) { - string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); - /* test for NULL */ - if (string == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; + if (U_FAILURE(status)) { return; } - u_memcpy(string, source.getBuffer(), length); - } - else { - string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); - /* test for NULL */ - if (string == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; + + int32_t length = source.length(); + UChar *string = NULL; + if (m_data_->isWritable && m_data_->iteratordata_.string != NULL) { + uprv_free((UChar *)m_data_->iteratordata_.string); + } + m_data_->isWritable = TRUE; + if (length > 0) { + string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); + /* test for NULL */ + if (string == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + u_memcpy(string, source.getBuffer(), length); } - *string = 0; - } - uprv_init_collIterate(m_data_->iteratordata_.coll, string, length, - &m_data_->iteratordata_); + else { + string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); + /* test for NULL */ + if (string == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + *string = 0; + } + /* Free offsetBuffer before initializing it. */ + ucol_freeOffsetBuffer(&(m_data_->iteratordata_)); + uprv_init_collIterate(m_data_->iteratordata_.coll, string, length, + &m_data_->iteratordata_, &status); - m_data_->reset_ = TRUE; + m_data_->reset_ = TRUE; } // Sets the source to the new character iterator. void CollationElementIterator::setText(CharacterIterator& source, UErrorCode& status) { - if (U_FAILURE(status)) - return; - - int32_t length = source.getLength(); - UChar *buffer = NULL; - - if (length == 0) { - buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); - /* test for NULL */ - if (buffer == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; + if (U_FAILURE(status)) return; + + int32_t length = source.getLength(); + UChar *buffer = NULL; + + if (length == 0) { + buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); + /* test for NULL */ + if (buffer == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + *buffer = 0; + } + else { + buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); + /* test for NULL */ + if (buffer == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + /* + Using this constructor will prevent buffer from being removed when + string gets removed + */ + UnicodeString string; + source.getText(string); + u_memcpy(buffer, string.getBuffer(), length); } - *buffer = 0; - } - else { - buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); - /* test for NULL */ - if (buffer == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } - /* - Using this constructor will prevent buffer from being removed when - string gets removed - */ - UnicodeString string; - source.getText(string); - u_memcpy(buffer, string.getBuffer(), length); - } - - if (m_data_->isWritable && m_data_->iteratordata_.string != NULL) { - uprv_free(m_data_->iteratordata_.string); - } - m_data_->isWritable = TRUE; - uprv_init_collIterate(m_data_->iteratordata_.coll, buffer, length, - &m_data_->iteratordata_); - m_data_->reset_ = TRUE; + + if (m_data_->isWritable && m_data_->iteratordata_.string != NULL) { + uprv_free((UChar *)m_data_->iteratordata_.string); + } + m_data_->isWritable = TRUE; + /* Free offsetBuffer before initializing it. */ + ucol_freeOffsetBuffer(&(m_data_->iteratordata_)); + uprv_init_collIterate(m_data_->iteratordata_.coll, buffer, length, + &m_data_->iteratordata_, &status); + m_data_->reset_ = TRUE; } int32_t CollationElementIterator::strengthOrder(int32_t order) const { - UCollationStrength s = ucol_getStrength(m_data_->iteratordata_.coll); - // Mask off the unwanted differences. - if (s == UCOL_PRIMARY) { - order &= RuleBasedCollator::PRIMARYDIFFERENCEONLY; - } - else if (s == UCOL_SECONDARY) { - order &= RuleBasedCollator::SECONDARYDIFFERENCEONLY; - } - - return order; + UCollationStrength s = ucol_getStrength(m_data_->iteratordata_.coll); + // Mask off the unwanted differences. + if (s == UCOL_PRIMARY) { + order &= RuleBasedCollator::PRIMARYDIFFERENCEONLY; + } + else if (s == UCOL_SECONDARY) { + order &= RuleBasedCollator::SECONDARYDIFFERENCEONLY; + } + + return order; } /* CollationElementIterator private constructors/destructors --------------- */ @@ -283,42 +278,42 @@ CollationElementIterator::CollationElementIterator( UErrorCode& status) : isDataOwned_(TRUE) { - if (U_FAILURE(status)) { - return; - } - - int32_t length = sourceText.length(); - UChar *string = NULL; - - if (length > 0) { - string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); - /* test for NULL */ - if (string == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - return; - } - /* - Using this constructor will prevent buffer from being removed when - string gets removed - */ - u_memcpy(string, sourceText.getBuffer(), length); - } - else { - string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); - /* test for NULL */ - if (string == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; + if (U_FAILURE(status)) { + return; + } + + int32_t length = sourceText.length(); + UChar *string = NULL; + + if (length > 0) { + string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); + /* test for NULL */ + if (string == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + /* + Using this constructor will prevent buffer from being removed when + string gets removed + */ + u_memcpy(string, sourceText.getBuffer(), length); + } + else { + string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); + /* test for NULL */ + if (string == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + *string = 0; + } + m_data_ = ucol_openElements(order->ucollator, string, length, &status); + + /* Test for buffer overflows */ + if (U_FAILURE(status)) { return; - } - *string = 0; - } - m_data_ = ucol_openElements(order->ucollator, string, length, &status); - - /* Test for buffer overflows */ - if (U_FAILURE(status)) { - return; - } - m_data_->isWritable = TRUE; + } + m_data_->isWritable = TRUE; } /** @@ -331,62 +326,62 @@ CollationElementIterator::CollationElementIterator( UErrorCode& status) : isDataOwned_(TRUE) { - if (U_FAILURE(status)) - return; - - // **** should I just drop this test? **** - /* - 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 ΓΌ) 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; - } - */ - int32_t length = sourceText.getLength(); - UChar *buffer; - if (length > 0) { - buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); - /* test for NULL */ - if (buffer == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; + if (U_FAILURE(status)) return; - } - /* - Using this constructor will prevent buffer from being removed when - string gets removed - */ - UnicodeString string(buffer, length, length); - ((CharacterIterator &)sourceText).getText(string); - const UChar *temp = string.getBuffer(); - u_memcpy(buffer, temp, length); - } - else { - buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); - /* test for NULL */ - if (buffer == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; + + // **** should I just drop this test? **** + /* + 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 \u00FC) 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; + } + */ + int32_t length = sourceText.getLength(); + UChar *buffer; + if (length > 0) { + buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length); + /* test for NULL */ + if (buffer == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + /* + Using this constructor will prevent buffer from being removed when + string gets removed + */ + UnicodeString string(buffer, length, length); + ((CharacterIterator &)sourceText).getText(string); + const UChar *temp = string.getBuffer(); + u_memcpy(buffer, temp, length); + } + else { + buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR); + /* test for NULL */ + if (buffer == NULL) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } + *buffer = 0; + } + m_data_ = ucol_openElements(order->ucollator, buffer, length, &status); + + /* Test for buffer overflows */ + if (U_FAILURE(status)) { return; - } - *buffer = 0; - } - m_data_ = ucol_openElements(order->ucollator, buffer, length, &status); - - /* Test for buffer overflows */ - if (U_FAILURE(status)) { - return; - } - m_data_->isWritable = TRUE; + } + m_data_->isWritable = TRUE; } /* CollationElementIterator protected methods ----------------------------- */ @@ -394,98 +389,96 @@ CollationElementIterator::CollationElementIterator( const CollationElementIterator& CollationElementIterator::operator=( const CollationElementIterator& other) { - if (this != &other) - { - UCollationElements *ucolelem = this->m_data_; - UCollationElements *otherucolelem = other.m_data_; - collIterate *coliter = &(ucolelem->iteratordata_); - collIterate *othercoliter = &(otherucolelem->iteratordata_); - int length = 0; - - // checking only UCOL_ITER_HASLEN is not enough here as we may be in - // the normalization buffer - length = othercoliter->endp - othercoliter->string; - - ucolelem->reset_ = otherucolelem->reset_; - ucolelem->isWritable = TRUE; - - /* create a duplicate of string */ - if (length > 0) { - coliter->string = (UChar *)uprv_malloc(length * U_SIZEOF_UCHAR); - if(coliter->string != NULL) { - uprv_memcpy(coliter->string, othercoliter->string, - length * U_SIZEOF_UCHAR); - } else { // Error: couldn't allocate memory. No copying should be done - length = 0; - } - } - else { - coliter->string = NULL; - } - - /* start and end of string */ - coliter->endp = coliter->string + length; - - /* handle writable buffer here */ - - if (othercoliter->flags & UCOL_ITER_INNORMBUF) { - uint32_t wlength = u_strlen(othercoliter->writableBuffer) + 1; - if (wlength < coliter->writableBufSize) { - uprv_memcpy(coliter->stackWritableBuffer, - othercoliter->stackWritableBuffer, - othercoliter->writableBufSize * U_SIZEOF_UCHAR); - } - else { - if (coliter->writableBuffer != coliter->stackWritableBuffer) { - uprv_free(coliter->writableBuffer); - } - coliter->writableBuffer = (UChar *)uprv_malloc( - wlength * U_SIZEOF_UCHAR); - if(coliter->writableBuffer != NULL) { - uprv_memcpy(coliter->writableBuffer, - othercoliter->writableBuffer, - wlength * U_SIZEOF_UCHAR); - coliter->writableBufSize = wlength; - } else { // Error: couldn't allocate memory for writableBuffer - coliter->writableBufSize = 0; - } - } - } - - /* current position */ - if (othercoliter->pos >= othercoliter->string && - othercoliter->pos <= othercoliter->endp) { - coliter->pos = coliter->string + - (othercoliter->pos - othercoliter->string); - } - else { - coliter->pos = coliter->writableBuffer + - (othercoliter->pos - othercoliter->writableBuffer); - } - - /* CE buffer */ - uprv_memcpy(coliter->CEs, othercoliter->CEs, - UCOL_EXPAND_CE_BUFFER_SIZE * sizeof(uint32_t)); - coliter->toReturn = coliter->CEs + - (othercoliter->toReturn - othercoliter->CEs); - coliter->CEpos = coliter->CEs + - (othercoliter->CEpos - othercoliter->CEs); - - if (othercoliter->fcdPosition != NULL) { - coliter->fcdPosition = coliter->string + - (othercoliter->fcdPosition - - othercoliter->string); - } - else { - coliter->fcdPosition = NULL; - } - coliter->flags = othercoliter->flags/*| UCOL_ITER_HASLEN*/; - coliter->origFlags = othercoliter->origFlags; - coliter->coll = othercoliter->coll; - this->isDataOwned_ = TRUE; - } - - return *this; + if (this != &other) + { + UCollationElements *ucolelem = this->m_data_; + UCollationElements *otherucolelem = other.m_data_; + collIterate *coliter = &(ucolelem->iteratordata_); + collIterate *othercoliter = &(otherucolelem->iteratordata_); + int length = 0; + + // checking only UCOL_ITER_HASLEN is not enough here as we may be in + // the normalization buffer + length = (int)(othercoliter->endp - othercoliter->string); + + ucolelem->reset_ = otherucolelem->reset_; + ucolelem->isWritable = TRUE; + + /* create a duplicate of string */ + if (length > 0) { + coliter->string = (UChar *)uprv_malloc(length * U_SIZEOF_UCHAR); + if(coliter->string != NULL) { + uprv_memcpy((UChar *)coliter->string, othercoliter->string, + length * U_SIZEOF_UCHAR); + } else { // Error: couldn't allocate memory. No copying should be done + length = 0; + } + } + else { + coliter->string = NULL; + } + + /* start and end of string */ + coliter->endp = coliter->string == NULL ? NULL : coliter->string + length; + + /* handle writable buffer here */ + + if (othercoliter->flags & UCOL_ITER_INNORMBUF) { + coliter->writableBuffer = othercoliter->writableBuffer; + coliter->writableBuffer.getTerminatedBuffer(); + } + + /* current position */ + if (othercoliter->pos >= othercoliter->string && + othercoliter->pos <= othercoliter->endp) + { + U_ASSERT(coliter->string != NULL); + coliter->pos = coliter->string + + (othercoliter->pos - othercoliter->string); + } + else { + coliter->pos = coliter->writableBuffer.getTerminatedBuffer() + + (othercoliter->pos - othercoliter->writableBuffer.getBuffer()); + } + + /* CE buffer */ + int32_t CEsize; + if (coliter->extendCEs) { + uprv_memcpy(coliter->CEs, othercoliter->CEs, sizeof(uint32_t) * UCOL_EXPAND_CE_BUFFER_SIZE); + CEsize = sizeof(othercoliter->extendCEs); + if (CEsize > 0) { + othercoliter->extendCEs = (uint32_t *)uprv_malloc(CEsize); + uprv_memcpy(coliter->extendCEs, othercoliter->extendCEs, CEsize); + } + coliter->toReturn = coliter->extendCEs + + (othercoliter->toReturn - othercoliter->extendCEs); + coliter->CEpos = coliter->extendCEs + CEsize; + } else { + CEsize = (int32_t)(othercoliter->CEpos - othercoliter->CEs); + if (CEsize > 0) { + uprv_memcpy(coliter->CEs, othercoliter->CEs, CEsize); + } + coliter->toReturn = coliter->CEs + + (othercoliter->toReturn - othercoliter->CEs); + coliter->CEpos = coliter->CEs + CEsize; + } + + if (othercoliter->fcdPosition != NULL) { + U_ASSERT(coliter->string != NULL); + coliter->fcdPosition = coliter->string + + (othercoliter->fcdPosition + - othercoliter->string); + } + else { + coliter->fcdPosition = NULL; + } + coliter->flags = othercoliter->flags/*| UCOL_ITER_HASLEN*/; + coliter->origFlags = othercoliter->origFlags; + coliter->coll = othercoliter->coll; + this->isDataOwned_ = TRUE; + } + + return *this; } U_NAMESPACE_END