Bug 207634 Convert GetSortKeyLen/CreateRawSortKey to AllocateRawSortKey r=smontagu sr=sspitzer

git-svn-id: svn://10.0.0.236/trunk@145164 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
neil%parkwaycc.co.uk 2003-07-24 20:31:35 +00:00
parent 7019c27f54
commit 7dc82ecf66
20 changed files with 278 additions and 511 deletions

View File

@ -133,10 +133,10 @@ TxObject* txResultStringComparator::createSortableValue(txAExprResult* aExprRes)
if (nsCaseKey.IsEmpty()) {
return val;
}
nsresult rv = createRawSortKey(kCollationCaseInSensitive,
nsCaseKey,
&val->mKey,
&val->mLength);
nsresult rv = mCollation->AllocateRawSortKey(kCollationCaseInSensitive,
nsCaseKey,
&val->mKey,
&val->mLength);
if (NS_FAILED(rv)) {
NS_ERROR("Failed to create raw sort key");
delete val;
@ -198,10 +198,10 @@ int txResultStringComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
if ((strval1->mCaseLength == 0) && (strval1->mLength != 0)) {
nsString* caseString = (nsString *)strval1->mCaseKey;
rv = createRawSortKey(kCollationCaseSensitive,
*caseString,
(PRUint8**)&strval1->mCaseKey,
&strval1->mCaseLength);
rv = mCollation->AllocateRawSortKey(kCollationCaseSensitive,
*caseString,
(PRUint8**)&strval1->mCaseKey,
&strval1->mCaseLength);
if (NS_FAILED(rv)) {
// XXX ErrorReport
strval1->mCaseKey = caseString;
@ -212,10 +212,10 @@ int txResultStringComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
}
if ((strval2->mCaseLength == 0) && (strval2->mLength != 0)) {
nsString* caseString = (nsString *)strval2->mCaseKey;
rv = createRawSortKey(kCollationCaseSensitive,
*caseString,
(PRUint8**)&strval2->mCaseKey,
&strval2->mCaseLength);
rv = mCollation->AllocateRawSortKey(kCollationCaseSensitive,
*caseString,
(PRUint8**)&strval2->mCaseKey,
&strval2->mCaseLength);
if (NS_FAILED(rv)) {
// XXX ErrorReport
strval2->mCaseKey = caseString;
@ -238,21 +238,6 @@ int txResultStringComparator::compareValues(TxObject* aVal1, TxObject* aVal2)
}
#ifndef TX_EXE
nsresult txResultStringComparator::createRawSortKey(const nsCollationStrength aStrength,
const nsString& aString,
PRUint8** aKey,
PRUint32* aLength)
{
nsresult rv = mCollation->GetSortKeyLen(aStrength, aString, aLength);
*aKey = (PRUint8*)PR_MALLOC(*aLength);
if (!*aKey)
return NS_ERROR_OUT_OF_MEMORY;
rv = mCollation->CreateRawSortKey(aStrength, aString, *aKey, aLength);
return rv;
}
txResultStringComparator::StringValue::StringValue() : mKey(0),
mCaseKey(0),
mLength(0),

View File

@ -662,16 +662,9 @@ nsFontMetricsOS2::LoadFont( HPS aPS, nsString* aFontname )
tempname.Append( NS_LITERAL_STRING(" ") );
}
PRInt32 res = gCollation->GetSortKeyLen(kCollationCaseInSensitive,
tempname, &keylen);
if( NS_SUCCEEDED(res) )
{
key = (PRUint8*) nsMemory::Alloc(keylen * sizeof(PRUint8));
res = gCollation->CreateRawSortKey( kCollationCaseInSensitive,
tempname, key,
&keylen );
}
PRInt32 res = gCollation->AllocateRawSortKey( kCollationCaseInSensitive,
tempname, &key,
&keylen );
NS_ASSERTION( NS_SUCCEEDED(res), "Create collation keys failed!" );
int i = gCachedIndex;
@ -758,12 +751,9 @@ nsFontMetricsOS2::LoadFont( HPS aPS, nsString* aFontname )
i = font->nextFamily + count;
} // end while
PR_FREEIF(key);
if( fh )
{
if( key )
nsMemory::Free(key);
return fh;
}
// If a font was not found, then maybe "familyname" is really a face name.
// See if a font with that facename exists on system and fake any applied
@ -1923,16 +1913,11 @@ nsFontMetricsOS2::InitializeGlobalFonts()
}
// Create collation sort key
res = gCollation->GetSortKeyLen(kCollationCaseInSensitive,
font->name, &font->len);
res = gCollation->AllocateRawSortKey(kCollationCaseInSensitive,
font->name, &font->key, &font->len);
if (NS_SUCCEEDED(res))
{
font->key = (PRUint8*) nsMemory::Alloc(font->len * sizeof(PRUint8));
res = gCollation->CreateRawSortKey( kCollationCaseInSensitive,
font->name, font->key,
&font->len );
// reset DBCS name to actual value
if (fontptr[0] == '@')
font->name.Insert( NS_LITERAL_STRING("@"), 0 );

View File

@ -72,15 +72,10 @@ public:
NS_IMETHOD CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result) = 0;
// get a length (of character) of a sort key to be generated by an input string
// length is a byte length
NS_IMETHOD GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen) = 0;
// create sort key from input string
// length is a byte length, caller should allocate a memory for a key
NS_IMETHOD CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32 *outLen) = 0;
// allocate sort key from input string
// returns newly allocated key and its byte length
NS_IMETHOD AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32 *outLen) = 0;
// compare two sort keys
// length is a byte length, result is same as strcmp

View File

@ -200,17 +200,32 @@ nsresult nsCollationMac::Initialize(nsILocale* locale)
return NS_OK;
};
nsresult nsCollationMac::CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{
PRUint32 aLength1, aLength2;
PRUint8 *aKey1 = nsnull, *aKey2 = nsnull;
nsresult res;
res = AllocateRawSortKey(strength, string1, &aKey1, &aLength1);
if (NS_SUCCEEDED(res)) {
res = AllocateRawSortKey(strength, string2, &aKey2, &aLength2);
if (NS_SUCCEEDED(res))
*result = strcmp((const char *)key1, (const char *)key2); // compare keys
}
// delete keys
PR_FREEIF(aKey1);
PR_FREEIF(aKey2);
return res;
}
nsresult nsCollationMac::GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen)
{
*outLen = stringIn.Length() * sizeof(PRUnichar);
return NS_OK;
}
nsresult nsCollationMac::CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen)
nsresult nsCollationMac::AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32* outLen)
{
nsresult res = NS_OK;
@ -228,42 +243,41 @@ nsresult nsCollationMac::CreateRawSortKey(const nsCollationStrength strength,
res = mCollation->UnicodeToChar(stringNormalized, &str);
if (NS_SUCCEEDED(res) && str != NULL) {
str_len = strlen(str);
NS_ASSERTION(str_len <= int(*outLen), "output buffer too small");
*key = str;
*outLen = str_len + 1;
// If no CJK then generate a collation key
if (smJapanese != m_scriptcode && smKorean != m_scriptcode &&
smTradChinese != m_scriptcode && smSimpChinese != m_scriptcode) {
for (int i = 0; i < str_len; i++) {
*key++ = (PRUint8) mac_sort_tbl_search((const unsigned char) str[i], m_mac_sort_tbl);
while (*str) {
*str = (PRUint8) mac_sort_tbl_search((const unsigned char) *str, m_mac_sort_tbl);
++str;
}
}
else {
// No CJK support, just copy the row string.
// Collation key is not a string, use memcpy instead of strcpy.
memcpy(key, str, str_len);
PRUint8 *end = key + str_len;
while (key < end) {
if ((unsigned char) *key < 128) {
key++;
}
else {
while (*str) {
if ((unsigned char) *str >= 128) {
// ShiftJIS specific, shift hankaku kana in front of zenkaku.
if (smJapanese == m_scriptcode) {
if (*key >= 0xA0 && *key < 0xE0) {
*key -= (0xA0 - 0x81);
if (*str >= 0xA0 && *str < 0xE0) {
*str -= (0xA0 - 0x81);
}
else if (*key >= 0x81 && *key < 0xA0) {
*key += (0xE0 - 0xA0);
else if (*str >= 0x81 && *str < 0xA0) {
*str += (0xE0 - 0xA0);
}
}
// advance 2 bytes if the API says so and not passing the end of the string
key += ((smFirstByte == CharacterByteType((Ptr) key, 0, m_scriptcode)) &&
(*(key + 1))) ? 2 : 1;
if (CharacterByteType((Ptr) str, 0, m_scriptcode) == smFirstByte) {
++str;
if (!*str)
break;
}
}
++str;
}
}
*outLen = str_len;
PR_Free(str);
}
return NS_OK;

View File

@ -43,25 +43,19 @@ public:
// compare two strings
// result is same as strcmp
NS_IMETHOD CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{return mCollation->CompareString(this, strength, string1, string2, result);}
const nsAString& string1, const nsAString& string2, PRInt32* result);
// get a length (of character) of a sort key to be generated by an input string
// length is character length not byte length
NS_IMETHOD GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen);
// create sort key from input string
// length is character length not byte length, caller to allocate a memory for a key
NS_IMETHOD CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen);
// allocate sort key from input string
// returns newly allocated key and its byte length
NS_IMETHOD AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32 *outLen);
// compare two sort keys
// length is character length not byte length, result is same as strcmp
NS_IMETHOD CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2,
PRInt32* result)
{*result = mCollation->CompareRawSortKey(key1, len1, key2, len2);return NS_OK;}
{*result = strcmp((const char *)key1, (const char *)key2); return NS_OK;}
// init this interface to a specified locale (should only be called by collation factory)
//

View File

@ -51,6 +51,8 @@ NS_IMPL_ISUPPORTS1(nsCollationMacUC, nsICollation);
nsCollationMacUC::nsCollationMacUC()
: mInit(PR_FALSE)
, mHasCollator(PR_FALSE)
, mBuffer(nsnull)
, mBufferLen(1)
{
}
@ -62,6 +64,7 @@ nsCollationMacUC::~nsCollationMacUC()
mHasCollator = PR_FALSE;
NS_ASSERTION((err == noErr), "UCDisposeCollator failed");
}
PR_FREEIF(mBuffer);
}
nsresult nsCollationMacUC::StrengthToOptions(
@ -70,27 +73,13 @@ nsresult nsCollationMacUC::StrengthToOptions(
{
NS_ENSURE_ARG_POINTER(aOptions);
NS_ENSURE_TRUE((aStrength < 4), NS_ERROR_FAILURE);
// set our default collaion option
UCCollateOptions defaultOption = kUCCollateStandardOptions | kUCCollatePunctuationSignificantMask;
switch (aStrength) {
case kCollationCaseInsensitiveAscii:
*aOptions = defaultOption
| kUCCollateCaseInsensitiveMask;
break;
case kCollationAccentInsenstive:
*aOptions = defaultOption
| kUCCollateDiacritInsensitiveMask;
break;
case kCollationCaseInSensitive:
*aOptions = defaultOption
| kUCCollateCaseInsensitiveMask
| kUCCollateDiacritInsensitiveMask;
break;
case kCollationCaseSensitive:
default:
*aOptions = defaultOption;
break;
}
// set our default collation options
UCCollateOptions options = kUCCollateStandardOptions | kUCCollatePunctuationSignificantMask;
if (aStrength & kCollationCaseInsensitiveAscii)
options |= kUCCollateCaseInsensitiveMask;
if (aStrength & kCollationAccentInsensitive)
options |= kUCCollateDiacritInsensitiveMask;
*aOptions = options;
return NS_OK;
}
@ -167,88 +156,53 @@ NS_IMETHODIMP nsCollationMacUC::Initialize(
};
NS_IMETHODIMP nsCollationMacUC::GetSortKeyLen(
const nsCollationStrength strength,
const nsAString& stringIn,
PRUint32* outLen)
{
NS_ENSURE_ARG_POINTER(outLen);
// If possible, a length is estimated by actually creating a key (and cache the result).
// If the string is too big then return the length by the formula.
mCachedStringLen = stringIn.Length();
// Set the default value for an output length.
*outLen = (1 + mCachedStringLen) * kCollationValueSizeFactor * sizeof(UCCollationValue);
if (mCachedStringLen > kCacheSize)
{
mCachedStringLen = mCachedKeyLen = 0; // indicate key is not cached
return NS_OK;
}
nsresult res = EnsureCollator(strength);
NS_ENSURE_SUCCESS(res, res);
ItemCount actual;
memcpy((void *) mCachedString, (void *) PromiseFlatString(stringIn).get(),
mCachedStringLen * sizeof(UniChar));
OSErr err = ::UCGetCollationKey(mCollator, (const UniChar *) mCachedString,
(ItemCount) mCachedStringLen,
kCacheSize * kCollationValueSizeFactor,
&actual, (UCCollationValue *) mCachedKey);
if (err == noErr)
*outLen = mCachedKeyLen = actual * sizeof(UCCollationValue);
else
mCachedStringLen = mCachedKeyLen = 0;
return NS_OK;
}
NS_IMETHODIMP nsCollationMacUC::CreateRawSortKey(
const nsCollationStrength strength,
const nsAString& stringIn,
PRUint8* key,
NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(
const nsCollationStrength strength,
const nsAString& stringIn,
PRUint8** key,
PRUint32* outLen)
{
NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_ARG_POINTER(key);
NS_ENSURE_ARG_POINTER(outLen);
*outLen = 0;
nsresult res = EnsureCollator(strength);
NS_ENSURE_SUCCESS(res, res);
OSStatus err;
// If we already get a key at the estimation then just copy the cached data.
PRUint32 stringInLen = stringIn.Length();
if (mCachedKeyLen &&
mCachedStringLen == stringInLen &&
!memcmp((void *) mCachedString,
(void *) (const UniChar*) PromiseFlatString(stringIn).get(), stringInLen*sizeof(UniChar)))
{
memcpy((void *) key, (void *) mCachedKey, mCachedKeyLen);
*outLen = mCachedKeyLen;
return NS_OK;
PRUint32 maxKeyLen = (1 + stringInLen) * kCollationValueSizeFactor * sizeof(UCCollationValue);
if (maxKeyLen > mBufferLen) {
PRUint32 newBufferLen = mBufferLen;
do newBufferLen *= 2;
while (maxKeyLen > newBufferLen);
void *newBuffer = PR_Malloc(newBufferLen);
if (!newBuffer)
return NS_ERROR_OUT_OF_MEMORY;
PR_FREEIF(mBuffer);
mBuffer = newBuffer;
mBufferLen = newBufferLen;
}
// If not cached then call the API.
PRUint32 keyLength = (1 + stringInLen) * kCollationValueSizeFactor * sizeof(UCCollationValue);
ItemCount actual;
err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(),
(UniCharCount) stringInLen,
(ItemCount) (keyLength / sizeof(UCCollationValue)),
&actual, (UCCollationValue *)key);
OSStatus err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(),
(UniCharCount) stringInLen,
(ItemCount) (mBufferLen / sizeof(UCCollationValue)),
&actual, (UCCollationValue *)key);
NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);
*outLen = actual * sizeof(UCCollationValue);
PRUint32 keyLength = actual * sizeof(UCCollationValue);
void *newKey = PR_Malloc(keyLength);
if (!newKey)
return NS_ERROR_OUT_OF_MEMORY;
memcpy(newKey, mBuffer, keyLength);
*key = (PRUint8 *)newKey;
*outLen = keyLength;
return NS_OK;
}
NS_IMETHODIMP nsCollationMacUC::CompareString(
const nsCollationStrength strength,
@ -262,19 +216,15 @@ NS_IMETHODIMP nsCollationMacUC::CompareString(
nsresult res = EnsureCollator(strength);
NS_ENSURE_SUCCESS(res, res);
SInt32 order;
*result = 0;
OSStatus err;
err = ::UCCompareText(mCollator,
(const UniChar *) PromiseFlatString(string1).get(), (UniCharCount) string1.Length(),
(const UniChar *) PromiseFlatString(string2).get(), (UniCharCount) string2.Length(),
NULL, &order);
NULL, &result);
NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);
// order could be -2, -1, 0, 1, or 2,
// *result can only be -1, 0 or 1
*result = (order == 0) ? 0 : ((order > 0) ? 1 : -1);
return NS_OK;
}
@ -290,17 +240,12 @@ NS_IMETHODIMP nsCollationMacUC::CompareRawSortKey(
NS_ENSURE_ARG_POINTER(result);
*result = 0;
SInt32 order;
OSStatus err;
err = ::UCCompareCollationKeys((const UCCollationValue*) key1, (ItemCount) len1,
(const UCCollationValue*) key2, (ItemCount) len2,
NULL, &order);
NULL, &result);
NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE);
// order could be -2, -1, 0, 1, or 2,
// *result can only be -1, 0 or 1
*result = (order == 0) ? 0 : ((order > 0) ? 1 : -1);
return NS_OK;
}

View File

@ -65,13 +65,9 @@ public:
const nsAString& string2,
PRInt32* result) ;
NS_IMETHOD GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn,
PRUint32* outLen);
NS_IMETHOD CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn,
PRUint8* key, PRUint32* outLen);
NS_IMETHOD AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn,
PRUint8** key, PRUint32* outLen);
NS_IMETHOD CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2,
@ -92,10 +88,8 @@ private:
LocaleRef mLocale;
nsCollationStrength mLastStrength;
CollatorRef mCollator;
UCCollationValue mCachedKey[kCacheSize * kCollationValueSizeFactor];
PRUint32 mCachedKeyLen; // byte length of key
UniChar mCachedString[kCacheSize];
PRUint32 mCachedStringLen; // character length of the string
void *mBuffer; // temporary buffer to generate collation keys
PRUint32 mBufferLen; // byte length of buffer
};
#endif /* nsCollationMacUC_h__ */

View File

@ -85,106 +85,6 @@ nsCollation::~nsCollation()
MOZ_COUNT_DTOR(nsCollation);
}
nsresult nsCollation::CompareString(nsICollation *inst, const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{
PRUint32 aLength1, aLength2;
PRUint8 *aKey1, *aKey2;
nsresult res;
res = inst->GetSortKeyLen(strength, string1, &aLength1);
if (NS_FAILED(res))
return res;
res = inst->GetSortKeyLen(strength, string2, &aLength2);
if (NS_FAILED(res)) {
return res;
}
// if input string is small then use local buffer for keys
if (aLength1 <= 128 && aLength2 <= 128) {
PRUint8 aKeyBuf1[128], aKeyBuf2[128];
res = inst->CreateRawSortKey(strength, string1, aKeyBuf1, &aLength1);
if (NS_SUCCEEDED(res)) {
res = inst->CreateRawSortKey(strength, string2, aKeyBuf2, &aLength2);
if (NS_SUCCEEDED(res)) {
*result = CompareRawSortKey(aKeyBuf1, aLength1, aKeyBuf2, aLength2);
}
}
return res;
}
// Create a key for string1
aKey1 = new PRUint8[aLength1];
if (NULL == aKey1)
return NS_ERROR_OUT_OF_MEMORY;
res = inst->CreateRawSortKey(strength, string1, aKey1, &aLength1);
if (NS_FAILED(res)) {
delete [] aKey1;
return res;
}
// Create a key for string2
aKey2 = new PRUint8[aLength2];
if (NULL == aKey2) {
delete [] aKey1;
return NS_ERROR_OUT_OF_MEMORY;
}
res = inst->CreateRawSortKey(strength, string2, aKey2, &aLength2);
if (NS_FAILED(res)) {
delete [] aKey1;
delete [] aKey2;
return res;
}
// Compare keys
*result = CompareRawSortKey(aKey1, aLength1, aKey2, aLength2);
// delete keys
delete [] aKey1;
delete [] aKey2;
return res;
}
PRInt32 nsCollation::CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2)
{
PRUint32 len = (len1 < len2) ? len1 : len2;
PRInt32 result;
result = (PRUint32) memcmp(key1, key2, len);
if (result == 0 && len1 != len2) {
result = (len1 < len2) ? -1 : 1;
}
return result;
}
nsresult nsCollation::CreateASCIISortKey(nsICollation *inst, const nsCollationStrength strength,
const PRUnichar* stringIn, char* key, PRUint32 *outLen)
{
NS_ENSURE_ARG_POINTER(stringIn);
NS_ENSURE_ARG_POINTER(key);
// ASCII key is twice as large as the original raw key.
// In order to avoid overrun the raw data while encoding,
// place the raw key at higher address in the buffer
// then place encoded data from begining of the buffer.
NS_ASSERTION(!(*outLen % 2), "the key length should be even");
PRUint8 *rawKey = (PRUint8 *)key + (*outLen / 2);
nsresult rv = inst->CreateRawSortKey(strength, nsDependentString(stringIn), rawKey, outLen);
NS_ENSURE_SUCCESS(rv, rv);
const char* hexChars = "0123456789ABCDEF";
for (PRUint32 i = 0; i < *outLen; i++) {
*key++ = hexChars[*rawKey >> 4];
*key++ = hexChars[*rawKey & 0x0f];
rawKey++;
}
return rv;
}
nsresult nsCollation::NormalizeString(const nsAString& stringIn, nsAString& stringOut)
{
if (!mCaseConversion) {

View File

@ -51,19 +51,6 @@ public:
~nsCollation();
nsresult CreateASCIISortKey(nsICollation *inst, const nsCollationStrength strength,
const PRUnichar* stringIn, char* key, PRUint32 *outLen);
// compare two strings
// result is same as strcmp
nsresult CompareString(nsICollation *inst, const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result);
// compare two sort keys
// length is a byte length, result is same as strcmp
PRInt32 CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2);
// normalize string before collation key generation
nsresult NormalizeString(const nsAString& stringIn, nsAString& stringOut);

View File

@ -73,47 +73,47 @@ nsresult nsCollationOS2::Initialize(nsILocale *locale)
return NS_OK;
}
nsresult nsCollationOS2::GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen)
{
// this may not necessary because collation key length
// probably will not change by this normalization
nsresult res = NS_OK;
nsAutoString stringNormalized;
nsresult nsCollationOS2::CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{
nsAutoString stringNormalized1, stringNormalized2;
if (strength != kCollationCaseSensitive) {
res = mCollation->NormalizeString(stringIn, stringNormalized);
nsresult res;
res = mCollation->NormalizeString(string1, stringNormalized1);
if (NS_FAILED(res)) {
return res;
}
res = mCollation->NormalizeString(string2, stringNormalized2);
if (NS_FAILED(res)) {
return res;
}
} else {
stringNormalized = stringIn;
stringNormalized1 = string1;
stringNormalized2 = string2;
}
LocaleObject locObj = NULL;
int ret = UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"", &locObj);
if (ret != ULS_SUCCESS)
UniCreateLocaleObject(UNI_UCS_STRING_POINTER, (UniChar *)L"en_US", &locObj);
int uLen = UniStrxfrm(locObj, NULL, NS_REINTERPRET_CAST(const UniChar *, stringNormalized.get()), 0);
if ( uLen > 0 ) {
uLen += 5; // Allow for the "extra" chars UniStrxfrm() will out put
// (overrunning the buffer if you let it...)
uLen *= 2; // And then adjust uLen to be the size in bytes,
// not unicode character count
} else {
uLen = 0;
}
*outLen = uLen;
UniFreeLocaleObject(locObj);
return res;
*result = UniStrcoll(locObj, (UniChar *)stringNormalized1.get(), (UniChar *)stringNormalized2.get());
return NS_OK;
}
nsresult nsCollationOS2::CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen)
nsresult nsCollationOS2::AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32* outLen)
{
nsresult res = NS_OK;
nsAutoString stringNormalized;
if (strength != kCollationCaseSensitive) {
res = mCollation->NormalizeString(stringIn, stringNormalized);
if (NS_FAILED(res))
return res;
} else {
stringNormalized = stringIn;
}
@ -148,29 +148,13 @@ nsresult nsCollationOS2::CreateRawSortKey(const nsCollationStrength strength,
// See how big the result really is
uLen = UniStrlen(pLocalBuffer);
// make sure it will fit in the output buffer...
if (uLen < length)
if (uLen < iBufferLength) {
// Success!
// Give 'em the real size in bytes...
*outLen = uLen * 2;
// And copy the string, byte reversed, so that it can be
// memcmp'ed
char *srcLow, *srcHi, *dst;
srcLow = (char*) pLocalBuffer;
srcHi = srcLow+1;
dst = (char*) key;
while( uLen ) {
*dst = *srcHi;
dst++;
*dst = *srcLow;
dst++;
srcLow += 2;
srcHi += 2;
uLen--;
}
*dst = 0;
dst++;
*dst = 0;
*key = (PRUint8 *)nsCRT::strdup((PRUnichar*) pLocalBuffer);
*outLen = uLen * 2 + 2;
res = NS_OK;
}
}
}
UniFreeLocaleObject(locObj);

View File

@ -39,25 +39,19 @@ public:
// compare two strings
// result is same as strcmp
NS_IMETHOD CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{return mCollation->CompareString(this, strength, string1, string2, result);}
const nsAString& string1, const nsAString& string2, PRInt32* result);
// allocate sort key from input string
// returns newly allocated key and its byte length
NS_IMETHOD AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32 *outLen);
// get a length (of character) of a sort key to be generated by an input string
// length is a byte length
NS_IMETHOD GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen);
// create sort key from input string
// length is character length not byte length, caller to allocate a memory for a key
NS_IMETHOD CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen);
// compare two sort keys
// length is character length not byte length, result is same as strcmp
NS_IMETHOD CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2,
PRInt32* result)
{*result = mCollation->CompareRawSortKey(key1, len1, key2, len2);return NS_OK;}
{*result = UniStrcmp((UniChar *)key1, (UniChar *)key2); return NS_OK;}
// init this interface to a specified locale (should only be called by collation factory)
//

View File

@ -168,53 +168,65 @@ nsresult nsCollationUnix::Initialize(nsILocale* locale)
return NS_OK;
};
nsresult nsCollationUnix::GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn,
PRUint32* outLen)
nsresult nsCollationUnix::CompareString(const nsCollationStrength strength,
const nsAString& string1,
const nsAString& string2,
PRInt32* result)
{
nsresult res = NS_OK;
// this may not necessary because collation key length
// probably will not change by this normalization
nsAutoString stringNormalized;
nsAutoString stringNormalized1, stringNormalized2;
if (strength != kCollationCaseSensitive) {
res = mCollation->NormalizeString(stringIn, stringNormalized);
res = mCollation->NormalizeString(string1, stringNormalized1);
if (NS_FAILED(res)) {
return res;
}
res = mCollation->NormalizeString(string2, stringNormalized2);
if (NS_FAILED(res)) {
return res;
}
} else {
stringNormalized = stringIn;
stringNormalized1 = string1;
stringNormalized2 = string2;
}
// convert unicode to charset
char *str;
char *str1, *str2;
res = mCollation->UnicodeToChar(stringNormalized, &str);
if (NS_SUCCEEDED(res) && str != NULL) {
if (mUseCodePointOrder) {
*outLen = strlen(str);
res = mCollation->UnicodeToChar(stringNormalized1, &str1);
if (NS_SUCCEEDED(res) && str1 != NULL) {
res = mCollation->UnicodeToChar(stringNormalized2, &str2);
if (NS_SUCCEEDED(res) && str2 != NULL) {
if (mUseCodePointOrder) {
*result = strcmp(str1, str2);
}
else {
DoSetLocale();
*result = strcoll(str1, str2);
DoRestoreLocale();
}
PR_Free(str2);
}
else {
DoSetLocale();
// call strxfrm to calculate a key length
int len = strxfrm(NULL, str, 0) + 1;
DoRestoreLocale();
*outLen = (len == -1) ? 0 : (PRUint32)len;
}
PR_Free(str);
PR_Free(str1);
}
return res;
}
nsresult nsCollationUnix::CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn,
PRUint8* key, PRUint32* outLen)
nsresult nsCollationUnix::AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn,
PRUint8** key, PRUint32* outLen)
{
nsresult res = NS_OK;
nsAutoString stringNormalized;
if (strength != kCollationCaseSensitive) {
res = mCollation->NormalizeString(stringIn, stringNormalized);
if (NS_FAILED(res))
return res;
} else {
stringNormalized = stringIn;
}
@ -224,21 +236,25 @@ nsresult nsCollationUnix::CreateRawSortKey(const nsCollationStrength strength,
res = mCollation->UnicodeToChar(stringNormalized, &str);
if (NS_SUCCEEDED(res) && str != NULL) {
if (mUseCodePointOrder) {
*outLen = strlen(str);
memcpy(key, str, *outLen);
}
else {
*key = (PRUint8 *)str;
*outLen = strlen(str) + 1;
} else {
DoSetLocale();
// call strxfrm to generate a key
int len = strxfrm((char *) key, str, *outLen);
DoRestoreLocale();
if (PRUint32(len) >= *outLen) {
res = NS_ERROR_FAILURE;
len = -1;
size_t len = strxfrm(nsnull, str, 0) + 1;
void *buffer = PR_Malloc(len);
if (!buffer) {
res = NS_ERROR_OUT_OF_MEMORY;
} else if (strxfrm((char *)buffer, str, len) >= len) {
PR_Free(buffer);
res = NS_ERROR_FAILURE;
} else {
*key = (PRUint8 *)buffer;
*outLen = len;
}
*outLen = (len == -1) ? 0 : (PRUint32)len;
DoRestoreLocale();
PR_Free(str);
}
PR_Free(str);
}
return res;

View File

@ -50,25 +50,19 @@ public:
// compare two strings
// result is same as strcmp
NS_IMETHOD CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{return mCollation->CompareString(this, strength, string1, string2, result);}
const nsAString& string1, const nsAString& string2, PRInt32* result);
// get a length (of character) of a sort key to be generated by an input string
// length is character length not byte length
NS_IMETHOD GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen);
// create sort key from input string
// length is character length not byte length, caller to allocate a memory for a key
NS_IMETHOD CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen);
// allocate sort key from input string
// returns newly allocated key and its byte length
NS_IMETHOD AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32 *outLen);
// compare two sort keys
// length is character length not byte length, result is same as strcmp
NS_IMETHOD CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2,
PRInt32* result)
{*result = mCollation->CompareRawSortKey(key1, len1, key2, len2);return NS_OK;}
{*result = strcmp((const char *)key1, (const char *)key2); return NS_OK;}
// init this interface to a specified locale (should only be called by collation factory)
//

View File

@ -49,7 +49,7 @@
#include "prmem.h"
#include "plstr.h"
#include <windows.h>
#undef CompareString
NS_IMPL_ISUPPORTS1(nsCollationWin, nsICollation);
@ -139,38 +139,54 @@ nsresult nsCollationWin::Initialize(nsILocale* locale)
return NS_OK;
};
nsresult nsCollationWin::GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen)
nsresult nsCollationWin::CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{
nsresult res = NS_OK;
int retval;
nsresult res;
DWORD dwMapFlags = LCMAP_SORTKEY;
if (strength == kCollationCaseInSensitive)
dwMapFlags |= NORM_IGNORECASE;
if (mW_API) {
*outLen = LCMapStringW(mLCID, dwMapFlags,
(LPCWSTR) PromiseFlatString(stringIn).get(),
(int) stringIn.Length(), NULL, 0);
}
else {
char *Cstr = nsnull;
res = mCollation->UnicodeToChar(stringIn, &Cstr);
if (NS_SUCCEEDED(res) && Cstr != nsnull) {
*outLen = LCMapStringA(mLCID, dwMapFlags, Cstr, PL_strlen(Cstr), NULL, 0);
PR_Free(Cstr);
retval = CompareStringW(mLCID, dwMapFlags,
(LPCWSTR) PromiseFlatString(string1).get(), -1,
(LPCWSTR) PromiseFlatString(string2).get(), -1);
if (retval) {
res = NS_OK;
*result = retval - 2;
} else {
res = NS_ERROR_FAILURE;
}
} else {
char *Cstr1 = nsnull, *Cstr2 = nsnull;
res = mCollation->UnicodeToChar(string1, &Cstr1);
if (NS_SUCCEEDED(res) && Cstr1 != nsnull) {
res = mCollation->UnicodeToChar(string2, &Cstr2);
if (NS_SUCCEEDED(res) && Cstr2 != nsnull) {
retval = CompareStringA(mLCID, dwMapFlags, Cstr1, -1, Cstr2, -1);
if (retval)
*result = retval - 2;
else
res = NS_ERROR_FAILURE;
PR_Free(Cstr2);
}
PR_Free(Cstr1);
}
}
return res;
}
nsresult nsCollationWin::CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen)
nsresult nsCollationWin::AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32* outLen)
{
int byteLen;
void *buffer;
nsresult res = NS_OK;
DWORD dwMapFlags = LCMAP_SORTKEY;
@ -179,17 +195,33 @@ nsresult nsCollationWin::CreateRawSortKey(const nsCollationStrength strength,
if (mW_API) {
byteLen = LCMapStringW(mLCID, dwMapFlags,
(LPCWSTR) PromiseFlatString(stringIn).get(), (int) stringIn.Length(), (LPWSTR) key, *outLen);
(LPCWSTR) PromiseFlatString(stringIn).get(),
-1, NULL, 0);
buffer = PR_Malloc(byteLen);
if (!buffer) {
res = NS_ERROR_OUT_OF_MEMORY;
} else {
*key = (PRUint8 *)buffer;
*outLen = LCMapStringW(mLCID, dwMapFlags,
(LPCWSTR) PromiseFlatString(stringIn).get(),
-1, (LPWSTR) buffer, byteLen);
}
}
else {
char *Cstr = nsnull;
res = mCollation->UnicodeToChar(stringIn, &Cstr);
if (NS_SUCCEEDED(res) && Cstr != nsnull) {
byteLen = LCMapStringA(mLCID, dwMapFlags, Cstr, PL_strlen(Cstr), (char *) key, (int) *outLen);
byteLen = LCMapStringA(mLCID, dwMapFlags, Cstr, -1, NULL, 0);
buffer = PR_Malloc(byteLen);
if (!buffer) {
res = NS_ERROR_OUT_OF_MEMORY;
} else {
*key = (PRUint8 *)buffer;
*outLen = LCMapStringA(mLCID, dwMapFlags, Cstr, -1, (char *) buffer, byteLen);
}
PR_Free(Cstr);
}
}
*outLen = (PRUint32) byteLen;
return res;
}

View File

@ -42,25 +42,19 @@ public:
// compare two strings
// result is same as strcmp
NS_IMETHOD CompareString(const nsCollationStrength strength,
const nsAString& string1, const nsAString& string2, PRInt32* result)
{return mCollation->CompareString(this, strength, string1, string2, result);}
const nsAString& string1, const nsAString& string2, PRInt32* result);
// get a length (of character) of a sort key to be generated by an input string
// length is a byte length
NS_IMETHOD GetSortKeyLen(const nsCollationStrength strength,
const nsAString& stringIn, PRUint32* outLen);
// create sort key from input string
// length is a byte length, caller should allocate a memory for a key
NS_IMETHOD CreateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8* key, PRUint32* outLen);
// allocate sort key from input string
// returns newly allocated key and its byte length
NS_IMETHOD AllocateRawSortKey(const nsCollationStrength strength,
const nsAString& stringIn, PRUint8** key, PRUint32 *outLen);
// compare two sort keys
// length is a byte length, result is same as strcmp
NS_IMETHOD CompareRawSortKey(const PRUint8* key1, const PRUint32 len1,
const PRUint8* key2, const PRUint32 len2,
PRInt32* result)
{*result = mCollation->CompareRawSortKey(key1, len1, key2, len2);return NS_OK;}
{*result = strcmp((const char *)key1, (const char *)key2); return NS_OK;}
// init this interface to a specified locale (should only be called by collation factory)
//

View File

@ -127,10 +127,8 @@ nsresult nsAbView::RemoveCardAt(PRInt32 row)
AbCard *abcard = (AbCard*) (mCards.ElementAt(row));
NS_IF_RELEASE(abcard->card);
mCards.RemoveElementAt(row);
if (abcard->primaryCollationKey)
nsMemory::Free(abcard->primaryCollationKey);
if (abcard->secondaryCollationKey)
nsMemory::Free(abcard->secondaryCollationKey);
PR_FREEIF(abcard->primaryCollationKey);
PR_FREEIF(abcard->secondaryCollationKey);
PR_FREEIF(abcard);
if (mAbViewListener && !mSuppressCountChange) {
@ -815,14 +813,7 @@ nsresult nsAbView::CreateCollationKey(const PRUnichar *aSource, PRUint8 **aKey,
// XXX can we avoid this copy?
nsAutoString sourceString(aSource);
rv = mCollationKeyGenerator->GetSortKeyLen(kCollationCaseInSensitive, sourceString, aKeyLen);
NS_ENSURE_SUCCESS(rv, rv);
*aKey = (PRUint8*) nsMemory::Alloc(*aKeyLen);
if (!aKey)
return NS_ERROR_OUT_OF_MEMORY;
rv = mCollationKeyGenerator->CreateRawSortKey(kCollationCaseInSensitive, sourceString, *aKey, aKeyLen);
rv = mCollationKeyGenerator->AllocateRawSortKey(kCollationCaseInSensitive, sourceString, aKey, aKeyLen);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to generate a raw sort key, see bug #121868");
return NS_OK;
}

View File

@ -792,17 +792,7 @@ nsresult nsAbDirectoryDataSource::CreateCollationKey(const nsString &aSource, P
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mCollationKeyGenerator->GetSortKeyLen(kCollationCaseInSensitive, aSource, aLength);
NS_ENSURE_SUCCESS(rv, rv);
if (*aLength == 0)
return NS_ERROR_FAILURE;
*aKey = (PRUint8 *) PR_Malloc(*aLength);
if (!aKey)
return NS_ERROR_OUT_OF_MEMORY;
return mCollationKeyGenerator->CreateRawSortKey(kCollationCaseInSensitive, aSource, *aKey, aLength);
return mCollationKeyGenerator->AllocateRawSortKey(kCollationCaseInSensitive, aSource, aKey, aLength);
}
nsresult nsAbDirectoryDataSource::DoDeleteFromDirectory(nsISupportsArray *parentDirs, nsISupportsArray *delDirs)

View File

@ -2777,17 +2777,7 @@ nsMsgFolder::CreateCollationKey(const nsString &aSource, PRUint8 **aKey, PRUint
if (!kCollationKeyGenerator)
return NS_ERROR_NULL_POINTER;
rv = kCollationKeyGenerator->GetSortKeyLen(kCollationCaseInSensitive, aSource, aLength);
NS_ENSURE_SUCCESS(rv, rv);
if (*aLength == 0)
return NS_ERROR_FAILURE;
*aKey = (PRUint8 *) PR_Malloc(*aLength);
if (!aKey)
return NS_ERROR_OUT_OF_MEMORY;
return kCollationKeyGenerator->CreateRawSortKey(kCollationCaseInSensitive, aSource, *aKey, aLength);
return kCollationKeyGenerator->AllocateRawSortKey(kCollationCaseInSensitive, aSource, aKey, aLength);
}
NS_IMETHODIMP nsMsgFolder::CompareSortKeys(nsIMsgFolder *aFolder, PRInt32 *sortOrder)

View File

@ -2874,8 +2874,7 @@ nsIMimeConverter *nsMsgDatabase::GetMimeConverter()
if (!m_mimeConverter)
{
// apply mime decode
nsComponentManager::CreateInstance(NS_MIME_CONVERTER_CONTRACTID, nsnull,
NS_GET_IID(nsIMimeConverter), getter_AddRefs(m_mimeConverter));
m_mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID);
}
return m_mimeConverter;
}
@ -3015,13 +3014,7 @@ nsMsgDatabase::CreateCollationKey(const PRUnichar *sourceString, PRUint8 **resul
if (!m_collationKeyGenerator) return NS_ERROR_FAILURE;
nsAutoString sourceStr(sourceString);
err = m_collationKeyGenerator->GetSortKeyLen(kCollationCaseInSensitive, sourceStr, len);
NS_ENSURE_SUCCESS(err,err);
*result = (PRUint8 *) PR_Malloc(*len);
if (!result) return NS_ERROR_OUT_OF_MEMORY;
err = m_collationKeyGenerator->CreateRawSortKey(kCollationCaseInSensitive, sourceStr, *result, len);
err = m_collationKeyGenerator->AllocateRawSortKey(kCollationCaseInSensitive, sourceStr, result, len);
NS_ENSURE_SUCCESS(err,err);
return err;
}

View File

@ -64,6 +64,7 @@
#include "nsIRequestObserver.h"
#include "nsITimelineService.h"
#include "nsCRT.h"
#include "prmem.h"
//----------------------------------------------------------------------------
// Global functions and data [declaration]
@ -1771,18 +1772,8 @@ nsresult nsCharsetMenu::ReorderMenuItemArray(nsVoidArray * aArray)
for (i = 0; i < count && NS_SUCCEEDED(res); i++) {
array[i].item = (nsMenuEntry *)aArray->ElementAt(i);
res = collation->GetSortKeyLen(kCollationCaseInSensitive,
(array[i].item)->mTitle, &array[i].len);
if (NS_SUCCEEDED(res)) {
array[i].key = new PRUint8 [array[i].len];
if (!(array[i].key)) {
res = NS_ERROR_OUT_OF_MEMORY;
goto done;
}
res = collation->CreateRawSortKey(kCollationCaseInSensitive,
(array[i].item)->mTitle, array[i].key, &array[i].len);
}
res = collation->AllocateRawSortKey(kCollationCaseInSensitive,
(array[i].item)->mTitle, &array[i].key, &array[i].len);
}
// reorder the array
@ -1798,8 +1789,7 @@ nsresult nsCharsetMenu::ReorderMenuItemArray(nsVoidArray * aArray)
done:
for (i = 0; i < count; i++) {
if (array[i].key)
delete [] array[i].key;
PR_FREEIF(array[i].key);
}
delete [] array;
return res;