You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.



Collation
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).