/*
*******************************************************************************
* Copyright (C) 1996-1999, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
*/
//=============================================================================
//
// File coll.h
//
//
//
// Created by: Helena Shih
//
// Modification History:
//
// Date Name Description
// 02/5/97 aliu Modified createDefault to load collation data from
// binary files when possible. Added related methods
// createCollationFromFile, chopLocale, createPathName.
// 02/11/97 aliu Added members addToCache, findInCache, and fgCache.
// 02/12/97 aliu Modified to create objects from RuleBasedCollator cache.
// Moved cache out of Collation class.
// 02/13/97 aliu Moved several methods out of this class and into
// RuleBasedCollator, with modifications. Modified
// createDefault() to call new RuleBasedCollator(Locale&)
// constructor. General clean up and documentation.
// 02/20/97 helena Added clone, operator==, operator!=, operator=, copy
// constructor and getDynamicClassID.
// 03/25/97 helena Updated with platform independent data types.
// 05/06/97 helena Added memory allocation error detection.
// 6/20/97 helena Java class name change.
// 09/03/97 helena Added createCollationKeyValues().
// 02/10/98 damiba Added compare() with length as parameter.
// 04/23/99 stephen Removed EDecompositionMode, merged with
// Normalizer::EMode.
// 11/02/99 helena Collator performance enhancements. Eliminates the
// UnicodeString construction and special case for NO_OP.
// 11/23/99 srl More performance enhancements. Inlining of
// critical accessors.
// 05/15/00 helena Added version information API.
//=============================================================================
#ifndef COLL_H
#define COLL_H
#include "unicode/locid.h"
#include "unicode/utypes.h"
#include "unicode/unistr.h"
#include "unicode/normlzr.h"
#include "unicode/chariter.h"
class CollationKey;
enum UColAttribute {
UCOL_FRENCH_COLLATION, /* attribute for direction of secondary weights*/
UCOL_ALTERNATE_HANDLING, /* attribute for handling variable elements*/
UCOL_CASE_FIRST, /* who goes first, lower case or uppercase */
UCOL_CASE_LEVEL, /* do we have an extra case level */
UCOL_NORMALIZATION_MODE, /* attribute for normalization */
UCOL_STRENGTH, /* attribute for strength */
UCOL_ATTRIBUTE_COUNT
};
enum UColAttributeValue {
/* accepted by most attributes */
UCOL_ATTR_DEFAULT,
/* for UCOL_FRENCH_COLLATION & UCOL_CASE_LEVEL*/
UCOL_ATTR_ON,
UCOL_ATTR_OFF,
/* for UCOL_ALTERNATE_HANDLING */
UCOL_ATTR_SHIFTED,
UCOL_ATTR_NON_IGNORABLE,
/* for UCOL_CASE_FIRST */
UCOL_ATTR_LOWER_FIRST,
UCOL_ATTR_UPPER_FIRST,
/* for UCOL_NORMALIZATION_MODE */
/** No decomposition/composition */
UCOL_ATTR_NO_NORMALIZATION,
/** Canonical decomposition */
UCOL_ATTR_DECOMP_CAN,
/** Compatibility decomposition */
UCOL_ATTR_DECOMP_COMPAT,
/** Default normalization */
UCOL_ATTR_DEFAULT_NORMALIZATION = UCOL_ATTR_DECOMP_COMPAT,
/** Canonical decomposition followed by canonical composition */
UCOL_ATTR_DECOMP_CAN_COMP_COMPAT,
/** Compatibility decomposition followed by canonical composition */
UCOL_ATTR_DECOMP_COMPAT_COMP_CAN,
/* for UCOL_STRENGTH */
/** Primary collation strength */
UCOL_ATTR_PRIMARY,
/** Secondary collation strength */
UCOL_ATTR_SECONDARY,
/** Tertiary collation strength */
UCOL_ATTR_TERTIARY,
UCOL_ATTR_DEFAULT_STRENGTH = UCOL_ATTR_TERTIARY,
/** Quaternary collation strength */
UCOL_ATTR_QUATERNARY,
/** Identical collation strength */
UCOL_ATTR_IDENTICAL,
/** Default collation strength */
UCOL_ATTRIBUTE_VALUE_COUNT
};
/**
* The Collator
class performs locale-sensitive
* String
comparison. You use this class to build
* searching and sorting routines for natural language text.
*
*
* Collator
is an abstract base class. Subclasses
* implement specific collation strategies. One subclass,
* RuleBasedCollator
, is currently provided
* and is applicable to a wide set of languages. Other
* subclasses may be created to handle more specialized needs.
*
*
* Like other locale-sensitive classes, you can use the static
* factory method, getInstance
, to obtain the appropriate
* Collator
object for a given locale. You will only need
* to look at the subclasses of Collator
if you need
* to understand the details of a particular collation strategy or
* if you need to modify that strategy.
*
*
* The following example shows how to compare two strings using
* the Collator
for the default locale.
*
** ** // Compare two strings in the default locale * UErrorCode success = U_ZERO_ERROR; * Collator* myCollator = Collator::createInstance(success); * if( myCollator->compare("abc", "ABC") < 0 ) { * cout << "abc is less than ABC" << endl; * }else{ * cout << "abc is greater than or equal to ABC" << endl; * } **
* You can set a Collator
's strength property
* to determine the level of difference considered significant in
* comparisons. Four strengths are provided: PRIMARY
,
* SECONDARY
, TERTIARY
, and IDENTICAL
.
* The exact assignment of strengths to language features is
* locale dependant. For example, in Czech, "e" and "f" are considered
* primary differences, while "e" and "\u00EA" are secondary differences,
* "e" and "E" are tertiary differences and "e" and "e" are identical.
* The following shows how both case and accents could be ignored for
* US English.
*
*** //Get the Collator for US English and set its strength to PRIMARY * UErrorCode success = U_ZERO_ERROR; * Collator* usCollator = Collator::createInstance(Locale::US, success); * usCollator->setStrength(Collator::PRIMARY); * if( usCollator->compare("abc", "ABC") == 0 ) { * cout << "'abc' and 'ABC' strings are equivalent with strength PRIMARY" << endl; * } **
* For comparing String
s exactly once, the compare
* method provides the best performance. When sorting a list of
* String
s however, it is generally necessary to compare each
* String
multiple times. In this case, CollationKey
s
* provide better performance. The CollationKey
class converts
* a String
to a series of bits that can be compared bitwise
* against other CollationKey
s. A CollationKey
is
* created by a Collator
object for a given String
.
*
* Note: Collator
s with different Locale,
* CollationStrength and DecompositionMode settings will return different
* sort orders for the same set of strings. Locales have specific
* collation rules, and the way in which secondary and tertiary differences
* are taken into account, for example, will result in a different sorting order
* for same strings.
*
* * @see RuleBasedCollator * @see CollationKey * @see CollationElementIterator * @see Locale * @see Normalizer * @version 1.7 1/14/97 * @author Helena Shih */ class U_I18N_API Collator { public: /** * Base letter represents a primary difference. Set comparison * level to PRIMARY to ignore secondary and tertiary differences. * Use this to set the strength of a Collator object. * Example of primary difference, "abc" < "abd" * * Diacritical differences on the same base letter represent a secondary * difference. Set comparison level to SECONDARY to ignore tertiary * differences. Use this to set the strength of a Collator object. * Example of secondary difference, "ä" >> "a". * * Uppercase and lowercase versions of the same character represents a * tertiary difference. Set comparison level to TERTIARY to include * all comparison differences. Use this to set the strength of a Collator * object. * Example of tertiary difference, "abc" <<< "ABC". * * Two characters are considered "identical" when they have the same * unicode spellings. * For example, "ä" == "ä". * * ECollationStrength is also used to determine the strength of sort keys * generated from Collator objects. */ enum ECollationStrength { PRIMARY = 0, SECONDARY = 1, TERTIARY = 2, IDENTICAL = 3 }; /** * LESS is returned if source string is compared to be less than target * string in the compare() method. * EQUAL is returned if source string is compared to be equal to target * string in the compare() method. * GREATER is returned if source string is compared to be greater than * target string in the compare() method. * @see Collator#compare */ enum EComparisonResult { LESS = -1, EQUAL = 0, GREATER = 1 }; /** * Destructor * @stable */ virtual ~Collator(); /** * Returns true if "other" is the same as "this" * @stable */ virtual UBool operator==(const Collator& other) const; /** * Returns true if "other" is not the same as "this". * @stable */ virtual UBool operator!=(const Collator& other) const; /** * Makes a shallow copy of the current object. * @stable */ virtual Collator* clone(void) const = 0; /** * Creates the collator object for the current default locale. * The default locale is determined by Locale::getDefault. * @return the collation object of the default locale.(for example, en_US) * @see Locale#getDefault * The UErrorCode& err parameter is used to return status information to the user. * To check whether the construction succeeded or not, you should check * the value of U_SUCCESS(err). If you wish more detailed information, you * can check for informational error results which still indicate success. * U_USING_FALLBACK_ERROR indicates that a fall back locale was used. For * example, 'de_CH' was requested, but nothing was found there, so 'de' was * used. U_USING_DEFAULT_ERROR indicates that the default locale data was * used; neither the requested locale nor any of its fall back locales * could be found. * The caller owns the returned object and is responsible for deleting it. * @stable */ static Collator* createInstance( UErrorCode& err); /** * Gets the table-based collation object for the desired locale. The * resource of the desired locale will be loaded by ResourceLoader. * Locale::ENGLISH is the base collation table and all other languages are * built on top of it with additional language-specific modifications. * @param desiredLocale the desired locale to create the collation table * with. * @return the created table-based collation object based on the desired * locale. * @see Locale * @see ResourceLoader * The UErrorCode& err parameter is used to return status information to the user. * To check whether the construction succeeded or not, you should check * the value of U_SUCCESS(err). If you wish more detailed information, you * can check for informational error results which still indicate success. * U_USING_FALLBACK_ERROR indicates that a fall back locale was used. For * example, 'de_CH' was requested, but nothing was found there, so 'de' was * used. U_USING_DEFAULT_ERROR indicates that the default locale data was * used; neither the requested locale nor any of its fall back locales * could be found. * The caller owns the returned object and is responsible for deleting it. * @stable */ static Collator* createInstance( const Locale& loc, UErrorCode& err); // comparison /** * The comparison function compares the character data stored in two * different strings. Returns information about whether a string * is less than, greater than or equal to another string. *
Example of use: *
* . UErrorCode status = U_ZERO_ERROR; * . Collator *myCollation = Collator::createInstance(Locale::US, status); * . if (U_FAILURE(status)) return; * . myCollation->setStrength(Collator::PRIMARY); * . // result would be Collator::EQUAL ("abc" == "ABC") * . // (no primary difference between "abc" and "ABC") * . Collator::EComparisonResult result = myCollation->compare("abc", "ABC"); * . myCollation->setStrength(Collator::TERTIARY); * . // result would be Collator::LESS (abc" <<< "ABC") * . // (with tertiary difference between "abc" and "ABC") * . Collator::EComparisonResult result = myCollation->compare("abc", "ABC"); ** @param source the source string to be compared with. * @param target the string that is to be compared with the source string. * @return Returns a byte value. GREATER if source is greater * than target; EQUAL if source is equal to target; LESS if source is less * than target * @stable **/ virtual EComparisonResult compare( const UnicodeString& source, const UnicodeString& target) const = 0; /** * Does the same thing as compare but limits the comparison to a specified length *
Example of use: *
* . UErrorCode status = U_ZERO_ERROR; * . Collator *myCollation = Collator::createInstance(Locale::US, status); * . if (U_FAILURE(status)) return; * . myCollation->setStrength(Collator::PRIMARY); * . // result would be Collator::EQUAL ("abc" == "ABC") * . // (no primary difference between "abc" and "ABC") * . Collator::EComparisonResult result = myCollation->compare("abc", "ABC",3); * . myCollation->setStrength(Collator::TERTIARY); * . // result would be Collator::LESS (abc" <<< "ABC") * . // (with tertiary difference between "abc" and "ABC") * . Collator::EComparisonResult result = myCollation->compare("abc", "ABC",3); ** @param source the source string to be compared with. * @param target the string that is to be compared with the source string. * @param length the length the comparison is limitted to * @return Returns a byte value. GREATER if source (up to the specified length) is greater * than target; EQUAL if source (up to specified length) is equal to target; LESS if source * (up to the specified length) is less than target. * @draft **/ virtual EComparisonResult compare( const UnicodeString& source, const UnicodeString& target, int32_t length) const = 0; /** * The comparison function compares the character data stored in two * different string arrays. Returns information about whether a string * array is less than, greater than or equal to another string array. *
Example of use: *
* . UErrorCode status = U_ZERO_ERROR; * . Collator *myCollation = Collator::createInstance(Locale::US, status); * . if (U_FAILURE(status)) return; * . myCollation->setStrength(Collator::PRIMARY); * . // result would be Collator::EQUAL ("abc" == "ABC") * . // (no primary difference between "abc" and "ABC") * . Collator::EComparisonResult result = myCollation->compare(L"abc", 3, L"ABC", 3); * . myCollation->setStrength(Collator::TERTIARY); * . // result would be Collator::LESS (abc" <<< "ABC") * . // (with tertiary difference between "abc" and "ABC") * . Collator::EComparisonResult result = myCollation->compare(L"abc", 3, L"ABC", 3); ** @param source the source string array to be compared with. * @param sourceLength the length of the source string array. If this value * is equal to -1, the string array is null-terminated. * @param target the string that is to be compared with the source string. * @param targetLength the length of the target string array. If this value * is equal to -1, the string array is null-terminated. * @return Returns a byte value. GREATER if source is greater * than target; EQUAL if source is equal to target; LESS if source is less * than target * @stable **/ virtual EComparisonResult compare( const UChar* source, int32_t sourceLength, const UChar* target, int32_t targetLength) const = 0; /** Transforms the string into a series of characters that can be compared * with CollationKey::compareTo. It is not possible to restore the original * string from the chars in the sort key. The generated sort key handles * only a limited number of ignorable characters. *
Use CollationKey::equals or CollationKey::compare to compare the * generated sort keys. *
Example of use: *
* . UErrorCode status = U_ZERO_ERROR; * . Collator *myCollation = Collator::createInstance(Locale::US, status); * . if (U_FAILURE(status)) return; * . myCollation->setStrength(Collator::PRIMARY); * . UErrorCode key1Status, key2Status; * . CollationKey CollationKey1 * . CollationKey1 = myCollation->getCollationKey("abc", CollationKey1, key1Status); * . CollationKey CollationKey2 * . CollationKey2 = myCollation->getCollationKey("ABC", CollationKey2, key2Status); * . if (U_FAILURE(key1Status) || U_FAILURE(key2Status)) { delete myCollation; return; } * . // Use CollationKey::compare() to compare the sort keys * . // result would be 0 (CollationKey1 == CollationKey2) * . int result = CollationKey1.compare(CollationKey2); * . myCollation->setStrength(Collator::TERTIARY); * . CollationKey1 = myCollation->getCollationKey("abc", CollationKey1, key1Status); * . CollationKey2 = myCollation->getCollationKey("ABC", CollationKey2, key2Status); * . if (U_FAILURE(key1Status) || U_FAILURE(key2Status)) { delete myCollation; return; } * . // Use CollationKey::compareTo to compare the collation keys * . // result would be -1 (CollationKey1 < CollationKey2) * . result = CollationKey1.compareTo(CollationKey2); * . delete myCollation; **
If the source string is null, a null collation key will be returned. * @param source the source string to be transformed into a sort key. * @param key the collation key to be filled in * @return the collation key of the string based on the collation rules. * @see CollationKey#compare * @draft */ virtual CollationKey& getCollationKey(const UnicodeString& source, CollationKey& key, UErrorCode& status) const = 0; /** Transforms the string into a series of characters that can be compared * with CollationKey::compareTo. It is not possible to restore the original * string from the chars in the sort key. The generated sort key handles * only a limited number of ignorable characters. *
Use CollationKey::equals or CollationKey::compare to compare the * generated sort keys. *
If the source string is null, a null collation key will be returned. * @param source the source string to be transformed into a sort key. * @param sourceLength length of the collation key * @param key the collation key to be filled in * @return the collation key of the string based on the collation rules. * @see CollationKey#compare * @draft */ virtual CollationKey& getCollationKey(const UChar *source, int32_t sourceLength, CollationKey& key, UErrorCode& status) const = 0; /** * Generates the hash code for the collation object * @stable */ virtual int32_t hashCode(void) const = 0; /** * Convenience method for comparing two strings based on * the collation rules. * @param source the source string to be compared with. * @param target the target string to be compared with. * @return true if the first string is greater than the second one, * according to the collation rules. false, otherwise. * @see Collator#compare * @stable */ UBool greater( const UnicodeString& source, const UnicodeString& target) const; /** * Convenience method for comparing two strings based on the collation * rules. * @param source the source string to be compared with. * @param target the target string to be compared with. * @return true if the first string is greater than or equal to the * second one, according to the collation rules. false, otherwise. * @see Collator#compare * @stable */ UBool greaterOrEqual( const UnicodeString& source, const UnicodeString& target) const; /** * Convenience method for comparing two strings based on the collation * rules. * @param source the source string to be compared with. * @param target the target string to be compared with. * @return true if the strings are equal according to the collation * rules. false, otherwise. * @see Collator#compare * @stable */ UBool equals( const UnicodeString& source, const UnicodeString& target) const; // getter/setter /** * Get the decomposition mode of the collator object. * @return the decomposition mode * @see Collator#setDecomposition * @stable */ Normalizer::EMode getDecomposition(void) const; /** * Set the decomposition mode of the collator object. success is equal * to U_ILLEGAL_ARGUMENT_ERROR if error occurs. * @param the new decomposition mode * @see Collator#getDecomposition * @stable */ void setDecomposition(Normalizer::EMode mode); /** * Determines the minimum strength that will be use in comparison or * transformation. *
E.g. with strength == SECONDARY, the tertiary difference is ignored *
E.g. with strength == PRIMARY, the secondary and tertiary difference * are ignored. * @return the current comparison level. * @see Collator#setStrength * @stable */ ECollationStrength getStrength(void) const; /** * Sets the minimum strength to be used in comparison or transformation. *
Example of use: *
* . UErrorCode status = U_ZERO_ERROR; * . Collator *myCollation = Collator::createInstance(Locale::US, status); * . if (U_FAILURE(status)) return; * . myCollation->setStrength(Collator::PRIMARY); * . // result will be "abc" == "ABC" * . // tertiary differences will be ignored * . Collator::ComparisonResult result = myCollation->compare("abc", "ABC"); ** @see Collator#getStrength * @param newStrength the new comparison level. * @stable */ void setStrength( ECollationStrength newStrength); /** * Get name of the object for the desired Locale, in the desired langauge * @param objectLocale must be from getAvailableLocales * @param displayLocale specifies the desired locale for output * @param name the fill-in parameter of the return value * @return display-able name of the object for the object locale in the * desired language * @stable */ static UnicodeString& getDisplayName( const Locale& objectLocale, const Locale& displayLocale, UnicodeString& name) ; /** * Get name of the object for the desired Locale, in the langauge of the * default locale. * @param objectLocale must be from getAvailableLocales * @param name the fill-in parameter of the return value * @return name of the object for the desired locale in the default * language * @stable */ static UnicodeString& getDisplayName( const Locale& objectLocale, UnicodeString& name) ; /** * Get the set of Locales for which Collations are installed * @param count the output parameter of number of elements in the locale list * @return the list of available locales which collations are installed * @stable */ static const Locale* getAvailableLocales(int32_t& count); /** * Gets the version information for a Collator. * @param info the version # information, the result will be filled in * @stable */ void getVersion(UVersionInfo info) const; /** * Returns a unique class ID POLYMORPHICALLY. Pure virtual method. * This method is to implement a simple version of RTTI, since not all * C++ compilers support genuine RTTI. Polymorphic operator==() and * clone() methods call this method. * * Concrete subclasses of Format must implement getDynamicClassID() * and also a static method and data member: * * static UClassID getStaticClassID() { return (UClassID)&fgClassID; } * static char fgClassID; * * @return The class ID for this object. All objects of a * given class have the same class ID. Objects of * other classes have different class IDs. * @stable */ virtual UClassID getDynamicClassID(void) const = 0; /* New APIs for 1.7. Not yet implemented */ /** * Universal attribute setter * @param attr attribute type * @param value attribute value * @param status to indicate whether the operation went on smoothly or there were errors * @draft API 1.7 freeze */ virtual void setAttribute(const UColAttribute attr, const UColAttributeValue value, UErrorCode &status) = 0; /** * Universal attribute getter * @param attr attribute type * @param status to indicate whether the operation went on smoothly or there were errors * @return attribute value * @draft API 1.7 freeze */ virtual UColAttributeValue getAttribute(const UColAttribute attr, UErrorCode &status) = 0; /** * Thread safe cloning operation * @return pointer to the new clone, user should remove it. * @draft API 1.7 freeze */ virtual Collator* safeClone(void) = 0; /** * String compare that uses user supplied character iteration. * The idea is to prevent users from having to convert the whole string into UChar's before comparing * since sometimes strings differ on first couple of characters. * @param coll collator to be used for comparing * @param source pointer to function for iterating over the first string * @param target pointer to function for iterating over the second string * @return The result of comparing the strings; one of UCOL_EQUAL, * UCOL_GREATER, UCOL_LESS * @draft API 1.7 freeze */ virtual EComparisonResult compare(ForwardCharacterIterator &source, ForwardCharacterIterator &target) = 0; /** * Get the sort key as an array of bytes from an UnicodeString. * @param source string to be processed. * @param result buffer to store result in. If NULL, number of bytes needed will be returned. * @param resultLength length of the result buffer. If if not enough the buffer will be filled to capacity. * @return Number of bytes needed for storing the sort key * @draft API 1.7 freeze */ virtual int32_t getSortKey(const UnicodeString& source, uint8_t *result, int32_t resultLength) const = 0; /** * Get the sort key as an array of bytes from an UChar buffer. * @param source string to be processed. * @param sourceLength length of string to be processed. * If -1, the string is 0 terminated and length will be decided by the function. * @param result buffer to store result in. If NULL, number of bytes needed will be returned. * @param resultLength length of the result buffer. If if not enough the buffer will be filled to capacity. * @return Number of bytes needed for storing the sort key * @draft API 1.7 freeze */ virtual int32_t getSortKey(const UChar *source, int32_t sourceLength, uint8_t *result, int32_t resultLength) const = 0; protected: /** * Constructors */ Collator(); Collator(ECollationStrength collationStrength, Normalizer::EMode decompositionMode); Collator(const Collator& other); /** * Assignment operator */ const Collator& operator=(const Collator& other); //-------------------------------------------------------------------------- private: ECollationStrength strength; Normalizer::EMode decmp; static const UVersionInfo fVersion; }; inline UBool Collator::operator==(const Collator& other) const { UBool result; if (this == &other) result = TRUE; else result = ((strength == other.strength) && (decmp == other.decmp)); return result; } inline UBool Collator::operator!=(const Collator& other) const { UBool result; result = !(*this == other); return result; } inline Collator::ECollationStrength Collator::getStrength() const { return strength; } inline Normalizer::EMode Collator::getDecomposition() const { return decmp; } #endif