int32_t
CollationSettings::hashCode() const {
int32_t h = options << 8; if((options & ALTERNATE_MASK) != 0) { h ^= variableTop; }
h ^= reorderCodesLength; for(int32_t i = 0; i < reorderCodesLength; ++i) {
h ^= (reorderCodes[i] << i);
} return h;
}
void
CollationSettings::resetReordering() { // When we turn off reordering, we want to set a nullptr permutation // rather than a no-op permutation. // Keep the memory via reorderCodes and its capacity.
reorderTable = nullptr;
minHighNoReorder = 0;
reorderRangesLength = 0;
reorderCodesLength = 0;
}
void
CollationSettings::aliasReordering(const CollationData &data, const int32_t *codes, int32_t length, const uint32_t *ranges, int32_t rangesLength, const uint8_t *table, UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return; } if(table != nullptr &&
(rangesLength == 0 ?
!reorderTableHasSplitBytes(table) :
rangesLength >= 2 && // The first offset must be 0. The last offset must not be 0.
(ranges[0] & 0xffff) == 0 && (ranges[rangesLength - 1] & 0xffff) != 0)) { // We need to release the memory before setting the alias pointer. if(reorderCodesCapacity != 0) {
uprv_free(const_cast<int32_t *>(reorderCodes));
reorderCodesCapacity = 0;
}
reorderTable = table;
reorderCodes = codes;
reorderCodesLength = length; // Drop ranges before the first split byte. They are reordered by the table. // This then speeds up reordering of the remaining ranges.
int32_t firstSplitByteRangeIndex = 0; while(firstSplitByteRangeIndex < rangesLength &&
(ranges[firstSplitByteRangeIndex] & 0xff0000) == 0) { // The second byte of the primary limit is 0.
++firstSplitByteRangeIndex;
} if(firstSplitByteRangeIndex == rangesLength) {
U_ASSERT(!reorderTableHasSplitBytes(table));
minHighNoReorder = 0;
reorderRanges = nullptr;
reorderRangesLength = 0;
} else {
U_ASSERT(table[ranges[firstSplitByteRangeIndex] >> 24] == 0);
minHighNoReorder = ranges[rangesLength - 1] & 0xffff0000;
reorderRanges = ranges + firstSplitByteRangeIndex;
reorderRangesLength = rangesLength - firstSplitByteRangeIndex;
} return;
} // Regenerate missing data.
setReordering(data, codes, length, errorCode);
}
void
CollationSettings::setReordering(const CollationData &data, const int32_t *codes, int32_t codesLength,
UErrorCode &errorCode) { if(U_FAILURE(errorCode)) { return; } if(codesLength == 0 || (codesLength == 1 && codes[0] == UCOL_REORDER_CODE_NONE)) {
resetReordering(); return;
}
UVector32 rangesList(errorCode);
data.makeReorderRanges(codes, codesLength, rangesList, errorCode); if(U_FAILURE(errorCode)) { return; }
int32_t rangesLength = rangesList.size(); if(rangesLength == 0) {
resetReordering(); return;
} const uint32_t *ranges = reinterpret_cast<uint32_t *>(rangesList.getBuffer()); // ranges[] contains at least two (limit, offset) pairs. // The first offset must be 0. The last offset must not be 0. // Separators (at the low end) and trailing weights (at the high end) // are never reordered.
U_ASSERT(rangesLength >= 2);
U_ASSERT((ranges[0] & 0xffff) == 0 && (ranges[rangesLength - 1] & 0xffff) != 0);
minHighNoReorder = ranges[rangesLength - 1] & 0xffff0000;
// Write the lead byte permutation table. // Set a 0 for each lead byte that has a range boundary in the middle.
uint8_t table[256];
int32_t b = 0;
int32_t firstSplitByteRangeIndex = -1; for(int32_t i = 0; i < rangesLength; ++i) {
uint32_t pair = ranges[i];
int32_t limit1 = static_cast<int32_t>(pair >> 24); while(b < limit1) {
table[b] = static_cast<uint8_t>(b + pair);
++b;
} // Check the second byte of the limit. if((pair & 0xff0000) != 0) {
table[limit1] = 0;
b = limit1 + 1; if(firstSplitByteRangeIndex < 0) {
firstSplitByteRangeIndex = i;
}
}
} while(b <= 0xff) {
table[b] = static_cast<uint8_t>(b);
++b;
} if(firstSplitByteRangeIndex < 0) { // The lead byte permutation table alone suffices for reordering.
rangesLength = 0;
} else { // Remove the ranges below the first split byte.
ranges += firstSplitByteRangeIndex;
rangesLength -= firstSplitByteRangeIndex;
}
setReorderArrays(codes, codesLength, ranges, rangesLength, table, errorCode);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.