UBool CollationKey::operator==(const CollationKey& source) const { return getLength() == source.getLength() && (this == &source || uprv_memcmp(getBytes(), source.getBytes(), getLength()) == 0); }
// @bug 4139572 // // getCollationKey throws exception for spanish text // Cannot reproduce this bug on 1.2, however it DOES fail on 1.1.6 // void CollationRegressionTest::Test4139572(/* char* par */) { // // Code pasted straight from the bug report // (and then translated to C++ ;-) // // create spanish locale and collator UErrorCode status = U_ZERO_ERROR; Locale l("es", "es"); Collator *col = NULL; col = Collator::createInstance(l, status); if (col == NULL || U_FAILURE(status)) { errln("Failed to create a collator for es_es locale."); delete col; return; } CollationKey key; // this spanish phrase kills it! col->getCollationKey("Nombre De Objeto", key, status); if (key.isBogus() || U_FAILURE(status)) { errln("Error creating CollationKey for \"Nombre De Ojbeto\""); } delete col; }
// @bug 4124632 // // Collator::getCollationKey was hanging on certain character sequences // void CollationRegressionTest::Test4124632(/* char* par */) { UErrorCode status = U_ZERO_ERROR; Collator *coll = NULL; coll = Collator::createInstance(Locale::getJapan(), status); if (coll == NULL || U_FAILURE(status)) { errln("Failed to create collator for Locale::JAPAN"); delete coll; return; } static const UChar test[] = {0x41, 0x0308, 0x62, 0x63, 0}; CollationKey key; coll->getCollationKey(test, key, status); if (key.isBogus() || U_FAILURE(status)) { errln("CollationKey creation failed."); } delete coll; }
// @bug 4146160 // // RuleBasedCollator doesn't use createCollationElementIterator internally // void CollationRegressionTest::Test4146160(/* char* par */) { #if 0 // // Use a custom collator class whose createCollationElementIterator // methods increment a count.... // UErrorCode status = U_ZERO_ERROR; CollationKey key; My4146160Collator::count = 0; My4146160Collator *mc = NULL; mc = new My4146160Collator(*en_us, status); if (mc == NULL || U_FAILURE(status)) { errln("Failed to create a My4146160Collator."); delete mc; return; } mc->getCollationKey("1", key, status); if (key.isBogus() || U_FAILURE(status)) { errln("Failure to get a CollationKey from a My4146160Collator."); delete mc; return; } if (My4146160Collator::count < 1) { errln("My4146160Collator::createCollationElementIterator not called for getCollationKey"); } My4146160Collator::count = 0; mc->compare("1", "2"); if (My4146160Collator::count < 1) { errln("My4146160Collator::createtCollationElementIterator not called for compare"); } delete mc; #endif }
CollationKey::CollationKey(const CollationKey& other) : UObject(other), fFlagAndLength(other.getLength()), fHashCode(other.fHashCode) { if (other.isBogus()) { setToBogus(); return; } int32_t length = fFlagAndLength; if (length > getCapacity() && reallocate(length, 0) == NULL) { setToBogus(); return; } if (length > 0) { uprv_memcpy(getBytes(), other.getBytes(), length); } }
// Bitwise comparison for the collation keys. UCollationResult CollationKey::compareTo(const CollationKey& target, UErrorCode &status) const { if(U_SUCCESS(status)) { const uint8_t *src = getBytes(); const uint8_t *tgt = target.getBytes(); // are we comparing the same string if (src == tgt) return UCOL_EQUAL; UCollationResult result; // are we comparing different lengths? int32_t minLength = getLength(); int32_t targetLength = target.getLength(); if (minLength < targetLength) { result = UCOL_LESS; } else if (minLength == targetLength) { result = UCOL_EQUAL; } else { minLength = targetLength; result = UCOL_GREATER; } if (minLength > 0) { int diff = uprv_memcmp(src, tgt, minLength); if (diff > 0) { return UCOL_GREATER; } else if (diff < 0) { return UCOL_LESS; } } return result; } else { return UCOL_EQUAL; } }