mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-8468 add cloning of collator reordering information - also added test for duplicate reorder codes
X-SVN-Rev: 29779
This commit is contained in:
parent
380074d3e4
commit
de5faa255e
5 changed files with 196 additions and 53 deletions
|
@ -249,6 +249,7 @@ Collator* RuleBasedCollator::clone() const
|
|||
return new RuleBasedCollator(*this);
|
||||
}
|
||||
|
||||
|
||||
CollationElementIterator* RuleBasedCollator::createCollationElementIterator
|
||||
(const UnicodeString& source) const
|
||||
{
|
||||
|
@ -598,6 +599,7 @@ void RuleBasedCollator::setReorderCodes(const int32_t *reorderCodes,
|
|||
int32_t reorderCodesLength,
|
||||
UErrorCode& status)
|
||||
{
|
||||
checkOwned();
|
||||
ucol_setReorderCodes(ucollator, reorderCodes, reorderCodesLength, &status);
|
||||
}
|
||||
|
||||
|
@ -711,8 +713,9 @@ void
|
|||
RuleBasedCollator::setUCollator(const char *locale,
|
||||
UErrorCode &status)
|
||||
{
|
||||
if (U_FAILURE(status))
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
if (ucollator && dataIsOwned)
|
||||
ucol_close(ucollator);
|
||||
ucollator = ucol_open_internal(locale, &status);
|
||||
|
|
|
@ -542,8 +542,13 @@ ucol_safeClone(const UCollator *coll, void *stackBuffer, int32_t * pBufferSize,
|
|||
int32_t imageSize = 0;
|
||||
int32_t rulesSize = 0;
|
||||
int32_t rulesPadding = 0;
|
||||
int32_t defaultReorderCodesSize = 0;
|
||||
int32_t reorderCodesSize = 0;
|
||||
uint8_t *image;
|
||||
UChar *rules;
|
||||
int32_t* defaultReorderCodes;
|
||||
int32_t* reorderCodes;
|
||||
uint8_t* leadBytePermutationTable;
|
||||
UBool colAllocated = FALSE;
|
||||
UBool imageAllocated = FALSE;
|
||||
|
||||
|
@ -554,13 +559,26 @@ ucol_safeClone(const UCollator *coll, void *stackBuffer, int32_t * pBufferSize,
|
|||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (coll->rules && coll->freeRulesOnClose) {
|
||||
rulesSize = (int32_t)(coll->rulesLength + 1)*sizeof(UChar);
|
||||
rulesPadding = (int32_t)(bufferSizeNeeded % sizeof(UChar));
|
||||
bufferSizeNeeded += rulesSize + rulesPadding;
|
||||
}
|
||||
|
||||
if (stackBuffer && *pBufferSize <= 0){ /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
// no padding for alignment needed from here since the next two are 4 byte quantities
|
||||
if (coll->defaultReorderCodes) {
|
||||
defaultReorderCodesSize = coll->defaultReorderCodesLength * sizeof(int32_t);
|
||||
bufferSizeNeeded += defaultReorderCodesSize;
|
||||
}
|
||||
if (coll->reorderCodes) {
|
||||
reorderCodesSize = coll->reorderCodesLength * sizeof(int32_t);
|
||||
bufferSizeNeeded += reorderCodesSize;
|
||||
}
|
||||
if (coll->leadBytePermutationTable) {
|
||||
bufferSizeNeeded += 256 * sizeof(uint8_t);
|
||||
}
|
||||
|
||||
if (stackBuffer && *pBufferSize <= 0) { /* 'preflighting' request - set needed size into *pBufferSize */
|
||||
*pBufferSize = bufferSizeNeeded;
|
||||
return 0;
|
||||
}
|
||||
|
@ -596,6 +614,10 @@ ucol_safeClone(const UCollator *coll, void *stackBuffer, int32_t * pBufferSize,
|
|||
}
|
||||
localCollator = (UCollator *)stackBufferChars;
|
||||
rules = (UChar *)(stackBufferChars + sizeof(UCollator) + rulesPadding);
|
||||
defaultReorderCodes = (int32_t*)((uint8_t*)rules + rulesSize);
|
||||
reorderCodes = (int32_t*)((uint8_t*)defaultReorderCodes + defaultReorderCodesSize);
|
||||
leadBytePermutationTable = (uint8_t*)reorderCodes + reorderCodesSize;
|
||||
|
||||
{
|
||||
UErrorCode tempStatus = U_ZERO_ERROR;
|
||||
imageSize = ucol_cloneBinary(coll, NULL, 0, &tempStatus);
|
||||
|
@ -629,6 +651,25 @@ ucol_safeClone(const UCollator *coll, void *stackBuffer, int32_t * pBufferSize,
|
|||
localCollator->freeRulesOnClose = FALSE;
|
||||
localCollator->rulesLength = coll->rulesLength;
|
||||
}
|
||||
|
||||
// collator reordering
|
||||
if (coll->defaultReorderCodes) {
|
||||
localCollator->defaultReorderCodes =
|
||||
(int32_t*) uprv_memcpy(defaultReorderCodes, coll->defaultReorderCodes, coll->defaultReorderCodesLength * sizeof(int32_t));
|
||||
localCollator->defaultReorderCodesLength = coll->defaultReorderCodesLength;
|
||||
localCollator->freeDefaultReorderCodesOnClose = FALSE;
|
||||
}
|
||||
if (coll->reorderCodes) {
|
||||
localCollator->reorderCodes =
|
||||
(int32_t*)uprv_memcpy(reorderCodes, coll->reorderCodes, coll->reorderCodesLength * sizeof(int32_t));
|
||||
localCollator->reorderCodesLength = coll->reorderCodesLength;
|
||||
localCollator->freeReorderCodesOnClose = FALSE;
|
||||
}
|
||||
if (coll->leadBytePermutationTable) {
|
||||
localCollator->leadBytePermutationTable =
|
||||
(uint8_t*) uprv_memcpy(leadBytePermutationTable, coll->leadBytePermutationTable, 256);
|
||||
localCollator->freeLeadBytePermutationTableOnClose = FALSE;
|
||||
}
|
||||
|
||||
int32_t i;
|
||||
for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) {
|
||||
|
@ -673,13 +714,14 @@ ucol_close(UCollator *coll)
|
|||
if(coll->image != NULL && coll->freeImageOnClose) {
|
||||
uprv_free((UCATableHeader *)coll->image);
|
||||
}
|
||||
if(coll->leadBytePermutationTable != NULL) {
|
||||
|
||||
if(coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
}
|
||||
if(coll->defaultReorderCodes != NULL) {
|
||||
if(coll->defaultReorderCodes != NULL && coll->freeDefaultReorderCodesOnClose == TRUE) {
|
||||
uprv_free(coll->defaultReorderCodes);
|
||||
}
|
||||
if(coll->reorderCodes != NULL) {
|
||||
if(coll->reorderCodes != NULL && coll->freeReorderCodesOnClose == TRUE) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
}
|
||||
|
||||
|
@ -871,9 +913,12 @@ UCollator* ucol_initCollator(const UCATableHeader *image, UCollator *fillIn, con
|
|||
result->freeRulesOnClose = FALSE;
|
||||
result->defaultReorderCodes = NULL;
|
||||
result->defaultReorderCodesLength = 0;
|
||||
result->freeDefaultReorderCodesOnClose = FALSE;
|
||||
result->reorderCodes = NULL;
|
||||
result->reorderCodesLength = 0;
|
||||
result->freeReorderCodesOnClose = FALSE;
|
||||
result->leadBytePermutationTable = NULL;
|
||||
result->freeLeadBytePermutationTableOnClose = FALSE;
|
||||
|
||||
/* get the version info from UCATableHeader and populate the Collator struct*/
|
||||
result->dataVersion[0] = result->image->version[0]; /* UCA Builder version*/
|
||||
|
@ -6968,6 +7013,7 @@ ucol_setAttribute(UCollator *coll, UColAttribute attr, UColAttributeValue value,
|
|||
if(U_FAILURE(*status) || coll == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
UColAttributeValue oldFrench = coll->frenchCollation;
|
||||
UColAttributeValue oldCaseFirst = coll->caseFirst;
|
||||
switch(attr) {
|
||||
|
@ -7149,13 +7195,13 @@ U_CAPI int32_t U_EXPORT2
|
|||
ucol_getReorderCodes(const UCollator *coll,
|
||||
int32_t *dest,
|
||||
int32_t destCapacity,
|
||||
UErrorCode *pErrorCode) {
|
||||
if (U_FAILURE(*pErrorCode)) {
|
||||
UErrorCode *status) {
|
||||
if (U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (destCapacity < 0 || (destCapacity > 0 && dest == NULL)) {
|
||||
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -7165,7 +7211,7 @@ ucol_getReorderCodes(const UCollator *coll,
|
|||
#endif
|
||||
|
||||
if (coll->reorderCodesLength > destCapacity) {
|
||||
*pErrorCode = U_BUFFER_OVERFLOW_ERROR;
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
return coll->reorderCodesLength;
|
||||
}
|
||||
for (int32_t i = 0; i < coll->reorderCodesLength; i++) {
|
||||
|
@ -7178,39 +7224,39 @@ U_CAPI void U_EXPORT2
|
|||
ucol_setReorderCodes(UCollator* coll,
|
||||
const int32_t* reorderCodes,
|
||||
int32_t reorderCodesLength,
|
||||
UErrorCode *pErrorCode) {
|
||||
if (U_FAILURE(*pErrorCode)) {
|
||||
UErrorCode *status) {
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reorderCodesLength < 0 || (reorderCodesLength > 0 && reorderCodes == NULL)) {
|
||||
*pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
uprv_free(coll->reorderCodes);
|
||||
if (coll->reorderCodes != NULL && coll->freeReorderCodesOnClose == TRUE) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
}
|
||||
coll->reorderCodes = NULL;
|
||||
coll->reorderCodesLength = 0;
|
||||
if (reorderCodesLength == 0) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
return;
|
||||
}
|
||||
coll->reorderCodes = (int32_t*) uprv_malloc(reorderCodesLength * sizeof(int32_t));
|
||||
if (coll->reorderCodes == NULL) {
|
||||
*pErrorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
coll->freeReorderCodesOnClose = TRUE;
|
||||
for (int32_t i = 0; i < reorderCodesLength; i++) {
|
||||
coll->reorderCodes[i] = reorderCodes[i];
|
||||
}
|
||||
coll->reorderCodesLength = reorderCodesLength;
|
||||
ucol_buildPermutationTable(coll, pErrorCode);
|
||||
if (U_FAILURE(*pErrorCode)) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
coll->reorderCodes = NULL;
|
||||
coll->reorderCodesLength = 0;
|
||||
}
|
||||
ucol_buildPermutationTable(coll, status);
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
|
|
|
@ -1029,6 +1029,9 @@ struct UCollator {
|
|||
UBool freeOptionsOnClose;
|
||||
UBool freeRulesOnClose;
|
||||
UBool freeImageOnClose;
|
||||
UBool freeDefaultReorderCodesOnClose;
|
||||
UBool freeReorderCodesOnClose;
|
||||
UBool freeLeadBytePermutationTableOnClose;
|
||||
|
||||
UBool latinOneUse;
|
||||
UBool latinOneRegenTable;
|
||||
|
@ -1112,13 +1115,13 @@ ucol_openRulesForImport( const UChar *rules,
|
|||
UErrorCode *status);
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
U_CFUNC void U_EXPORT2
|
||||
ucol_buildPermutationTable(UCollator *coll, UErrorCode *status);
|
||||
|
||||
U_CAPI int U_EXPORT2
|
||||
U_CFUNC int U_EXPORT2
|
||||
ucol_getLeadBytesForReorderCode(const UCollator *uca, int reorderCode, uint16_t* returnLeadBytes, int returnCapacity);
|
||||
|
||||
U_CAPI int U_EXPORT2
|
||||
U_CFUNC int U_EXPORT2
|
||||
ucol_getReorderCodesForLeadByte(const UCollator *uca, int leadByte, int16_t* returnReorderCodes, int returnCapacity);
|
||||
|
||||
#ifdef XP_CPLUSPLUS
|
||||
|
|
|
@ -274,7 +274,14 @@ ucol_open_internal(const char *loc,
|
|||
if (U_SUCCESS(intStatus)) {
|
||||
int32_t reorderCodesLen = 0;
|
||||
const int32_t* reorderCodes = ures_getIntVector(reorderRes, &reorderCodesLen, status);
|
||||
ucol_setReorderCodes(result, reorderCodes, reorderCodesLen, status);
|
||||
if (reorderCodesLen > 0) {
|
||||
ucol_setReorderCodes(result, reorderCodes, reorderCodesLen, status);
|
||||
// copy the reorder codes into the default reorder codes
|
||||
result->defaultReorderCodesLength = result->reorderCodesLength;
|
||||
result->defaultReorderCodes = (int32_t*) uprv_malloc(result->defaultReorderCodesLength * sizeof(int32_t));
|
||||
uprv_memcpy(result->defaultReorderCodes, result->reorderCodes, result->defaultReorderCodesLength * sizeof(int32_t));
|
||||
result->freeDefaultReorderCodesOnClose = TRUE;
|
||||
}
|
||||
if (U_FAILURE(*status)) {
|
||||
goto clean;
|
||||
}
|
||||
|
@ -1032,22 +1039,27 @@ void ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UE
|
|||
return;
|
||||
}
|
||||
|
||||
coll->reorderCodesLength = 0;
|
||||
if (coll->reorderCodes != NULL) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
}
|
||||
|
||||
if (parser->reorderCodesLength == 0 || parser->reorderCodes == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
coll->reorderCodesLength = 0;
|
||||
if (coll->reorderCodes != NULL && coll->freeReorderCodesOnClose == TRUE) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
}
|
||||
|
||||
if (coll->defaultReorderCodes != NULL && coll->freeDefaultReorderCodesOnClose == TRUE) {
|
||||
uprv_free(coll->defaultReorderCodes);
|
||||
}
|
||||
coll->defaultReorderCodesLength = parser->reorderCodesLength;
|
||||
coll->defaultReorderCodes = (int32_t*) uprv_malloc(coll->defaultReorderCodesLength * sizeof(int32_t));
|
||||
uprv_memcpy(coll->defaultReorderCodes, parser->reorderCodes, coll->defaultReorderCodesLength * sizeof(int32_t));
|
||||
coll->freeDefaultReorderCodesOnClose = TRUE;
|
||||
|
||||
coll->reorderCodesLength = parser->reorderCodesLength;
|
||||
coll->reorderCodes = (int32_t*) uprv_malloc(coll->reorderCodesLength * sizeof(int32_t));
|
||||
uprv_memcpy(coll->reorderCodes, parser->reorderCodes, coll->reorderCodesLength * sizeof(int32_t));
|
||||
coll->freeReorderCodesOnClose = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1063,7 +1075,8 @@ void ucol_setReorderCodesFromParser(UCollator *coll, UColTokenParser *parser, UE
|
|||
* - the data is an usigned short count followed by count number
|
||||
* of lead bytes stored in an unsigned short
|
||||
*/
|
||||
int ucol_getLeadBytesForReorderCode(const UCollator *uca, int reorderCode, uint16_t* returnLeadBytes, int returnCapacity) {
|
||||
U_CFUNC int U_EXPORT2
|
||||
ucol_getLeadBytesForReorderCode(const UCollator *uca, int reorderCode, uint16_t* returnLeadBytes, int returnCapacity) {
|
||||
uint16_t reorderCodeIndexLength = *((uint16_t*) ((uint8_t *)uca->image + uca->image->scriptToLeadByte));
|
||||
uint16_t* reorderCodeIndex = (uint16_t*) ((uint8_t *)uca->image + uca->image->scriptToLeadByte + 2 *sizeof(uint16_t));
|
||||
|
||||
|
@ -1100,7 +1113,8 @@ int ucol_getLeadBytesForReorderCode(const UCollator *uca, int reorderCode, uint1
|
|||
* data[data size] - array of unsigned short (2 bytes each entry)
|
||||
* - the data is an usigned short count followed by count number of reorder codes
|
||||
*/
|
||||
int ucol_getReorderCodesForLeadByte(const UCollator *uca, int leadByte, int16_t* returnReorderCodes, int returnCapacity) {
|
||||
U_CFUNC int U_EXPORT2
|
||||
ucol_getReorderCodesForLeadByte(const UCollator *uca, int leadByte, int16_t* returnReorderCodes, int returnCapacity) {
|
||||
uint16_t* leadByteTable = ((uint16_t*) ((uint8_t *)uca->image + uca->image->leadByteToScript));
|
||||
uint16_t leadByteIndexLength = *leadByteTable;
|
||||
if (leadByte >= leadByteIndexLength) {
|
||||
|
@ -1126,7 +1140,8 @@ int ucol_getReorderCodesForLeadByte(const UCollator *uca, int leadByte, int16_t*
|
|||
// used to mark ignorable reorder code slots
|
||||
static const int32_t UCOL_REORDER_CODE_IGNORE = UCOL_REORDER_CODE_LIMIT + 1;
|
||||
|
||||
void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
||||
U_CFUNC void U_EXPORT2
|
||||
ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
||||
uint16_t leadBytesSize = 256;
|
||||
uint16_t leadBytes[256];
|
||||
int32_t internalReorderCodesLength = coll->reorderCodesLength + (UCOL_REORDER_CODE_LIMIT - UCOL_REORDER_CODE_FIRST);
|
||||
|
@ -1155,7 +1170,9 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
if (coll->reorderCodes == NULL || coll->reorderCodesLength == 0
|
||||
|| (coll->reorderCodesLength == 1 && coll->reorderCodes[0] == UCOL_REORDER_CODE_NONE)) {
|
||||
if (coll->leadBytePermutationTable != NULL) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
if (coll->freeLeadBytePermutationTableOnClose) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
coll->reorderCodesLength = 0;
|
||||
}
|
||||
|
@ -1164,13 +1181,23 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
|
||||
// set reordering to the default reordering
|
||||
if (coll->reorderCodes[0] == UCOL_REORDER_CODE_DEFAULT) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
if (coll->freeReorderCodesOnClose == TRUE) {
|
||||
uprv_free(coll->reorderCodes);
|
||||
}
|
||||
coll->reorderCodes = NULL;
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
|
||||
if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
|
||||
if (coll->defaultReorderCodesLength == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
coll->reorderCodes = (int32_t*)uprv_malloc(coll->defaultReorderCodesLength * sizeof(int32_t));
|
||||
if (internalReorderCodes == NULL) {
|
||||
coll->freeReorderCodesOnClose = TRUE;
|
||||
if (coll->reorderCodes == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
@ -1180,6 +1207,7 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
|
||||
if (coll->leadBytePermutationTable == NULL) {
|
||||
coll->leadBytePermutationTable = (uint8_t*)uprv_malloc(256*sizeof(uint8_t));
|
||||
coll->freeLeadBytePermutationTableOnClose = TRUE;
|
||||
if (coll->leadBytePermutationTable == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
|
@ -1190,10 +1218,10 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
internalReorderCodes = (int32_t*)uprv_malloc(internalReorderCodesLength * sizeof(int32_t));
|
||||
if (internalReorderCodes == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
if (coll->leadBytePermutationTable != NULL) {
|
||||
if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1236,10 +1264,10 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
if (fromTheBottom == false) {
|
||||
// double turnaround
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
if (coll->leadBytePermutationTable != NULL) {
|
||||
if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
coll->reorderCodesLength = 0;
|
||||
if (internalReorderCodes != NULL) {
|
||||
uprv_free(internalReorderCodes);
|
||||
|
@ -1258,10 +1286,10 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
if (permutationSlotFilled[leadBytes[leadByteIndex]]) {
|
||||
// lead byte already used
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
if (coll->leadBytePermutationTable != NULL) {
|
||||
if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
coll->reorderCodesLength = 0;
|
||||
if (internalReorderCodes != NULL) {
|
||||
uprv_free(internalReorderCodes);
|
||||
|
@ -1280,10 +1308,10 @@ void ucol_buildPermutationTable(UCollator *coll, UErrorCode *status) {
|
|||
if (permutationSlotFilled[leadBytes[leadByteIndex]]) {
|
||||
// lead byte already used
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
if (coll->leadBytePermutationTable != NULL) {
|
||||
if (coll->leadBytePermutationTable != NULL && coll->freeLeadBytePermutationTableOnClose == TRUE) {
|
||||
uprv_free(coll->leadBytePermutationTable);
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
}
|
||||
coll->leadBytePermutationTable = NULL;
|
||||
coll->reorderCodesLength = 0;
|
||||
if (internalReorderCodes != NULL) {
|
||||
uprv_free(internalReorderCodes);
|
||||
|
|
|
@ -5992,6 +5992,7 @@ static void TestReorderingAPI(void)
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UCollator *myCollation;
|
||||
int32_t reorderCodes[3] = {USCRIPT_GREEK, USCRIPT_HAN, UCOL_REORDER_CODE_PUNCTUATION};
|
||||
int32_t duplicateReorderCodes[] = {USCRIPT_CUNEIFORM, USCRIPT_GREEK, UCOL_REORDER_CODE_CURRENCY, USCRIPT_EGYPTIAN_HIEROGLYPHS};
|
||||
UCollationResult collResult;
|
||||
int32_t retrievedReorderCodesLength;
|
||||
int32_t retrievedReorderCodes[10];
|
||||
|
@ -6069,6 +6070,13 @@ static void TestReorderingAPI(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* test for error condition on duplicate reorder codes */
|
||||
ucol_setReorderCodes(myCollation, duplicateReorderCodes, LEN(duplicateReorderCodes), &status);
|
||||
if (!U_FAILURE(status)) {
|
||||
log_err_status(status, "ERROR: setting duplicate reorder codes did not generate a failure");
|
||||
return;
|
||||
}
|
||||
|
||||
ucol_close(myCollation);
|
||||
}
|
||||
|
||||
|
@ -6102,7 +6110,6 @@ static void TestReorderingAPIWithRuleCreatedCollator(void)
|
|||
|
||||
/* get the reordering */
|
||||
retrievedReorderCodesLength = ucol_getReorderCodes(myCollation, retrievedReorderCodes, LEN(retrievedReorderCodes), &status);
|
||||
printf("retrievedReorderCodesLength = %d\n", retrievedReorderCodesLength);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err_status(status, "ERROR: getting reorder codes: %s\n", myErrorName(status));
|
||||
return;
|
||||
|
@ -6265,15 +6272,71 @@ static void TestEquivalentReorderingScripts() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void TestReorderingAcrossCloning()
|
||||
{
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UCollator *myCollation;
|
||||
int32_t reorderCodes[3] = {USCRIPT_GREEK, USCRIPT_HAN, UCOL_REORDER_CODE_PUNCTUATION};
|
||||
UCollator *clonedCollation;
|
||||
int32_t bufferSize;
|
||||
int32_t* buffer;
|
||||
int32_t retrievedReorderCodesLength;
|
||||
int32_t retrievedReorderCodes[10];
|
||||
int loopIndex;
|
||||
|
||||
log_verbose("Testing non-lead bytes in a sort key with and without reordering\n");
|
||||
|
||||
/* build collator tertiary */
|
||||
myCollation = ucol_open("", &status);
|
||||
ucol_setStrength(myCollation, UCOL_TERTIARY);
|
||||
if(U_FAILURE(status)) {
|
||||
log_err_status(status, "ERROR: in creation of collator: %s\n", myErrorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
/* set the reorderding */
|
||||
ucol_setReorderCodes(myCollation, reorderCodes, LEN(reorderCodes), &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err_status(status, "ERROR: setting reorder codes: %s\n", myErrorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
/* clone the collator */
|
||||
clonedCollation = ucol_safeClone(myCollation, NULL, &bufferSize, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err_status(status, "ERROR: cloning collator: %s\n", myErrorName(status));
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the reordering */
|
||||
retrievedReorderCodesLength = ucol_getReorderCodes(clonedCollation, retrievedReorderCodes, LEN(retrievedReorderCodes), &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err_status(status, "ERROR: getting reorder codes: %s\n", myErrorName(status));
|
||||
return;
|
||||
}
|
||||
if (retrievedReorderCodesLength != LEN(reorderCodes)) {
|
||||
log_err_status(status, "ERROR: retrieved reorder codes length was %d but should have been %d\n", retrievedReorderCodesLength, LEN(reorderCodes));
|
||||
return;
|
||||
}
|
||||
for (loopIndex = 0; loopIndex < retrievedReorderCodesLength; loopIndex++) {
|
||||
if (retrievedReorderCodes[loopIndex] != reorderCodes[loopIndex]) {
|
||||
log_err_status(status, "ERROR: retrieved reorder code doesn't match set reorder code at index %d\n", loopIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*uprv_free(buffer);*/
|
||||
ucol_close(myCollation);
|
||||
ucol_close(clonedCollation);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility function to test one collation reordering test case set.
|
||||
* @param testcases Array of test cases.
|
||||
* @param n_testcases Size of the array testcases.
|
||||
* @param str_rules Array of rules. These rules should be specifying the same rule in different formats.
|
||||
* @param n_rules Size of the array str_rules.
|
||||
* @param reorderTokens Array of reordering codes.
|
||||
* @param reorderTokensLen Size of the array reorderTokens.
|
||||
*/
|
||||
static void doTestOneReorderingAPITestCase(const OneTestCase testCases[], uint32_t testCasesLen, const int32_t reorderTokens[], int32_t reorderTokensLen)
|
||||
{
|
||||
|
@ -6643,10 +6706,8 @@ static void TestImportWithType(void)
|
|||
ucol_close(importvidecoll);
|
||||
ucol_close(vicoll);
|
||||
ucol_close(decoll);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* 'IV INTERNATIONAL SCIENTIFIC - PRACTICAL CONFERENCE "GEOPOLITICS, GEOECONOMICS AND INTERNATIONAL RELATIONS PROBLEMS" 22-23 June 2010, St. Petersburg, Russia' */
|
||||
static const UChar longUpperStr1[]= { /* 155 chars */
|
||||
0x49, 0x56, 0x20, 0x49, 0x4E, 0x54, 0x45, 0x52, 0x4E, 0x41, 0x54, 0x49, 0x4F, 0x4E, 0x41, 0x4C,
|
||||
|
@ -6841,6 +6902,8 @@ void addMiscCollTest(TestNode** root)
|
|||
TEST(TestNonScriptReorder);
|
||||
TEST(TestHaniReorder);
|
||||
TEST(TestMultipleReorder);
|
||||
TEST(TestReorderingAcrossCloning);
|
||||
|
||||
TEST(TestCaseLevelBufferOverflow);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue