by Naoki Hotta <naoki@netscape.com>
Last Modified: Feb. 12, '99
Description
The collation functions are intended to provide a set of simple, cross-platform functions that Mozilla and Netscape developers can use to perform locale sensitive collations.Two types of collation functions are necessary, a comparison function which directly compares two strings and returns a result and a sort key generation function.
The caller first need to instanciate nsICollationFactory with a locale
(nsILocale). The factory will create a
collation interface (nsCollation) for a specified locale.
Once the collation interface is available, locale sensitive string
comparison and sort key generation are possible.
Use CompareString in order to compare two strings. Sort key is useful
for performance critical operation which requires comparison of a same
string many times (e.g. sorting). In order to create a sort key, the caller
need to allocate a memory which length is taken by GetSortKeyLen then call
CreateSortKey to generate a sort key. Call CompareSortKey to compare two
sort keys. Note that only the keys generated by the same instance can be
compared.
Input strings for both generic comparison and a sort key creation should
be Unicode (UCS2). Sort keys are generated as an opaque byte buffer and
the length indicates a number of bytes. Collation strength should be specified
for both string comparison and sort key creation. Currently, case sensitiveness
can be specified by the selector. Comparison result to be given as an interger
(-1, 0, 1) which is identical to strcmp.
API
typedef enum {kCollationStrengthDefault = 0, // use the primary comparison for the given local - no flags)
kCollationCaseInsensitiveAscii = 1, // do not consider case differences when doing the comparison i.e. A=a)
kCollationAccentInsenstive = 2, // do not consider accent differences when doing the comparison a=á)
kCollationCaseSensitive = kCollationStrengthDefault,
kCollationCaseInSensitive = (kCollationCaseInsensitiveAscii | kCollationAccentInsenstive)
} nsCollationStrength;
// Create a collation interface for an input locale.
//
class nsICollationFactory : public nsISupports {
public:
NS_IMETHOD CreateCollation(nsILocale* locale, nsICollation**
instancePtr) = 0;
};
// Locale sensitive collation interface
//
class nsICollation : public nsISupports {
public:
// compare two strings
// result is same as strcmp
NS_IMETHOD CompareString(const nsCollationStrength strength,
const nsString& string1, const nsString& 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 nsString& 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 CreateSortKey(const nsCollationStrength strength,
const nsString& stringIn, PRUint8* key, PRUint32 *outLen) = 0;
// compare two sort keys
// length is a byte length, result is same as strcmp
NS_IMETHOD CompareSortKey(const PRUint8* key1, const PRUint32
len1,
const PRUint8* key2, const PRUint32 len2,
PRInt32* result) = 0;
// init this interface to a specified locale (should only
be called by collation factory)
//
NS_IMETHOD Initialize(nsILocale* locale) = 0;
};
Example
Following example compares two string in two ways (with and without sort key). Details omitted.// create a nsILocale by nsILocaleFactory (see the spec or mozilla/intl/locale/test/nsLocaleTest.cpp)
// create a factory
res = nsRepository::CreateInstance(kCollationFactoryCID,
NULL, kICollationFactoryIID, (void**) &f);
// get a collation interface instance
res = f->CreateCollation(locale, &inst);
// compare string1 and string2
res = inst->CompareString(kCollationCaseSensitive, string1,
string2, &result);
// get a length of a sort key for string1
res = inst->GetSortKeyLen(kCollationCaseInSensitive, string1,
&keyLength1);
// allocate a buffer for a sort key
aKey1 = (PRUint8 *) new PRUint8[keyLength1];
// create a sort key for string1
res = inst->CreateSortKey(kCollationCaseSensitive, string1,
aKey1, &keyLength1);
// create a sort key for string2
...
// compare sort keys
res = t->CompareSortKey(aKey1, keyLength1, aKey2, keyLength2,
&result);
Undecided (or unimplemented) issues
- Input string is specifed as nsStrings, this may change (to whatever appropriate for XPIDL).