зеркало из https://github.com/mozilla/pjs.git
Cache charset more efficiently in nsCollation. Bug 201670, author=neil@parkwaycc.co.uk, r=smontagu, sr=alecf
This commit is contained in:
Родитель
de70a5e3b9
Коммит
2d4cbb03b5
|
@ -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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче