X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/46f4442e9a5a4f3b98b7c1083586332f6a8a99a4..586446045a9ad027ace9532db9e32639f87706dd:/icuSources/i18n/translit.cpp diff --git a/icuSources/i18n/translit.cpp b/icuSources/i18n/translit.cpp index a39d6e91..bb9ba9b1 100644 --- a/icuSources/i18n/translit.cpp +++ b/icuSources/i18n/translit.cpp @@ -1,6 +1,6 @@ /* ********************************************************************** - * Copyright (C) 1999-2008, International Business Machines + * Copyright (C) 1999-2012, International Business Machines * Corporation and others. All Rights Reserved. ********************************************************************** * Date Name Description @@ -8,6 +8,8 @@ ********************************************************************** */ +#include "utypeinfo.h" // for 'typeid' to work + #include "unicode/utypes.h" #if !UCONFIG_NO_TRANSLITERATION @@ -22,6 +24,7 @@ #include "unicode/uniset.h" #include "unicode/uscript.h" #include "unicode/strenum.h" +#include "unicode/utf16.h" #include "cpdtrans.h" #include "nultrans.h" #include "rbt_data.h" @@ -86,20 +89,17 @@ static const char RB_RULE_BASED_IDS[] = "RuleBasedTransliteratorIDs"; /** * The mutex controlling access to registry object. */ -static UMTX registryMutex = 0; +static UMutex registryMutex = U_MUTEX_INITIALIZER; /** * System transliterator registry; non-null when initialized. */ -static U_NAMESPACE_QUALIFIER TransliteratorRegistry* registry = 0; +static icu::TransliteratorRegistry* registry = 0; // Macro to check/initialize the registry. ONLY USE WITHIN // MUTEX. Avoids function call when registry is initialized. #define HAVE_REGISTRY(status) (registry!=0 || initializeRegistry(status)) -// Empty string -static const UChar EMPTY[] = {0}; //"" - U_NAMESPACE_BEGIN UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(Transliterator) @@ -369,7 +369,7 @@ void Transliterator::_transliterate(Replaceable& text, } if (index.limit > 0 && - UTF_IS_LEAD(text.charAt(index.limit - 1))) { + U16_IS_LEAD(text.charAt(index.limit - 1))) { // Oops, there is a dangling lead surrogate in the buffer. // This will break most transliterators, since they will // assume it is part of a pair. Don't transliterate until @@ -408,7 +408,7 @@ void Transliterator::_transliterate(Replaceable& text, int32_t n = getMaximumContextLength(); while (newCS > originalStart && n-- > 0) { --newCS; - newCS -= UTF_CHAR_LENGTH(text.char32At(newCS)) - 1; + newCS -= U16_LENGTH(text.char32At(newCS)) - 1; } index.contextStart = uprv_max(newCS, originalStart); #endif @@ -479,14 +479,14 @@ void Transliterator::filteredTransliterate(Replaceable& text, UChar32 c; while (index.start < globalLimit && !filter->contains(c=text.char32At(index.start))) { - index.start += UTF_CHAR_LENGTH(c); + index.start += U16_LENGTH(c); } // Find the end of this run of unfiltered chars index.limit = index.start; while (index.limit < globalLimit && filter->contains(c=text.char32At(index.limit))) { - index.limit += UTF_CHAR_LENGTH(c); + index.limit += U16_LENGTH(c); } } @@ -569,8 +569,7 @@ void Transliterator::filteredTransliterate(Replaceable& text, // transliterations and commit complete transliterations. for (;;) { // Length of additional code point, either one or two - int32_t charLength = - UTF_CHAR_LENGTH(text.char32At(passLimit)); + int32_t charLength = U16_LENGTH(text.char32At(passLimit)); passLimit += charLength; if (passLimit > runLimit) { break; @@ -596,7 +595,7 @@ void Transliterator::filteredTransliterate(Replaceable& text, int32_t rs = rollbackStart + delta - (index.limit - passStart); // Delete the partially transliterated text - text.handleReplaceBetween(passStart, index.limit, EMPTY); + text.handleReplaceBetween(passStart, index.limit, UnicodeString()); // Copy the rollback text back text.copy(rs, rs + uncommittedLength, passStart); @@ -634,7 +633,7 @@ void Transliterator::filteredTransliterate(Replaceable& text, globalLimit += totalDelta; // Delete the rollback copy - text.handleReplaceBetween(rollbackOrigin, rollbackOrigin + runLength, EMPTY); + text.handleReplaceBetween(rollbackOrigin, rollbackOrigin + runLength, UnicodeString()); // Move start past committed text index.start = passStart; @@ -977,7 +976,6 @@ Transliterator* Transliterator::createBasicInstance(const UnicodeString& id, TransliteratorAlias* alias = 0; Transliterator* t = 0; - umtx_init(®istryMutex); umtx_lock(®istryMutex); if (HAVE_REGISTRY(ec)) { t = registry->get(id, alias, ec); @@ -1101,7 +1099,7 @@ Transliterator::createFromRules(const UnicodeString& ID, UnicodeString* idBlock = (UnicodeString*)parser.idBlockVector.elementAt(i); if (!idBlock->isEmpty()) { Transliterator* temp = createInstance(*idBlock, UTRANS_FORWARD, parseError, status); - if (temp != NULL && temp->getDynamicClassID() != NullTransliterator::getStaticClassID()) + if (temp != NULL && typeid(*temp) != typeid(NullTransliterator)) transliterators.addElement(temp, status); else delete temp; @@ -1109,7 +1107,8 @@ Transliterator::createFromRules(const UnicodeString& ID, } if (!parser.dataVector.isEmpty()) { TransliterationRuleData* data = (TransliterationRuleData*)parser.dataVector.orphanElementAt(0); - RuleBasedTransliterator* temprbt = new RuleBasedTransliterator(UnicodeString(CompoundTransliterator::PASS_STRING) + (passNumber++), + // TODO: Should passNumber be turned into a decimal-string representation (1 -> "1")? + RuleBasedTransliterator* temprbt = new RuleBasedTransliterator(UnicodeString(CompoundTransliterator::PASS_STRING) + UnicodeString(passNumber++), data, TRUE); // Check if NULL before adding it to transliterators to avoid future usage of NULL pointer. if (temprbt == NULL) { @@ -1145,7 +1144,7 @@ UnicodeString& Transliterator::toRules(UnicodeString& rulesSource, if (!ICU_Utility::escapeUnprintable(rulesSource, c)) { rulesSource.append(c); } - i += UTF_CHAR_LENGTH(c); + i += U16_LENGTH(c); } } else { rulesSource = getID(); @@ -1157,18 +1156,15 @@ UnicodeString& Transliterator::toRules(UnicodeString& rulesSource, } int32_t Transliterator::countElements() const { - return (this->getDynamicClassID() == - CompoundTransliterator::getStaticClassID()) ? - ((const CompoundTransliterator*) this)->getCount() : 0; + const CompoundTransliterator* ct = dynamic_cast(this); + return ct != NULL ? ct->getCount() : 0; } const Transliterator& Transliterator::getElement(int32_t index, UErrorCode& ec) const { if (U_FAILURE(ec)) { return *this; } - const CompoundTransliterator* cpd = - (this->getDynamicClassID() == CompoundTransliterator::getStaticClassID()) ? - (const CompoundTransliterator*) this : 0; + const CompoundTransliterator* cpd = dynamic_cast(this); int32_t n = (cpd == NULL) ? 1 : cpd->getCount(); if (index < 0 || index >= n) { ec = U_INDEX_OUTOFBOUNDS_ERROR; @@ -1181,13 +1177,11 @@ const Transliterator& Transliterator::getElement(int32_t index, UErrorCode& ec) UnicodeSet& Transliterator::getSourceSet(UnicodeSet& result) const { handleGetSourceSet(result); if (filter != NULL) { - UnicodeSet* filterSet; + UnicodeSet* filterSet = dynamic_cast(filter); UBool deleteFilterSet = FALSE; // Most, but not all filters will be UnicodeSets. Optimize for // the high-runner case. - if (filter->getDynamicClassID() == UnicodeSet::getStaticClassID()) { - filterSet = (UnicodeSet*) filter; - } else { + if (filterSet == NULL) { filterSet = new UnicodeSet(); // Check null pointer if (filterSet == NULL) { @@ -1216,7 +1210,6 @@ UnicodeSet& Transliterator::getTargetSet(UnicodeSet& result) const { void U_EXPORT2 Transliterator::registerFactory(const UnicodeString& id, Transliterator::Factory factory, Transliterator::Token context) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1256,7 +1249,6 @@ void Transliterator::_registerSpecialInverse(const UnicodeString& target, * @see #unregister */ void U_EXPORT2 Transliterator::registerInstance(Transliterator* adoptedPrototype) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1271,7 +1263,6 @@ void Transliterator::_registerInstance(Transliterator* adoptedPrototype) { void U_EXPORT2 Transliterator::registerAlias(const UnicodeString& aliasID, const UnicodeString& realID) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1294,7 +1285,6 @@ void Transliterator::_registerAlias(const UnicodeString& aliasID, */ void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1310,7 +1300,6 @@ void U_EXPORT2 Transliterator::unregister(const UnicodeString& ID) { */ int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) { int32_t retVal = 0; - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1327,7 +1316,6 @@ int32_t U_EXPORT2 Transliterator::countAvailableIDs(void) { */ const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) { const UnicodeString* result = NULL; - umtx_init(®istryMutex); umtx_lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1341,7 +1329,6 @@ const UnicodeString& U_EXPORT2 Transliterator::getAvailableID(int32_t index) { StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) { if (U_FAILURE(ec)) return NULL; StringEnumeration* result = NULL; - umtx_init(®istryMutex); umtx_lock(®istryMutex); if (HAVE_REGISTRY(ec)) { result = registry->getAvailableIDs(); @@ -1354,7 +1341,6 @@ StringEnumeration* U_EXPORT2 Transliterator::getAvailableIDs(UErrorCode& ec) { } int32_t U_EXPORT2 Transliterator::countAvailableSources(void) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; return HAVE_REGISTRY(ec) ? _countAvailableSources() : 0; @@ -1362,7 +1348,6 @@ int32_t U_EXPORT2 Transliterator::countAvailableSources(void) { UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index, UnicodeString& result) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1372,7 +1357,6 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableSource(int32_t index, } int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& source) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; return HAVE_REGISTRY(ec) ? _countAvailableTargets(source) : 0; @@ -1381,7 +1365,6 @@ int32_t U_EXPORT2 Transliterator::countAvailableTargets(const UnicodeString& sou UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index, const UnicodeString& source, UnicodeString& result) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1392,7 +1375,6 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableTarget(int32_t index, int32_t U_EXPORT2 Transliterator::countAvailableVariants(const UnicodeString& source, const UnicodeString& target) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; return HAVE_REGISTRY(ec) ? _countAvailableVariants(source, target) : 0; @@ -1402,7 +1384,6 @@ UnicodeString& U_EXPORT2 Transliterator::getAvailableVariant(int32_t index, const UnicodeString& source, const UnicodeString& target, UnicodeString& result) { - umtx_init(®istryMutex); Mutex lock(®istryMutex); UErrorCode ec = U_ZERO_ERROR; if (HAVE_REGISTRY(ec)) { @@ -1464,7 +1445,7 @@ UChar Transliterator::filteredCharAt(const Replaceable& text, int32_t i) const { * and return TRUE. If the registry cannot be initialized, return * FALSE (rare). * - * IMPORTANT: Upon entry, registryMutex must be LOCKED. The entirely + * IMPORTANT: Upon entry, registryMutex must be LOCKED. The entire * initialization is done with the lock held. There is NO REASON to * unlock, since no other thread that is waiting on the registryMutex * cannot itself proceed until the registry is initialized. @@ -1631,7 +1612,7 @@ UBool Transliterator::initializeRegistry(UErrorCode &status) { _registerSpecialInverse(UNICODE_STRING_SIMPLE("Title"), UNICODE_STRING_SIMPLE("Lower"), FALSE); - ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, transliterator_cleanup); + ucln_i18n_registerCleanup(UCLN_I18N_TRANSLITERATOR, utrans_transliterator_cleanup); return TRUE; } @@ -1645,14 +1626,13 @@ U_NAMESPACE_END * necessarily invalidate any rule-based transliterators held by the * user, because RBTs hold pointers to common data objects. */ -U_CFUNC UBool transliterator_cleanup(void) { +U_CFUNC UBool utrans_transliterator_cleanup(void) { U_NAMESPACE_USE TransliteratorIDParser::cleanup(); if (registry) { delete registry; registry = NULL; } - umtx_destroy(®istryMutex); return TRUE; }