8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:03:03 +01:00

Rework on CORE-4125 to work with ICU 3.0.

This commit is contained in:
asfernandes 2013-06-26 02:15:24 +00:00
parent 22d12617bb
commit 6dedc68d41

View File

@ -77,14 +77,14 @@ public:
minorVersion(aMinorVersion),
inModule(NULL),
ucModule(NULL),
ciAiTrans(NULL)
ciAiTransCache(*getDefaultMemoryPool())
{
}
~ICU()
{
if (ciAiTrans)
utransClose(ciAiTrans);
while (ciAiTransCache.hasData())
utransClose(ciAiTransCache.pop());
delete ucModule;
delete inModule;
@ -108,12 +108,41 @@ public:
module->findSymbol(symbol, ptr);
}
UTransliterator* getCiAiTransliterator()
{
ciAiTransCacheMutex.enter();
UTransliterator* ret;
if (!ciAiTransCache.isEmpty())
{
ret = ciAiTransCache.pop();
ciAiTransCacheMutex.leave();
}
else
{
ciAiTransCacheMutex.leave();
UErrorCode errorCode = U_ZERO_ERROR;
ret = utransOpen("Any-Upper; NFD; [:Nonspacing Mark:] Remove; NFC",
UTRANS_FORWARD, NULL, 0, NULL, &errorCode);
}
return ret;
}
void releaseCiAiTransliterator(UTransliterator* trans)
{
MutexLockGuard guard(ciAiTransCacheMutex);
ciAiTransCache.push(trans);
}
int majorVersion;
int minorVersion;
ModuleLoader::Module* inModule;
ModuleLoader::Module* ucModule;
UVersionInfo collVersion;
UTransliterator* ciAiTrans;
Mutex ciAiTransCacheMutex;
Array<UTransliterator*> ciAiTransCache;
void (U_EXPORT2 *uInit)(UErrorCode* status);
void (U_EXPORT2 *uVersionToString)(UVersionInfo versionArray, char* versionString);
@ -146,9 +175,6 @@ public:
int32_t rulesLength, /* -1 if null-terminated */
UParseError* parseError, /* may be Null */
UErrorCode* status);
UTransliterator* (U_EXPORT2 *utransClone)(
const UTransliterator* trans,
UErrorCode* status);
void (U_EXPORT2 *utransTransUChars)(
const UTransliterator* trans,
UChar* text,
@ -893,7 +919,6 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const Firebird::string& icuVersion,
icu->getEntryPoint("ucol_strcoll", icu->inModule, icu->ucolStrColl);
icu->getEntryPoint("ucol_getVersion", icu->inModule, icu->ucolGetVersion);
icu->getEntryPoint("utrans_open", icu->inModule, icu->utransOpen);
icu->getEntryPoint("utrans_clone", icu->inModule, icu->utransClone);
icu->getEntryPoint("utrans_close", icu->inModule, icu->utransClose);
icu->getEntryPoint("utrans_transUChars", icu->inModule, icu->utransTransUChars);
@ -920,15 +945,6 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const Firebird::string& icuVersion,
}
}
icu->ciAiTrans = icu->utransOpen("Any-Upper; NFD; [:Nonspacing Mark:] Remove; NFC",
UTRANS_FORWARD, NULL, 0, NULL, &status);
if (!icu->ciAiTrans)
{
gds__log("utransOpen failed");
delete icu;
continue;
}
UCollator* collator = icu->ucolOpen("", &status);
if (!collator)
{
@ -1266,20 +1282,18 @@ ULONG UnicodeUtil::Utf16Collation::canonical(ULONG srcLen, const USHORT* src, UL
memcpy(upperStr.getBuffer(srcLen / sizeof(USHORT)), src, srcLen);
// ASF: We cannot use a single transliterator simultaneously in multiple threads,
// but the creation is expensive. It's much faster to clone a pre-created one.
UErrorCode errorCode = U_ZERO_ERROR;
UTransliterator* trans = icu->utransClone(icu->ciAiTrans, &errorCode);
UTransliterator* trans = icu->getCiAiTransliterator();
if (errorCode <= 0)
if (trans)
{
const int32_t capacity = upperStr.getCount();
int32_t len = srcLen / sizeof(USHORT);
int32_t limit = len;
UErrorCode errorCode = U_ZERO_ERROR;
icu->utransTransUChars(trans, reinterpret_cast<UChar*>(upperStr.begin()),
&len, capacity, 0, &limit, &errorCode);
icu->utransClose(trans);
icu->releaseCiAiTransliterator(trans);
len *= sizeof(USHORT);
if (ULONG(len) > dstLen)