Cache charset more efficiently in nsCollation. Bug 201670, author=neil@parkwaycc.co.uk, r=smontagu, sr=alecf

This commit is contained in:
smontagu%netscape.com 2003-04-21 23:51:25 +00:00
Родитель de70a5e3b9
Коммит 2d4cbb03b5
10 изменённых файлов: 54 добавлений и 148 удалений

Просмотреть файл

@ -149,7 +149,6 @@ nsresult nsCollationMac::Initialize(nsILocale* locale)
// locale -> script code + charset name
m_scriptcode = smRoman;
mCharset.Assign(NS_LITERAL_STRING("ISO-8859-1"));
PRUnichar *aLocaleUnichar;
nsAutoString aCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"));
@ -188,7 +187,7 @@ nsresult nsCollationMac::Initialize(nsILocale* locale)
PRUnichar* mappedCharset = NULL;
res = platformCharset->GetDefaultCharsetForLocale(aLocale.get(), &mappedCharset);
if (NS_SUCCEEDED(res) && mappedCharset) {
mCharset.Assign(mappedCharset);
res = mCollation->SetCharset(mappedCharset);
nsMemory::Free(mappedCharset);
}
}
@ -227,7 +226,7 @@ nsresult nsCollationMac::CreateRawSortKey(const nsCollationStrength strength,
char *str;
int str_len;
res = mCollation->UnicodeToChar(stringNormalized, &str, mCharset);
res = mCollation->UnicodeToChar(stringNormalized, &str);
if (NS_SUCCEEDED(res) && str != NULL) {
str_len = strlen(str);
NS_ASSERTION(str_len <= *outLen, "output buffer too small");

Просмотреть файл

@ -33,7 +33,6 @@ class nsCollationMac : public nsICollation {
protected:
nsCollation *mCollation; // XP collation class
nsString mCharset; // Charset name, used for the conversion
short m_scriptcode; // Macintosh platform script code
unsigned char m_mac_sort_tbl[256]; // Mapping table from a character code to a collation key value.

Просмотреть файл

@ -212,57 +212,61 @@ nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stri
return NS_OK;
}
nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst, const nsAString& aCharset)
nsresult nsCollation::SetCharset(const PRUnichar* aCharset)
{
NS_ENSURE_ARG_POINTER(aCharset);
nsresult rv;
nsCOMPtr <nsICharsetConverterManager2> charsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr <nsIAtom> charsetAtom;
rv = charsetConverterManager->GetCharsetAtom(aCharset, getter_AddRefs(charsetAtom));
if (NS_SUCCEEDED(rv))
rv = charsetConverterManager->GetUnicodeEncoder(charsetAtom, getter_AddRefs(mEncoder));
}
return rv;
}
nsresult nsCollation::UnicodeToChar(const nsAString& aSrc, char** dst)
{
NS_ENSURE_ARG_POINTER(dst);
nsresult res = NS_OK;
if (!mCharsetConverterManager)
mCharsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
if (!mEncoder)
res = SetCharset(NS_LITERAL_STRING("ISO-8859-1").get());
if (NS_SUCCEEDED(res)) {
nsCOMPtr <nsIAtom> charsetAtom;
res = mCharsetConverterManager->GetCharsetAtom(PromiseFlatString(aCharset).get(), getter_AddRefs(charsetAtom));
const nsPromiseFlatString& src = PromiseFlatString(aSrc);
const PRUnichar *unichars = src.get();
PRInt32 unicharLength = src.Length();
PRInt32 dstLength;
res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength);
if (NS_SUCCEEDED(res)) {
if (charsetAtom != mEncoderCharsetAtom) {
mEncoderCharsetAtom = charsetAtom;
res = mCharsetConverterManager->GetUnicodeEncoder(mEncoderCharsetAtom, getter_AddRefs(mEncoder));
}
if (NS_SUCCEEDED(res)) {
const nsPromiseFlatString& src = PromiseFlatString(aSrc);
const PRUnichar *unichars = src.get();
PRInt32 unicharLength = src.Length();
PRInt32 dstLength;
res = mEncoder->GetMaxLength(unichars, unicharLength, &dstLength);
if (NS_SUCCEEDED(res)) {
PRInt32 bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call
*dst = (char *) PR_Malloc(bufLength);
if (*dst) {
**dst = '\0';
res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength);
PRInt32 bufLength = dstLength + 1 + 32; // extra 32 bytes for Finish() call
*dst = (char *) PR_Malloc(bufLength);
if (*dst) {
**dst = '\0';
res = mEncoder->Convert(unichars, &unicharLength, *dst, &dstLength);
if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) {
// Finishes the conversion. The converter has the possibility to write some
// extra data and flush its final state.
PRInt32 finishLength = bufLength - dstLength; // remaining unused buffer length
if (finishLength > 0) {
res = mEncoder->Finish((*dst + dstLength), &finishLength);
if (NS_SUCCEEDED(res)) {
(*dst)[dstLength + finishLength] = '\0';
}
}
if (NS_SUCCEEDED(res) || (NS_ERROR_UENC_NOMAPPING == res)) {
// Finishes the conversion. The converter has the possibility to write some
// extra data and flush its final state.
PRInt32 finishLength = bufLength - dstLength; // remaining unused buffer length
if (finishLength > 0) {
res = mEncoder->Finish((*dst + dstLength), &finishLength);
if (NS_SUCCEEDED(res)) {
(*dst)[dstLength + finishLength] = '\0';
}
if (NS_FAILED(res)) {
PR_Free(*dst);
*dst = nsnull;
}
}
else {
res = NS_ERROR_OUT_OF_MEMORY;
}
}
}
if (NS_FAILED(res)) {
PR_Free(*dst);
*dst = nsnull;
}
}
else {
res = NS_ERROR_OUT_OF_MEMORY;
}
}
}

Просмотреть файл

@ -69,14 +69,12 @@ public:
nsresult NormalizeString(const nsAString& stringIn, nsAString& stringOut);
// charset conversion util, C string buffer is allocate by PR_Malloc, caller should call PR_Free
nsresult UnicodeToChar(const nsAString& aSrc, char** dst, const nsAString& aCharset);
nsresult SetCharset(const PRUnichar* aCharset);
nsresult UnicodeToChar(const nsAString& aSrc, char** dst);
protected:
nsCOMPtr <nsICaseConversion> mCaseConversion;
nsCOMPtr <nsIUnicodeEncoder> mEncoder;
nsCOMPtr <nsIAtom> mEncoderCharsetAtom;
nsCOMPtr <nsICharsetConverterManager2> mCharsetConverterManager;
};
#endif /* nsCollation_h__ */

Просмотреть файл

@ -60,8 +60,6 @@ nsCollationOS2::~nsCollationOS2()
nsresult nsCollationOS2::Initialize(nsILocale *locale)
{
#define kPlatformLocaleLength 64
#define MAPPEDCHARSET_BUFFER_LEN 80
NS_ASSERTION(mCollation == NULL, "Should only be initialized once");
nsresult res;
@ -72,82 +70,6 @@ nsresult nsCollationOS2::Initialize(nsILocale *locale)
return NS_ERROR_OUT_OF_MEMORY;
}
// default local charset name
mCharset.Assign(NS_LITERAL_STRING("ISO-8859-1"));
// default platform locale
mLocale.Assign(NS_LITERAL_STRING("C"));
PRUnichar *aLocaleUnichar = NULL;
nsString aCategory;
aCategory.Assign(NS_LITERAL_STRING("NSILOCALE_COLLATE"));
// get locale string, use app default if no locale specified
if (locale == nsnull) {
nsCOMPtr<nsILocaleService> localeService =
do_GetService(NS_LOCALESERVICE_CONTRACTID, &res);
if (NS_SUCCEEDED(res)) {
nsILocale *appLocale;
res = localeService->GetApplicationLocale(&appLocale);
if (NS_SUCCEEDED(res)) {
res = appLocale->GetCategory(aCategory.get(), &aLocaleUnichar);
appLocale->Release();
}
}
}
else {
res = locale->GetCategory(aCategory.get(), &aLocaleUnichar);
}
// Get platform locale and charset name from locale, if available
if (NS_SUCCEEDED(res)) {
nsString aLocale;
aLocale = aLocaleUnichar;
if (NULL != aLocaleUnichar) {
nsMemory::Free(aLocaleUnichar);
}
// keep the same behavior as 4.x as well as avoiding Linux collation key problem
if (aLocale.EqualsIgnoreCase("en-US")) {
aLocale.Assign(NS_LITERAL_STRING("C"));
}
nsCOMPtr <nsIOS2Locale> os2Locale = do_GetService(NS_OS2LOCALE_CONTRACTID, &res);
if (NS_SUCCEEDED(res)) {
PRUnichar platformLocale[kPlatformLocaleLength+1];
res = os2Locale->GetPlatformLocale(platformLocale, kPlatformLocaleLength+1);
if (NS_SUCCEEDED(res)) {
mLocale.Assign(platformLocale, kPlatformLocaleLength+1);
}
}
// Create a locale object and query for the code page
nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &res);
if (NS_SUCCEEDED(res)) {
PRUnichar mappedCharset[MAPPEDCHARSET_BUFFER_LEN] = { 0 };
LocaleObject locObj = NULL;
UniChar *pmCodepage;
int ret = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)mLocale.get(), &locObj);
if (ret != ULS_SUCCESS)
return NS_ERROR_FAILURE;
ret = UniQueryLocaleItem(locObj, LOCI_iCodepage, &pmCodepage);
if (ret != ULS_SUCCESS)
return NS_ERROR_FAILURE;
int cpLen = UniStrlen((UniChar*)pmCodepage);
UniStrncpy((UniChar *)mappedCharset, pmCodepage, cpLen);
UniFreeMem(pmCodepage);
UniFreeLocaleObject(locObj);
PRUint32 mpLen = UniStrlen(NS_REINTERPRET_CAST(const UniChar *, mappedCharset));
if (NS_SUCCEEDED(ret) && mappedCharset) {
mCharset.Assign((PRUnichar*)mappedCharset, mpLen);
}
}
}
return NS_OK;
}

Просмотреть файл

@ -32,7 +32,6 @@ protected:
nsCollation *mCollation;
nsString mLocale;
nsString mSavedLocale;
nsString mCharset;
public:
NS_DECL_ISUPPORTS

Просмотреть файл

@ -112,9 +112,6 @@ nsresult nsCollationUnix::Initialize(nsILocale* locale)
return NS_ERROR_OUT_OF_MEMORY;
}
// default local charset name
mCharset.Assign(NS_LITERAL_STRING("ISO-8859-1"));
// default platform locale
mLocale.Assign('C');
@ -168,19 +165,12 @@ nsresult nsCollationUnix::Initialize(nsILocale* locale)
PRUnichar* mappedCharset = NULL;
res = platformCharset->GetDefaultCharsetForLocale(aLocale.get(), &mappedCharset);
if (NS_SUCCEEDED(res) && mappedCharset) {
mCharset = mappedCharset;
mCollation->SetCharset(mappedCharset);
nsMemory::Free(mappedCharset);
}
}
}
#if defined(DEBUG_UNIX_COLLATION)
printf("nsCollationUnix::Initialize mLocale = %s\n"
"nsCollationUnix::Initialize mCharset = %s\n",
mLocale.get(),
NS_LossyConvertUCS2toASCII(mCharset).get());
#endif
return NS_OK;
};
@ -203,7 +193,7 @@ nsresult nsCollationUnix::GetSortKeyLen(const nsCollationStrength strength,
// convert unicode to charset
char *str;
res = mCollation->UnicodeToChar(stringNormalized, &str, mCharset);
res = mCollation->UnicodeToChar(stringNormalized, &str);
if (NS_SUCCEEDED(res) && str != NULL) {
if (mUseCodePointOrder) {
*outLen = strlen(str);
@ -236,7 +226,7 @@ nsresult nsCollationUnix::CreateRawSortKey(const nsCollationStrength strength,
// convert unicode to charset
char *str;
res = mCollation->UnicodeToChar(stringNormalized, &str, mCharset);
res = mCollation->UnicodeToChar(stringNormalized, &str);
if (NS_SUCCEEDED(res) && str != NULL) {
if (mUseCodePointOrder) {
*outLen = strlen(str);

Просмотреть файл

@ -35,7 +35,6 @@ protected:
nsCollation *mCollation;
nsCString mLocale;
nsCString mSavedLocale;
nsString mCharset;
PRBool mUseCodePointOrder;
void DoSetLocale();

Просмотреть файл

@ -86,9 +86,6 @@ nsresult nsCollationWin::Initialize(nsILocale* locale)
else {
mW_API = PR_FALSE;
}
// default charset name
mCharset.Assign(NS_LITERAL_STRING("ISO-8859-1"));
// default LCID (en-US)
mLCID = 1033;
@ -135,7 +132,7 @@ nsresult nsCollationWin::Initialize(nsILocale* locale)
PRUnichar* mappedCharset = NULL;
res = platformCharset->GetDefaultCharsetForLocale(aLocale.get(), &mappedCharset);
if (NS_SUCCEEDED(res) && mappedCharset) {
mCharset.Assign(mappedCharset);
mCollation->SetCharset(mappedCharset);
nsMemory::Free(mappedCharset);
}
}
@ -161,7 +158,7 @@ nsresult nsCollationWin::GetSortKeyLen(const nsCollationStrength strength,
}
else {
char *Cstr = nsnull;
res = mCollation->UnicodeToChar(stringIn, &Cstr, mCharset);
res = mCollation->UnicodeToChar(stringIn, &Cstr);
if (NS_SUCCEEDED(res) && Cstr != nsnull) {
*outLen = LCMapStringA(mLCID, dwMapFlags, Cstr, PL_strlen(Cstr), NULL, 0);
PR_Free(Cstr);
@ -187,7 +184,7 @@ nsresult nsCollationWin::CreateRawSortKey(const nsCollationStrength strength,
}
else {
char *Cstr = nsnull;
res = mCollation->UnicodeToChar(stringIn, &Cstr, mCharset);
res = mCollation->UnicodeToChar(stringIn, &Cstr);
if (NS_SUCCEEDED(res) && Cstr != nsnull) {
byteLen = LCMapStringA(mLCID, dwMapFlags, Cstr, PL_strlen(Cstr), (char *) key, (int) *outLen);
PR_Free(Cstr);

Просмотреть файл

@ -34,7 +34,6 @@ class nsCollationWin : public nsICollation {
protected:
nsCollation *mCollation; // XP collation class
PRBool mW_API; // If Windows95 or 98, we cannot use W version of API
nsString mCharset; // for unicode conversion
PRUint32 mLCID; // Windows platform locale ID
public: