/*
******************************************************************************
- * Copyright (C) 1996-2008, International Business Machines Corporation and *
- * others. All Rights Reserved. *
+ * Copyright (C) 1996-2012, International Business Machines Corporation and
+ * others. All Rights Reserved.
******************************************************************************
*/
* 01/29/01 synwee Modified into a C++ wrapper calling C APIs (ucol.h)
*/
+#include "utypeinfo.h" // for 'typeid' to work
+
#include "unicode/utypes.h"
#if !UCONFIG_NO_COLLATION
#include "uresimp.h"
#include "ucln_in.h"
-static U_NAMESPACE_QUALIFIER Locale* availableLocaleList = NULL;
+static icu::Locale* availableLocaleList = NULL;
static int32_t availableLocaleListCount;
-static U_NAMESPACE_QUALIFIER ICULocaleService* gService = NULL;
+static icu::ICULocaleService* gService = NULL;
/**
* Release all static memory held by collator.
class ICUCollatorFactory : public ICUResourceBundleFactory {
public:
- ICUCollatorFactory(): ICUResourceBundleFactory(UnicodeString(U_ICUDATA_COLL, -1, US_INV)) { }
+ ICUCollatorFactory() : ICUResourceBundleFactory(UnicodeString(U_ICUDATA_COLL, -1, US_INV)) { }
+ virtual ~ICUCollatorFactory();
protected:
virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
};
+ICUCollatorFactory::~ICUCollatorFactory() {}
+
UObject*
ICUCollatorFactory::create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const {
if (handlesKey(key, status)) {
UErrorCode status = U_ZERO_ERROR;
registerFactory(new ICUCollatorFactory(), status);
}
-
+
+ virtual ~ICUCollatorService();
+
virtual UObject* cloneInstance(UObject* instance) const {
return ((Collator*)instance)->clone();
}
}
};
+ICUCollatorService::~ICUCollatorService() {}
+
// -------------------------------------
static ICULocaleService*
if (status && U_SUCCESS(*status) && hasService()) {
Locale desiredLocale(loc);
Collator *col = (Collator*)gService->get(desiredLocale, *status);
- if (col && col->getDynamicClassID() == RuleBasedCollator::getStaticClassID()) {
- RuleBasedCollator *rbc = (RuleBasedCollator *)col;
+ RuleBasedCollator *rbc;
+ if (col && (rbc = dynamic_cast<RuleBasedCollator *>(col))) {
if (!rbc->dataIsOwned) {
result = ucol_safeClone(rbc->ucollator, NULL, NULL, status);
} else {
result = rbc->ucollator;
rbc->ucollator = NULL; // to prevent free on delete
}
+ } else {
+ // should go in a function- ucol_initDelegate(delegate)
+ result = (UCollator *)uprv_malloc(sizeof(UCollator));
+ if(result == NULL) {
+ *status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ uprv_memset(result, 0, sizeof(UCollator));
+ result->delegate = col;
+ result->freeOnClose = TRUE; // do free on close.
+ col = NULL; // to prevent free on delete.
+ }
}
delete col;
}
umtx_lock(NULL);
if (availableLocaleList == NULL)
{
- availableLocaleList = temp;
availableLocaleListCount = localeCount;
+ availableLocaleList = temp;
temp = NULL;
ucln_i18n_registerCleanup(UCLN_I18N_COLLATOR, collator_cleanup);
}
Locale actualLoc;
Collator *result =
(Collator*)gService->get(desiredLocale, &actualLoc, status);
+
// Ugly Hack Alert! If the returned locale is empty (not root,
// but empty -- getName() == "") then that means the service
// returned a default object, not a "real" service object. In
}
#endif
+Collator *
+Collator::safeClone() const {
+ return clone();
+}
+
// implement deprecated, previously abstract method
Collator::EComparisonResult Collator::compare(const UnicodeString& source,
const UnicodeString& target) const
{
UErrorCode ec = U_ZERO_ERROR;
- return (Collator::EComparisonResult)compare(source, target, ec);
+ return (EComparisonResult)compare(source, target, ec);
}
// implement deprecated, previously abstract method
int32_t length) const
{
UErrorCode ec = U_ZERO_ERROR;
- return (Collator::EComparisonResult)compare(source, target, length, ec);
+ return (EComparisonResult)compare(source, target, length, ec);
}
// implement deprecated, previously abstract method
const
{
UErrorCode ec = U_ZERO_ERROR;
- return (Collator::EComparisonResult)compare(source, sourceLength, target, targetLength, ec);
+ return (EComparisonResult)compare(source, sourceLength, target, targetLength, ec);
+}
+
+UCollationResult Collator::compare(UCharIterator &/*sIter*/,
+ UCharIterator &/*tIter*/,
+ UErrorCode &status) const {
+ if(U_SUCCESS(status)) {
+ // Not implemented in the base class.
+ status = U_UNSUPPORTED_ERROR;
+ }
+ return UCOL_EQUAL;
+}
+
+UCollationResult Collator::compareUTF8(const StringPiece &source,
+ const StringPiece &target,
+ UErrorCode &status) const {
+ if(U_FAILURE(status)) {
+ return UCOL_EQUAL;
+ }
+ UCharIterator sIter, tIter;
+ uiter_setUTF8(&sIter, source.data(), source.length());
+ uiter_setUTF8(&tIter, target.data(), target.length());
+ return compare(sIter, tIter, status);
}
UBool Collator::equals(const UnicodeString& source,
UBool Collator::operator==(const Collator& other) const
{
- return (UBool)(this == &other);
+ // Subclasses: Call this method and then add more specific checks.
+ return typeid(*this) == typeid(other);
}
UBool Collator::operator!=(const Collator& other) const
}
}
}
-
- virtual ~CFactory()
- {
- delete _delegate;
- delete _ids;
- }
-
+
+ virtual ~CFactory();
+
virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const;
protected:
getDisplayName(const UnicodeString& id, const Locale& locale, UnicodeString& result) const;
};
+CFactory::~CFactory()
+{
+ delete _delegate;
+ delete _ids;
+}
+
UObject*
CFactory::create(const ICUServiceKey& key, const ICUService* /* service */, UErrorCode& status) const
{
//isAvailableLocaleListInitialized(status);
}
- virtual ~CollationLocaleListEnumeration() {
- }
+ virtual ~CollationLocaleListEnumeration();
virtual StringEnumeration * clone() const
{
if(index < availableLocaleListCount) {
result = availableLocaleList[index++].getName();
if(resultLength != NULL) {
- *resultLength = uprv_strlen(result);
+ *resultLength = (int32_t)uprv_strlen(result);
}
} else {
if(resultLength != NULL) {
}
};
+CollationLocaleListEnumeration::~CollationLocaleListEnumeration() {}
+
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CollationLocaleListEnumeration)
return new UStringEnumeration(uenum);
}
+StringEnumeration* U_EXPORT2
+Collator::getKeywordValuesForLocale(const char* key, const Locale& locale,
+ UBool commonlyUsed, UErrorCode& status) {
+ // This is a wrapper over ucol_getKeywordValuesForLocale
+ UEnumeration *uenum = ucol_getKeywordValuesForLocale(key, locale.getName(),
+ commonlyUsed, &status);
+ if (U_FAILURE(status)) {
+ uenum_close(uenum);
+ return NULL;
+ }
+ return new UStringEnumeration(uenum);
+}
+
Locale U_EXPORT2
Collator::getFunctionalEquivalent(const char* keyword, const Locale& locale,
UBool& isAvailable, UErrorCode& status) {
return Locale::createFromName(loc);
}
+Collator::ECollationStrength
+Collator::getStrength(void) const {
+ UErrorCode intStatus = U_ZERO_ERROR;
+ return (ECollationStrength)getAttribute(UCOL_STRENGTH, intStatus);
+}
+
+void
+Collator::setStrength(ECollationStrength newStrength) {
+ UErrorCode intStatus = U_ZERO_ERROR;
+ setAttribute(UCOL_STRENGTH, (UColAttributeValue)newStrength, intStatus);
+}
+
+int32_t
+Collator::getReorderCodes(int32_t* /* dest*/,
+ int32_t /* destCapacity*/,
+ UErrorCode& status) const
+{
+ if (U_SUCCESS(status)) {
+ status = U_UNSUPPORTED_ERROR;
+ }
+ return 0;
+}
+
+void
+Collator::setReorderCodes(const int32_t* /* reorderCodes */,
+ int32_t /* reorderCodesLength */,
+ UErrorCode& status)
+{
+ if (U_SUCCESS(status)) {
+ status = U_UNSUPPORTED_ERROR;
+ }
+}
+
+int32_t U_EXPORT2
+Collator::getEquivalentReorderCodes(int32_t /* reorderCode */,
+ int32_t* /* dest */,
+ int32_t /* destCapacity */,
+ UErrorCode& status)
+{
+ if (U_SUCCESS(status)) {
+ status = U_UNSUPPORTED_ERROR;
+ }
+ return 0;
+}
+
+int32_t
+Collator::internalGetShortDefinitionString(const char * /*locale*/,
+ char * /*buffer*/,
+ int32_t /*capacity*/,
+ UErrorCode &status) const {
+ if(U_SUCCESS(status)) {
+ status = U_UNSUPPORTED_ERROR; /* Shouldn't happen, internal function */
+ }
+ return 0;
+}
+
// UCollator private data members ----------------------------------------
/* This is useless information */