ICU-3858 turn upvec_toTrie() into more generic upvec_compact()

X-SVN-Rev: 17073
This commit is contained in:
Markus Scherer 2005-01-02 00:21:25 +00:00
parent 378a016021
commit 1f69d77027
2 changed files with 53 additions and 8 deletions

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2002-2004, International Business Machines
* Copyright (C) 2002-2005, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -277,16 +277,17 @@ upvec_compareRows(const void *context, const void *l, const void *r) {
}
U_CAPI int32_t U_EXPORT2
upvec_toTrie(uint32_t *pv, UNewTrie *trie, UErrorCode *pErrorCode) {
upvec_compact(uint32_t *pv, UPVecCompactHandler *handler, void *context, UErrorCode *pErrorCode) {
uint32_t *row;
int32_t columns, valueColumns, rows, count;
UChar32 start, limit;
/* argument checking */
if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
return 0;
}
if(pv==NULL || trie==NULL) {
if(pv==NULL || handler==NULL) {
*pErrorCode=U_ILLEGAL_ARGUMENT_ERROR;
return 0;
}
@ -295,6 +296,10 @@ upvec_toTrie(uint32_t *pv, UNewTrie *trie, UErrorCode *pErrorCode) {
columns=(int32_t)pv[UPVEC_COLUMNS];
rows=(int32_t)pv[UPVEC_ROWS];
if(rows==0) {
return 0;
}
/* sort the properties vectors to find unique vector values */
if(rows>1) {
uprv_sortArray(pv+UPVEC_HEADER_LENGTH, rows, columns*4,
@ -306,7 +311,7 @@ upvec_toTrie(uint32_t *pv, UNewTrie *trie, UErrorCode *pErrorCode) {
/*
* Move vector contents up to a contiguous array with only unique
* vector values, and set indexes to those values into the trie.
* vector values, and call the handler function for each vector.
*
* This destroys the Properties Vector structure and replaces it
* with an array of just vector values.
@ -315,19 +320,34 @@ upvec_toTrie(uint32_t *pv, UNewTrie *trie, UErrorCode *pErrorCode) {
count=-valueColumns;
do {
/* fetch these first before memmove() may overwrite them */
start=(UChar32)row[0];
limit=(UChar32)row[1];
/* add a new values vector if it is different from the current one */
if(count<0 || 0!=uprv_memcmp(row+2, pv+count, valueColumns*4)) {
count+=valueColumns;
uprv_memmove(pv+count, row+2, valueColumns*4);
}
if(count>0 && !utrie_setRange32(trie, (UChar32)row[0], (UChar32)row[1], (uint32_t)count, FALSE)) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
handler(context, start, limit, count, pv+count, valueColumns, pErrorCode);
if(U_FAILURE(*pErrorCode)) {
return 0;
}
row+=columns;
} while(--rows>0);
/* count is at the beginning of the last vector, add valueColumns to include that last vector */
return count+valueColumns;
}
U_CAPI void U_CALLCONV
upvec_compactToTrieHandler(void *context,
UChar32 start, UChar32 limit,
int32_t rowIndex, uint32_t *row, int32_t columns,
UErrorCode *pErrorCode) {
if(!utrie_setRange32((UNewTrie *)context, start, limit, (uint32_t)rowIndex, FALSE)) {
*pErrorCode=U_BUFFER_OVERFLOW_ERROR;
}
}

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 2002-2004, International Business Machines
* Copyright (C) 2002-2005, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -72,7 +72,32 @@ U_CAPI uint32_t * U_EXPORT2
upvec_getRow(uint32_t *pv, int32_t rowIndex,
UChar32 *pRangeStart, UChar32 *pRangeLimit);
/*
* Compact the vectors:
* - modify the memory
* - keep only unique vectors
* - store them contiguously from the beginning of the memory
* - for each (non-unique) row, call the handler function
*
* The handler's rowIndex is the uint32_t index of the row in the compacted
* memory block.
* (Therefore, it starts at 0 increases in increments of the columns value.)
*/
typedef void U_CALLCONV
UPVecCompactHandler(void *context,
UChar32 start, UChar32 limit,
int32_t rowIndex, uint32_t *row, int32_t columns,
UErrorCode *pErrorCode);
U_CAPI int32_t U_EXPORT2
upvec_toTrie(uint32_t *pv, UNewTrie *trie, UErrorCode *pErrorCode);
upvec_compact(uint32_t *pv, UPVecCompactHandler *handler, void *context, UErrorCode *pErrorCode);
/* context=UNewTrie, stores the rowIndex values into the trie */
U_CAPI void U_CALLCONV
upvec_compactToTrieHandler(void *context,
UChar32 start, UChar32 limit,
int32_t rowIndex, uint32_t *row, int32_t columns,
UErrorCode *pErrorCode);
#endif