Index: source/i18n/collationfastlatin.cpp |
diff --git a/source/i18n/collationfastlatin.cpp b/source/i18n/collationfastlatin.cpp |
index dc654a3efc2d02f25aa31e2f5293198f68864772..70e393c4dfeaecb6b9bbcfc392745d52deaf0363 100644 |
--- a/source/i18n/collationfastlatin.cpp |
+++ b/source/i18n/collationfastlatin.cpp |
@@ -1,6 +1,6 @@ |
/* |
******************************************************************************* |
-* Copyright (C) 2013-2014, International Business Machines |
+* Copyright (C) 2013-2015, International Business Machines |
* Corporation and others. All Rights Reserved. |
******************************************************************************* |
* collationfastlatin.cpp |
@@ -17,7 +17,6 @@ |
#include "collationdata.h" |
#include "collationfastlatin.h" |
#include "collationsettings.h" |
-#include "putilimp.h" // U_ALIGN_CODE |
#include "uassert.h" |
U_NAMESPACE_BEGIN |
@@ -36,33 +35,50 @@ CollationFastLatin::getOptions(const CollationData *data, const CollationSetting |
// lowest long mini primary. |
miniVarTop = MIN_LONG - 1; |
} else { |
- uint32_t v1 = settings.variableTop >> 24; |
int32_t headerLength = *table & 0xff; |
- int32_t i = headerLength - 1; |
- if(i <= 0 || v1 > (table[i] & 0x7fu)) { |
+ int32_t i = 1 + settings.getMaxVariable(); |
+ if(i >= headerLength) { |
return -1; // variableTop >= digits, should not occur |
} |
- while(i > 1 && v1 <= (table[i - 1] & 0x7fu)) { --i; } |
- // In the table header, the miniVarTop is in bits 15..7, with 4 zero bits 19..16 implied. |
- // Shift right to make it comparable with long mini primaries in bits 15..3. |
- miniVarTop = (table[i] & 0xff80) >> 4; |
+ miniVarTop = table[i]; |
} |
- const uint8_t *reorderTable = settings.reorderTable; |
- if(reorderTable != NULL) { |
- const uint16_t *scripts = data->scripts; |
- int32_t length = data->scriptsLength; |
- uint32_t prevLastByte = 0; |
- for(int32_t i = 0; i < length;) { |
- // reordered last byte of the group |
- uint32_t lastByte = reorderTable[scripts[i] & 0xff]; |
- if(lastByte < prevLastByte) { |
- // The permutation affects the groups up to Latin. |
- return -1; |
+ UBool digitsAreReordered = FALSE; |
+ if(settings.hasReordering()) { |
+ uint32_t prevStart = 0; |
+ uint32_t beforeDigitStart = 0; |
+ uint32_t digitStart = 0; |
+ uint32_t afterDigitStart = 0; |
+ for(int32_t group = UCOL_REORDER_CODE_FIRST; |
+ group < UCOL_REORDER_CODE_FIRST + CollationData::MAX_NUM_SPECIAL_REORDER_CODES; |
+ ++group) { |
+ uint32_t start = data->getFirstPrimaryForGroup(group); |
+ start = settings.reorder(start); |
+ if(group == UCOL_REORDER_CODE_DIGIT) { |
+ beforeDigitStart = prevStart; |
+ digitStart = start; |
+ } else if(start != 0) { |
+ if(start < prevStart) { |
+ // The permutation affects the groups up to Latin. |
+ return -1; |
+ } |
+ // In the future, there might be a special group between digits & Latin. |
+ if(digitStart != 0 && afterDigitStart == 0 && prevStart == beforeDigitStart) { |
+ afterDigitStart = start; |
+ } |
+ prevStart = start; |
} |
- if(scripts[i + 2] == USCRIPT_LATIN) { break; } |
- i = i + 2 + scripts[i + 1]; |
- prevLastByte = lastByte; |
+ } |
+ uint32_t latinStart = data->getFirstPrimaryForGroup(USCRIPT_LATIN); |
+ latinStart = settings.reorder(latinStart); |
+ if(latinStart < prevStart) { |
+ return -1; |
+ } |
+ if(afterDigitStart == 0) { |
+ afterDigitStart = latinStart; |
+ } |
+ if(!(beforeDigitStart < digitStart && digitStart < afterDigitStart)) { |
+ digitsAreReordered = TRUE; |
} |
} |
@@ -78,7 +94,7 @@ CollationFastLatin::getOptions(const CollationData *data, const CollationSetting |
} |
primaries[c] = (uint16_t)p; |
} |
- if((settings.options & CollationSettings::NUMERIC) != 0) { |
+ if(digitsAreReordered || (settings.options & CollationSettings::NUMERIC) != 0) { |
// Bail out for digits. |
for(UChar32 c = 0x30; c <= 0x39; ++c) { primaries[c] = 0; } |
} |
@@ -102,7 +118,6 @@ CollationFastLatin::compareUTF16(const uint16_t *table, const uint16_t *primarie |
options &= 0xffff; // needed for CollationSettings::getStrength() to work |
// Check for supported characters, fetch mini CEs, and compare primaries. |
- U_ALIGN_CODE(16); |
int32_t leftIndex = 0, rightIndex = 0; |
/** |
* Single mini CE or a pair. |
@@ -439,7 +454,6 @@ CollationFastLatin::compareUTF8(const uint16_t *table, const uint16_t *primaries |
options &= 0xffff; // needed for CollationSettings::getStrength() to work |
// Check for supported characters, fetch mini CEs, and compare primaries. |
- U_ALIGN_CODE(16); |
int32_t leftIndex = 0, rightIndex = 0; |
/** |
* Single mini CE or a pair. |