]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/tblcoll.cpp
ICU-3.13.tar.gz
[apple/icu.git] / icuSources / i18n / tblcoll.cpp
1 /*
2 ******************************************************************************
3 * Copyright (C) {1996-2003}, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 ******************************************************************************
6 */
7
8 /**
9 * File tblcoll.cpp
10 *
11 * Created by: Helena Shih
12 *
13 * Modification History:
14 *
15 * Date Name Description
16 * 2/5/97 aliu Added streamIn and streamOut methods. Added
17 * constructor which reads RuleBasedCollator object from
18 * a binary file. Added writeToFile method which streams
19 * RuleBasedCollator out to a binary file. The streamIn
20 * and streamOut methods use istream and ostream objects
21 * in binary mode.
22 * 2/11/97 aliu Moved declarations out of for loop initializer.
23 * Added Mac compatibility #ifdef for ios::nocreate.
24 * 2/12/97 aliu Modified to use TableCollationData sub-object to
25 * hold invariant data.
26 * 2/13/97 aliu Moved several methods into this class from Collation.
27 * Added a private RuleBasedCollator(Locale&) constructor,
28 * to be used by Collator::getInstance(). General
29 * clean up. Made use of UErrorCode variables consistent.
30 * 2/20/97 helena Added clone, operator==, operator!=, operator=, and copy
31 * constructor and getDynamicClassID.
32 * 3/5/97 aliu Changed compaction cycle to improve performance. We
33 * use the maximum allowable value which is kBlockCount.
34 * Modified getRules() to load rules dynamically. Changed
35 * constructFromFile() call to accomodate this (added
36 * parameter to specify whether binary loading is to
37 * take place).
38 * 05/06/97 helena Added memory allocation error check.
39 * 6/20/97 helena Java class name change.
40 * 6/23/97 helena Adding comments to make code more readable.
41 * 09/03/97 helena Added createCollationKeyValues().
42 * 06/26/98 erm Changes for CollationKeys using byte arrays.
43 * 08/10/98 erm Synched with 1.2 version of RuleBasedCollator.java
44 * 04/23/99 stephen Removed EDecompositionMode, merged with
45 * Normalizer::EMode
46 * 06/14/99 stephen Removed kResourceBundleSuffix
47 * 06/22/99 stephen Fixed logic in constructFromFile() since .ctx
48 * files are no longer used.
49 * 11/02/99 helena Collator performance enhancements. Special case
50 * for NO_OP situations.
51 * 11/17/99 srl More performance enhancements. Inlined some internal functions.
52 * 12/15/99 aliu Update to support Thai collation. Move NormalizerIterator
53 * to implementation file.
54 * 01/29/01 synwee Modified into a C++ wrapper calling C APIs (ucol.h)
55 */
56
57 #include "unicode/utypes.h"
58
59 #if !UCONFIG_NO_COLLATION
60
61 #include "unicode/tblcoll.h"
62 #include "unicode/coleitr.h"
63 #include "unicode/resbund.h"
64 #include "unicode/uset.h"
65 #include "ucol_imp.h"
66 #include "uresimp.h"
67 #include "uhash.h"
68 #include "cmemory.h"
69 #include "cstring.h"
70
71 /* public RuleBasedCollator constructor ---------------------------------- */
72
73 U_NAMESPACE_BEGIN
74
75 /**
76 * Copy constructor, aliasing, not write-through
77 */
78 RuleBasedCollator::RuleBasedCollator(const RuleBasedCollator& that)
79 : Collator(that)
80 , dataIsOwned(FALSE)
81 , isWriteThroughAlias(FALSE)
82 , ucollator(that.ucollator)
83 , urulestring(that.urulestring)
84 {
85 }
86
87 RuleBasedCollator::RuleBasedCollator(const UnicodeString& rules,
88 UErrorCode& status) :
89 dataIsOwned(FALSE)
90 {
91 construct(rules,
92 UCOL_DEFAULT_STRENGTH,
93 UCOL_DEFAULT,
94 status);
95 }
96
97 RuleBasedCollator::RuleBasedCollator(const UnicodeString& rules,
98 ECollationStrength collationStrength,
99 UErrorCode& status) : dataIsOwned(FALSE)
100 {
101 construct(rules,
102 getUCollationStrength(collationStrength),
103 UCOL_DEFAULT,
104 status);
105 }
106
107 RuleBasedCollator::RuleBasedCollator(const UnicodeString& rules,
108 UColAttributeValue decompositionMode,
109 UErrorCode& status) :
110 dataIsOwned(FALSE)
111 {
112 construct(rules,
113 UCOL_DEFAULT_STRENGTH,
114 decompositionMode,
115 status);
116 }
117
118 RuleBasedCollator::RuleBasedCollator(const UnicodeString& rules,
119 ECollationStrength collationStrength,
120 UColAttributeValue decompositionMode,
121 UErrorCode& status) : dataIsOwned(FALSE)
122 {
123 construct(rules,
124 getUCollationStrength(collationStrength),
125 decompositionMode,
126 status);
127 }
128
129 void
130 RuleBasedCollator::setRuleStringFromCollator(UErrorCode& status)
131 {
132 urulestring = NULL;
133 if (U_SUCCESS(status))
134 {
135 int32_t length;
136 const UChar *r = ucol_getRules(ucollator, &length);
137
138 if (length > 0) {
139 // alias the rules string
140 urulestring = new UnicodeString(TRUE, r, length);
141 }
142 else {
143 urulestring = new UnicodeString();
144 }
145 /* test for NULL */
146 if (urulestring == 0) {
147 status = U_MEMORY_ALLOCATION_ERROR;
148 return;
149 }
150 }
151 }
152
153 // not aliasing, not write-through
154 void
155 RuleBasedCollator::construct(const UnicodeString& rules,
156 UColAttributeValue collationStrength,
157 UColAttributeValue decompositionMode,
158 UErrorCode& status)
159 {
160 urulestring = 0;
161 ucollator = ucol_openRules(rules.getBuffer(), rules.length(),
162 decompositionMode, collationStrength,
163 NULL, &status);
164
165 dataIsOwned = TRUE; // since we own a collator now, we need to get rid of it
166 isWriteThroughAlias = FALSE;
167
168 setRuleStringFromCollator(status);
169 }
170
171 /* RuleBasedCollator public destructor ----------------------------------- */
172
173 RuleBasedCollator::~RuleBasedCollator()
174 {
175 if (dataIsOwned)
176 {
177 ucol_close(ucollator);
178 delete urulestring;
179 }
180 ucollator = 0;
181 urulestring = 0;
182 }
183
184 /* RuleBaseCollator public methods --------------------------------------- */
185
186 UBool RuleBasedCollator::operator==(const Collator& that) const
187 {
188 /* only checks for address equals here */
189 if (Collator::operator==(that))
190 return TRUE;
191
192 if (getDynamicClassID() != that.getDynamicClassID())
193 return FALSE; /* not the same class */
194
195 RuleBasedCollator& thatAlias = (RuleBasedCollator&)that;
196
197 // weiv: use C function, commented code below is wrong
198 return ucol_equals(this->ucollator, thatAlias.ucollator);
199 /*
200 synwee : orginal code does not check for data compatibility
201 */
202 /*
203 if (ucollator != thatAlias.ucollator)
204 return FALSE;
205
206 return TRUE;
207 */
208 }
209
210 // aliasing, not write-through
211 RuleBasedCollator& RuleBasedCollator::operator=(const RuleBasedCollator& that)
212 {
213 if (this != &that)
214 {
215 if (dataIsOwned)
216 {
217 ucol_close(ucollator);
218 ucollator = NULL;
219 delete urulestring;
220 }
221
222 dataIsOwned = FALSE;
223 isWriteThroughAlias = FALSE;
224 ucollator = that.ucollator;
225 urulestring = that.urulestring;
226 }
227 return *this;
228 }
229
230 // aliasing, not write-through
231 Collator* RuleBasedCollator::clone() const
232 {
233 return new RuleBasedCollator(*this);
234 }
235
236 CollationElementIterator* RuleBasedCollator::createCollationElementIterator
237 (const UnicodeString& source) const
238 {
239 UErrorCode status = U_ZERO_ERROR;
240 CollationElementIterator *result = new CollationElementIterator(source, this,
241 status);
242 if (U_FAILURE(status)) {
243 delete result;
244 return NULL;
245 }
246
247 return result;
248 }
249
250 /**
251 * Create a CollationElementIterator object that will iterate over the
252 * elements in a string, using the collation rules defined in this
253 * RuleBasedCollator
254 */
255 CollationElementIterator* RuleBasedCollator::createCollationElementIterator
256 (const CharacterIterator& source) const
257 {
258 UErrorCode status = U_ZERO_ERROR;
259 CollationElementIterator *result = new CollationElementIterator(source, this,
260 status);
261
262 if (U_FAILURE(status)) {
263 delete result;
264 return NULL;
265 }
266
267 return result;
268 }
269
270 /**
271 * Return a string representation of this collator's rules. The string can
272 * later be passed to the constructor that takes a UnicodeString argument,
273 * which will construct a collator that's functionally identical to this one.
274 * You can also allow users to edit the string in order to change the collation
275 * data, or you can print it out for inspection, or whatever.
276 */
277 const UnicodeString& RuleBasedCollator::getRules() const
278 {
279 return (*urulestring);
280 }
281
282 void RuleBasedCollator::getRules(UColRuleOption delta, UnicodeString &buffer)
283 {
284 int32_t rulesize = ucol_getRulesEx(ucollator, delta, NULL, -1);
285
286 if (rulesize > 0) {
287 UChar *rules = (UChar*) uprv_malloc( sizeof(UChar) * (rulesize) );
288 if(rules != NULL) {
289 ucol_getRulesEx(ucollator, delta, rules, rulesize);
290 buffer.setTo(rules, rulesize);
291 uprv_free(rules);
292 } else { // couldn't allocate
293 buffer.remove();
294 }
295 }
296 else {
297 buffer.remove();
298 }
299 }
300
301 UnicodeSet *
302 RuleBasedCollator::getTailoredSet(UErrorCode &status) const
303 {
304 if(U_FAILURE(status)) {
305 return NULL;
306 }
307 return (UnicodeSet *)ucol_getTailoredSet(this->ucollator, &status);
308 }
309
310
311 void RuleBasedCollator::getVersion(UVersionInfo versionInfo) const
312 {
313 if (versionInfo!=NULL){
314 ucol_getVersion(ucollator, versionInfo);
315 }
316 }
317
318 Collator::EComparisonResult RuleBasedCollator::compare(
319 const UnicodeString& source,
320 const UnicodeString& target,
321 int32_t length) const
322 {
323 UErrorCode status = U_ZERO_ERROR;
324 return getEComparisonResult(compare(source.getBuffer(), uprv_min(length,source.length()), target.getBuffer(), uprv_min(length,target.length()), status));
325 }
326
327 UCollationResult RuleBasedCollator::compare(
328 const UnicodeString& source,
329 const UnicodeString& target,
330 int32_t length,
331 UErrorCode &status) const
332 {
333 return compare(source.getBuffer(), uprv_min(length,source.length()), target.getBuffer(), uprv_min(length,target.length()), status);
334 }
335
336 Collator::EComparisonResult RuleBasedCollator::compare(const UChar* source,
337 int32_t sourceLength,
338 const UChar* target,
339 int32_t targetLength)
340 const
341 {
342 return getEComparisonResult(ucol_strcoll(ucollator, source, sourceLength,
343 target, targetLength));
344 }
345
346 UCollationResult RuleBasedCollator::compare(const UChar* source,
347 int32_t sourceLength,
348 const UChar* target,
349 int32_t targetLength,
350 UErrorCode &status) const
351 {
352 if(U_SUCCESS(status)) {
353 return ucol_strcoll(ucollator, source, sourceLength, target, targetLength);
354 } else {
355 return UCOL_EQUAL;
356 }
357 }
358
359 /**
360 * Compare two strings using this collator
361 */
362 Collator::EComparisonResult RuleBasedCollator::compare(
363 const UnicodeString& source,
364 const UnicodeString& target) const
365 {
366 return getEComparisonResult(ucol_strcoll(ucollator, source.getBuffer(), source.length(),
367 target.getBuffer(), target.length()));
368 }
369
370 UCollationResult RuleBasedCollator::compare(
371 const UnicodeString& source,
372 const UnicodeString& target,
373 UErrorCode &status) const
374 {
375 if(U_SUCCESS(status)) {
376 return ucol_strcoll(ucollator, source.getBuffer(), source.length(),
377 target.getBuffer(), target.length());
378 } else {
379 return UCOL_EQUAL;
380 }
381 }
382
383 /**
384 * Retrieve a collation key for the specified string. The key can be compared
385 * with other collation keys using a bitwise comparison (e.g. memcmp) to find
386 * the ordering of their respective source strings. This is handy when doing a
387 * sort, where each sort key must be compared many times.
388 *
389 * The basic algorithm here is to find all of the collation elements for each
390 * character in the source string, convert them to an ASCII representation, and
391 * put them into the collation key. But it's trickier than that. Each
392 * collation element in a string has three components: primary ('A' vs 'B'),
393 * secondary ('u' vs 'ü'), and tertiary ('A' vs 'a'), and a primary difference
394 * at the end of a string takes precedence over a secondary or tertiary
395 * difference earlier in the string.
396 *
397 * To account for this, we put all of the primary orders at the beginning of
398 * the string, followed by the secondary and tertiary orders. Each set of
399 * orders is terminated by nulls so that a key for a string which is a initial
400 * substring of another key will compare less without any special case.
401 *
402 * Here's a hypothetical example, with the collation element represented as a
403 * three-digit number, one digit for primary, one for secondary, etc.
404 *
405 * String: A a B É
406 * Collation Elements: 101 100 201 511
407 * Collation Key: 1125<null>0001<null>1011<null>
408 *
409 * To make things even trickier, secondary differences (accent marks) are
410 * compared starting at the *end* of the string in languages with French
411 * secondary ordering. But when comparing the accent marks on a single base
412 * character, they are compared from the beginning. To handle this, we reverse
413 * all of the accents that belong to each base character, then we reverse the
414 * entire string of secondary orderings at the end.
415 */
416 CollationKey& RuleBasedCollator::getCollationKey(
417 const UnicodeString& source,
418 CollationKey& sortkey,
419 UErrorCode& status) const
420 {
421 return getCollationKey(source.getBuffer(), source.length(), sortkey, status);
422 }
423
424 CollationKey& RuleBasedCollator::getCollationKey(const UChar* source,
425 int32_t sourceLen,
426 CollationKey& sortkey,
427 UErrorCode& status) const
428 {
429 if (U_FAILURE(status))
430 {
431 return sortkey.setToBogus();
432 }
433
434 if ((!source) || (sourceLen == 0)) {
435 return sortkey.reset();
436 }
437
438 uint8_t *result;
439 int32_t resultLen = ucol_getSortKeyWithAllocation(ucollator,
440 source, sourceLen,
441 &result,
442 &status);
443 sortkey.adopt(result, resultLen);
444 return sortkey;
445 }
446
447 /**
448 * Return the maximum length of any expansion sequences that end with the
449 * specified comparison order.
450 * @param order a collation order returned by previous or next.
451 * @return the maximum length of any expansion seuences ending with the
452 * specified order or 1 if collation order does not occur at the end of any
453 * expansion sequence.
454 * @see CollationElementIterator#getMaxExpansion
455 */
456 int32_t RuleBasedCollator::getMaxExpansion(int32_t order) const
457 {
458 uint8_t result;
459 UCOL_GETMAXEXPANSION(ucollator, (uint32_t)order, result);
460 return result;
461 }
462
463 uint8_t* RuleBasedCollator::cloneRuleData(int32_t &length,
464 UErrorCode &status)
465 {
466 return ucol_cloneRuleData(ucollator, &length, &status);
467 }
468
469 void RuleBasedCollator::setAttribute(UColAttribute attr,
470 UColAttributeValue value,
471 UErrorCode &status)
472 {
473 if (U_FAILURE(status))
474 return;
475 checkOwned();
476 ucol_setAttribute(ucollator, attr, value, &status);
477 }
478
479 UColAttributeValue RuleBasedCollator::getAttribute(UColAttribute attr,
480 UErrorCode &status)
481 {
482 if (U_FAILURE(status))
483 return UCOL_DEFAULT;
484 return ucol_getAttribute(ucollator, attr, &status);
485 }
486
487 uint32_t RuleBasedCollator::setVariableTop(const UChar *varTop, int32_t len, UErrorCode &status) {
488 checkOwned();
489 return ucol_setVariableTop(ucollator, varTop, len, &status);
490 }
491
492 uint32_t RuleBasedCollator::setVariableTop(const UnicodeString varTop, UErrorCode &status) {
493 checkOwned();
494 return ucol_setVariableTop(ucollator, varTop.getBuffer(), varTop.length(), &status);
495 }
496
497 void RuleBasedCollator::setVariableTop(const uint32_t varTop, UErrorCode &status) {
498 checkOwned();
499 ucol_restoreVariableTop(ucollator, varTop, &status);
500 }
501
502 uint32_t RuleBasedCollator::getVariableTop(UErrorCode &status) const {
503 return ucol_getVariableTop(ucollator, &status);
504 }
505
506 Collator* RuleBasedCollator::safeClone(void)
507 {
508 UErrorCode intStatus = U_ZERO_ERROR;
509 int32_t buffersize = U_COL_SAFECLONE_BUFFERSIZE;
510 UCollator *ucol = ucol_safeClone(ucollator, NULL, &buffersize,
511 &intStatus);
512 if (U_FAILURE(intStatus)) {
513 return NULL;
514 }
515
516 UnicodeString *r = new UnicodeString(*urulestring);
517 RuleBasedCollator *result = new RuleBasedCollator(ucol, r);
518 result->dataIsOwned = TRUE;
519 result->isWriteThroughAlias = FALSE;
520
521 return result;
522 }
523
524
525 int32_t RuleBasedCollator::getSortKey(const UnicodeString& source,
526 uint8_t *result, int32_t resultLength)
527 const
528 {
529 return ucol_getSortKey(ucollator, source.getBuffer(), source.length(), result, resultLength);
530 }
531
532 int32_t RuleBasedCollator::getSortKey(const UChar *source,
533 int32_t sourceLength, uint8_t *result,
534 int32_t resultLength) const
535 {
536 return ucol_getSortKey(ucollator, source, sourceLength, result, resultLength);
537 }
538
539 Collator::ECollationStrength RuleBasedCollator::getStrength(void) const
540 {
541 UErrorCode intStatus = U_ZERO_ERROR;
542 return getECollationStrength(ucol_getAttribute(ucollator, UCOL_STRENGTH,
543 &intStatus));
544 }
545
546 void RuleBasedCollator::setStrength(ECollationStrength newStrength)
547 {
548 checkOwned();
549 UErrorCode intStatus = U_ZERO_ERROR;
550 UCollationStrength strength = getUCollationStrength(newStrength);
551 ucol_setAttribute(ucollator, UCOL_STRENGTH, strength, &intStatus);
552 }
553
554 /**
555 * Create a hash code for this collation. Just hash the main rule table -- that
556 * should be good enough for almost any use.
557 */
558 int32_t RuleBasedCollator::hashCode() const
559 {
560 int32_t length;
561 const UChar *rules = ucol_getRules(ucollator, &length);
562 return uhash_hashUCharsN(rules, length);
563 }
564
565 /**
566 * return the locale of this collator
567 */
568 const Locale RuleBasedCollator::getLocale(ULocDataLocaleType type, UErrorCode &status) const {
569 const char *result = ucol_getLocale(ucollator, type, &status);
570 if(result == NULL) {
571 Locale res("");
572 res.setToBogus();
573 return res;
574 } else {
575 return Locale(result);
576 }
577 }
578
579 void
580 RuleBasedCollator::setLocales(const Locale& requestedLocale, const Locale& validLocale) {
581 checkOwned();
582 size_t rlen = uprv_strlen(requestedLocale.getName());
583 char* rloc = (char *)uprv_malloc((rlen+1)*sizeof(char));
584 if (rloc) {
585 uprv_strcpy(rloc, requestedLocale.getName());
586 size_t vlen = uprv_strlen(validLocale.getName());
587 char* vloc = (char*)uprv_malloc((vlen+1)*sizeof(char));
588 if (vloc) {
589 uprv_strcpy(vloc, validLocale.getName());
590 ucol_setReqValidLocales(ucollator, rloc, vloc);
591 return;
592 }
593 uprv_free(rloc);
594 }
595 }
596
597 // RuleBaseCollatorNew private constructor ----------------------------------
598
599 RuleBasedCollator::RuleBasedCollator()
600 : dataIsOwned(FALSE), isWriteThroughAlias(FALSE), ucollator(0), urulestring(0)
601 {
602 }
603
604 RuleBasedCollator::RuleBasedCollator(UCollator *collator,
605 UnicodeString *rule)
606 : dataIsOwned(FALSE), isWriteThroughAlias(FALSE), urulestring(0)
607 {
608 ucollator = collator;
609 urulestring = rule;
610 }
611
612 RuleBasedCollator::RuleBasedCollator(const Locale& desiredLocale,
613 UErrorCode& status) :
614 dataIsOwned(FALSE), ucollator(0), urulestring(0)
615 {
616 if (U_FAILURE(status))
617 return;
618
619 /*
620 Try to load, in order:
621 1. The desired locale's collation.
622 2. A fallback of the desired locale.
623 3. The default locale's collation.
624 4. A fallback of the default locale.
625 5. The default collation rules, which contains en_US collation rules.
626
627 To reiterate, we try:
628 Specific:
629 language+country+variant
630 language+country
631 language
632 Default:
633 language+country+variant
634 language+country
635 language
636 Root: (aka DEFAULTRULES)
637 steps 1-5 are handled by resource bundle fallback mechanism.
638 however, in a very unprobable situation that no resource bundle
639 data exists, step 5 is repeated with hardcoded default rules.
640 */
641
642 setUCollator(desiredLocale, status);
643
644 if (U_FAILURE(status))
645 {
646 status = U_ZERO_ERROR;
647
648 setUCollator(kRootLocaleName, status);
649 if (status == U_ZERO_ERROR) {
650 status = U_USING_DEFAULT_WARNING;
651 }
652 }
653
654 if (U_SUCCESS(status))
655 {
656 int32_t length;
657 const UChar *r = ucol_getRules(ucollator, &length);
658 if (length > 0) {
659 // alias the rules string
660 urulestring = new UnicodeString(TRUE, r, length);
661 }
662 else {
663 urulestring = new UnicodeString();
664 }
665 /* test for NULL */
666 if (urulestring == 0) {
667 status = U_MEMORY_ALLOCATION_ERROR;
668 return;
669 }
670 dataIsOwned = TRUE;
671 isWriteThroughAlias = FALSE;
672 }
673
674 return;
675 }
676
677 void
678 RuleBasedCollator::setUCollator(const char *locale,
679 UErrorCode &status)
680 {
681 if (U_FAILURE(status))
682 return;
683 if (ucollator && dataIsOwned)
684 ucol_close(ucollator);
685 ucollator = ucol_open_internal(locale, &status);
686 dataIsOwned = TRUE;
687 isWriteThroughAlias = FALSE;
688 }
689
690
691 void
692 RuleBasedCollator::checkOwned() {
693 if (!(dataIsOwned || isWriteThroughAlias)) {
694 UErrorCode status = U_ZERO_ERROR;
695 ucollator = ucol_safeClone(ucollator, NULL, NULL, &status);
696 setRuleStringFromCollator(status);
697 dataIsOwned = TRUE;
698 isWriteThroughAlias = FALSE;
699 }
700 }
701
702 /* RuleBasedCollator private data members -------------------------------- */
703
704 /*
705 * TODO:
706 * These should probably be enums (<=0xffff) or #defines (>0xffff)
707 * for better performance.
708 * Include ucol_imp.h and use its constants if possible.
709 * Only used in coleitr.h?!
710 * Remove from here!
711 */
712
713 /* need look up in .commit() */
714 const int32_t RuleBasedCollator::CHARINDEX = 0x70000000;
715 /* Expand index follows */
716 const int32_t RuleBasedCollator::EXPANDCHARINDEX = 0x7E000000;
717 /* contract indexes follows */
718 const int32_t RuleBasedCollator::CONTRACTCHARINDEX = 0x7F000000;
719 /* unmapped character values */
720 const int32_t RuleBasedCollator::UNMAPPED = 0xFFFFFFFF;
721 /* primary strength increment */
722 const int32_t RuleBasedCollator::PRIMARYORDERINCREMENT = 0x00010000;
723 /* secondary strength increment */
724 const int32_t RuleBasedCollator::SECONDARYORDERINCREMENT = 0x00000100;
725 /* tertiary strength increment */
726 const int32_t RuleBasedCollator::TERTIARYORDERINCREMENT = 0x00000001;
727 /* mask off anything but primary order */
728 const int32_t RuleBasedCollator::PRIMARYORDERMASK = 0xffff0000;
729 /* mask off anything but secondary order */
730 const int32_t RuleBasedCollator::SECONDARYORDERMASK = 0x0000ff00;
731 /* mask off anything but tertiary order */
732 const int32_t RuleBasedCollator::TERTIARYORDERMASK = 0x000000ff;
733 /* mask off ignorable char order */
734 const int32_t RuleBasedCollator::IGNORABLEMASK = 0x0000ffff;
735 /* use only the primary difference */
736 const int32_t RuleBasedCollator::PRIMARYDIFFERENCEONLY = 0xffff0000;
737 /* use only the primary and secondary difference */
738 const int32_t RuleBasedCollator::SECONDARYDIFFERENCEONLY = 0xffffff00;
739 /* primary order shift */
740 const int32_t RuleBasedCollator::PRIMARYORDERSHIFT = 16;
741 /* secondary order shift */
742 const int32_t RuleBasedCollator::SECONDARYORDERSHIFT = 8;
743 /* starting value for collation elements */
744 const int32_t RuleBasedCollator::COLELEMENTSTART = 0x02020202;
745 /* testing mask for primary low element */
746 const int32_t RuleBasedCollator::PRIMARYLOWZEROMASK = 0x00FF0000;
747 /* reseting value for secondaries and tertiaries */
748 const int32_t RuleBasedCollator::RESETSECONDARYTERTIARY = 0x00000202;
749 /* reseting value for tertiaries */
750 const int32_t RuleBasedCollator::RESETTERTIARY = 0x00000002;
751
752 const int32_t RuleBasedCollator::PRIMIGNORABLE = 0x0202;
753
754 /* unique file id for parity check */
755 const int16_t RuleBasedCollator::FILEID = 0x5443;
756 /* binary collation file extension */
757 const char RuleBasedCollator::kFilenameSuffix[] = ".col";
758 /* class id ? Value is irrelevant */
759 const char RuleBasedCollator::fgClassID = 0;
760
761 U_NAMESPACE_END
762
763 #endif /* #if !UCONFIG_NO_COLLATION */