1b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* 2b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru******************************************************************************* 3b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* 4b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* Copyright (C) 2002-2009, International Business Machines 5b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* Corporation and others. All Rights Reserved. 6b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* 7b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru******************************************************************************* 8b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* file name: propsvec.c 9b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* encoding: US-ASCII 10b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* tab size: 8 (not used) 11b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* indentation:4 12b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* 13b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* created on: 2002feb22 14b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* created by: Markus W. Scherer 15b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* 16b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru* Store bits (Unicode character properties) in bit set vectors. 17b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru*/ 18b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 19b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <stdlib.h> 20b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "unicode/utypes.h" 21b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "cmemory.h" 22b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "utrie.h" 23b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "utrie2.h" 24b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "uarrsort.h" 25b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include "propsvec.h" 26b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 27b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustruct UPropsVectors { 28b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *v; 29b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t columns; /* number of columns, plus two for start & limit values */ 30b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t maxRows; 31b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t rows; 32b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t prevRow; /* search optimization: remember last row seen */ 33b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool isCompacted; 34b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}; 35b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 36b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define UPVEC_INITIAL_ROWS (1<<12) 37b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define UPVEC_MEDIUM_ROWS ((int32_t)1<<16) 38b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define UPVEC_MAX_ROWS (UPVEC_MAX_CP+1) 39b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 40b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI UPropsVectors * U_EXPORT2 41b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_open(int32_t columns, UErrorCode *pErrorCode) { 42b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UPropsVectors *pv; 43b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *v, *row; 44b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t cp; 45b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(columns<1) { 50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 53b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru columns+=2; /* count range start and limit columns */ 54b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 55b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv=(UPropsVectors *)uprv_malloc(sizeof(UPropsVectors)); 56b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru v=(uint32_t *)uprv_malloc(UPVEC_INITIAL_ROWS*columns*4); 57b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv==NULL || v==NULL) { 58b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(pv); 59b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(v); 60b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 61b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 62b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 63b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memset(pv, 0, sizeof(UPropsVectors)); 64b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->v=v; 65b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->columns=columns; 66b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->maxRows=UPVEC_INITIAL_ROWS; 67b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->rows=2+(UPVEC_MAX_CP-UPVEC_FIRST_SPECIAL_CP); 68b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 69b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* set the all-Unicode row and the special-value rows */ 70b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row=pv->v; 71b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memset(row, 0, pv->rows*columns*4); 72b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row[0]=0; 73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row[1]=0x110000; 74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row+=columns; 75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for(cp=UPVEC_FIRST_SPECIAL_CP; cp<=UPVEC_MAX_CP; ++cp) { 76b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row[0]=cp; 77b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row[1]=cp+1; 78b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row+=columns; 79b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 80b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return pv; 81b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 82b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 83b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI void U_EXPORT2 84b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_close(UPropsVectors *pv) { 85b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv!=NULL) { 86b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(pv->v); 87b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(pv); 88b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 89b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 90b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 91b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic uint32_t * 92b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru_findRow(UPropsVectors *pv, UChar32 rangeStart) { 93b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *row; 94b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t columns, i, start, limit, prevRow, rows; 95b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 96b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru columns=pv->columns; 97b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rows=limit=pv->rows; 98b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru prevRow=pv->prevRow; 99b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 100b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* check the vicinity of the last-seen row (start searching with an unrolled loop) */ 101b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row=pv->v+prevRow*columns; 102b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(rangeStart>=(UChar32)row[0]) { 103b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(rangeStart<(UChar32)row[1]) { 104b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* same row as last seen */ 105b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row; 106b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(rangeStart<(UChar32)(row+=columns)[1]) { 107b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* next row after the last one */ 108b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=prevRow+1; 109b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row; 110b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(rangeStart<(UChar32)(row+=columns)[1]) { 111b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* second row after the last one */ 112b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=prevRow+2; 113b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row; 114b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if((rangeStart-(UChar32)row[1])<10) { 115b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* we are close, continue looping */ 116b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru prevRow+=2; 117b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru do { 118b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ++prevRow; 119b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row+=columns; 120b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } while(rangeStart>=(UChar32)row[1]); 121b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=prevRow; 122b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row; 123b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 124b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(rangeStart<(UChar32)pv->v[1]) { 125b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* the very first row */ 126b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=0; 127b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return pv->v; 128b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 129b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 130b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* do a binary search for the start of the range */ 131b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru start=0; 132b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru while(start<limit-1) { 133b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru i=(start+limit)/2; 134b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row=pv->v+i*columns; 135b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(rangeStart<(UChar32)row[0]) { 136b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru limit=i; 137b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(rangeStart<(UChar32)row[1]) { 138b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=i; 139b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row; 140b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 141b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru start=i; 142b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 143b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 144b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 145b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* must be found because all ranges together always cover all of Unicode */ 146b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=start; 147b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return pv->v+start*columns; 148b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 149b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 150b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI void U_EXPORT2 151b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_setValue(UPropsVectors *pv, 152b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 start, UChar32 end, 153b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t column, 154b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t value, uint32_t mask, 155b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode *pErrorCode) { 156b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *firstRow, *lastRow; 157b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t columns; 158b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 limit; 159b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UBool splitFirstRow, splitLastRow; 160b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 161b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* argument checking */ 162b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 163b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 164b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 165b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if( pv==NULL || 166b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru start<0 || start>end || end>UPVEC_MAX_CP || 167b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru column<0 || column>=(pv->columns-2) 168b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru ) { 169b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 170b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 171b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 172b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv->isCompacted) { 173b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_NO_WRITE_PERMISSION; 174b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 175b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 176b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru limit=end+1; 177b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 178b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* initialize */ 179b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru columns=pv->columns; 180b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru column+=2; /* skip range start and limit columns */ 181b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru value&=mask; 182b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 183b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* find the rows whose ranges overlap with the input range */ 184b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 185b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* find the first and last rows, always successful */ 186b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru firstRow=_findRow(pv, start); 187b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow=_findRow(pv, end); 188b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 189b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* 190b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Rows need to be split if they partially overlap with the 191b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * input range (only possible for the first and last rows) 192b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * and if their value differs from the input value. 193b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 194b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru splitFirstRow= (UBool)(start!=(UChar32)firstRow[0] && value!=(firstRow[column]&mask)); 195b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru splitLastRow= (UBool)(limit!=(UChar32)lastRow[1] && value!=(lastRow[column]&mask)); 196b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 197b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* split first/last rows if necessary */ 198b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(splitFirstRow || splitLastRow) { 199b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t count, rows; 200b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 201b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rows=pv->rows; 202b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if((rows+splitFirstRow+splitLastRow)>pv->maxRows) { 203b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *newVectors; 204b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t newMaxRows; 205b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 206b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv->maxRows<UPVEC_MEDIUM_ROWS) { 207b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru newMaxRows=UPVEC_MEDIUM_ROWS; 208b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else if(pv->maxRows<UPVEC_MAX_ROWS) { 209b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru newMaxRows=UPVEC_MAX_ROWS; 210b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 211b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Implementation bug, or UPVEC_MAX_ROWS too low. */ 212b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 213b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 214b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 215b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru newVectors=(uint32_t *)uprv_malloc(newMaxRows*columns*4); 216b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(newVectors==NULL) { 217b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 218b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 219b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 220b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memcpy(newVectors, pv->v, rows*columns*4); 221b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru firstRow=newVectors+(firstRow-pv->v); 222b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow=newVectors+(lastRow-pv->v); 223b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_free(pv->v); 224b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->v=newVectors; 225b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->maxRows=newMaxRows; 226b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 227b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 228b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* count the number of row cells to move after the last row, and move them */ 229b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count = (int32_t)((pv->v+rows*columns)-(lastRow+columns)); 230b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(count>0) { 231b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memmove( 232b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow+(1+splitFirstRow+splitLastRow)*columns, 233b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow+columns, 234b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count*4); 235b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 236b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->rows=rows+splitFirstRow+splitLastRow; 237b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 238b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* split the first row, and move the firstRow pointer to the second part */ 239b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(splitFirstRow) { 240b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* copy all affected rows up one and move the lastRow pointer */ 241b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count = (int32_t)((lastRow-firstRow)+columns); 242b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memmove(firstRow+columns, firstRow, count*4); 243b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow+=columns; 244b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 245b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* split the range and move the firstRow pointer */ 246b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru firstRow[1]=firstRow[columns]=(uint32_t)start; 247b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru firstRow+=columns; 248b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 249b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 250b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* split the last row */ 251b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(splitLastRow) { 252b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* copy the last row data */ 253b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memcpy(lastRow+columns, lastRow, columns*4); 254b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 255b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* split the range and move the firstRow pointer */ 256b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow[1]=lastRow[columns]=(uint32_t)limit; 257b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 258b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 259b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 260b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* set the "row last seen" to the last row for the range */ 261b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->prevRow=(int32_t)((lastRow-(pv->v))/columns); 262b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 263b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* set the input value in all remaining rows */ 264b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru firstRow+=column; 265b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru lastRow+=column; 266b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru mask=~mask; 267b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for(;;) { 268b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *firstRow=(*firstRow&mask)|value; 269b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(firstRow==lastRow) { 270b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 271b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 272b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru firstRow+=columns; 273b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 274b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 275b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 276b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI uint32_t U_EXPORT2 277b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_getValue(const UPropsVectors *pv, UChar32 c, int32_t column) { 278b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *row; 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UPropsVectors *ncpv; 280b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 281b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv->isCompacted || c<0 || c>UPVEC_MAX_CP || column<0 || column>=(pv->columns-2)) { 282b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 283b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ncpv=(UPropsVectors *)pv; 28550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho row=_findRow(ncpv, c); 286b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row[2+column]; 287b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 288b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 289b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI uint32_t * U_EXPORT2 290b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_getRow(const UPropsVectors *pv, int32_t rowIndex, 291b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 *pRangeStart, UChar32 *pRangeEnd) { 292b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *row; 293b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t columns; 294b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 295b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv->isCompacted || rowIndex<0 || rowIndex>=pv->rows) { 296b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 297b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 298b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 299b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru columns=pv->columns; 300b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row=pv->v+rowIndex*columns; 301b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pRangeStart!=NULL) { 302b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pRangeStart=(UChar32)row[0]; 303b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 304b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pRangeEnd!=NULL) { 305b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pRangeEnd=(UChar32)row[1]-1; 306b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 307b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return row+2; 308b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 309b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 310b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Querustatic int32_t U_CALLCONV 311b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_compareRows(const void *context, const void *l, const void *r) { 312b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const uint32_t *left=(const uint32_t *)l, *right=(const uint32_t *)r; 313b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru const UPropsVectors *pv=(const UPropsVectors *)context; 314b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t i, count, columns; 315b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 316b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count=columns=pv->columns; /* includes start/limit columns */ 317b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 318b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* start comparing after start/limit but wrap around to them */ 319b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru i=2; 320b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru do { 321b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(left[i]!=right[i]) { 322b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return left[i]<right[i] ? -1 : 1; 323b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 324b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(++i==columns) { 325b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru i=0; 326b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 327b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } while(--count>0); 328b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 329b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return 0; 330b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 331b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 332b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI void U_EXPORT2 333b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_compact(UPropsVectors *pv, UPVecCompactHandler *handler, void *context, UErrorCode *pErrorCode) { 334b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *row; 335b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t i, columns, valueColumns, rows, count; 336b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 start, limit; 337b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 338b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* argument checking */ 339b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 340b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 341b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 342b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(handler==NULL) { 343b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 344b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 345b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 346b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pv->isCompacted) { 347b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 348b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 349b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 350b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Set the flag now: Sorting and compacting destroys the builder data structure. */ 351b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->isCompacted=TRUE; 352b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 353b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru rows=pv->rows; 354b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru columns=pv->columns; 355b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru valueColumns=columns-2; /* not counting start & limit */ 356b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 357b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* sort the properties vectors to find unique vector values */ 358b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_sortArray(pv->v, rows, columns*4, 359b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru upvec_compareRows, pv, FALSE, pErrorCode); 360b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 361b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 362b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 363b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 364b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* 365b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Find and set the special values. 366b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * This has to do almost the same work as the compaction below, 367b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * to find the indexes where the special-value rows will move. 368b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 369b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row=pv->v; 370b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count=-valueColumns; 371b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for(i=0; i<rows; ++i) { 372b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru start=(UChar32)row[0]; 373b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 374b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* count a new values vector if it is different from the current one */ 375b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(count<0 || 0!=uprv_memcmp(row+2, row-valueColumns, valueColumns*4)) { 376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count+=valueColumns; 377b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 378b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 379b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(start>=UPVEC_FIRST_SPECIAL_CP) { 380b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru handler(context, start, start, count, row+2, valueColumns, pErrorCode); 381b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 382b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 383b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 384b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 385b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 386b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row+=columns; 387b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* count is at the beginning of the last vector, add valueColumns to include that last vector */ 390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count+=valueColumns; 391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* Call the handler once more to signal the start of delivering real values. */ 393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru handler(context, UPVEC_START_REAL_VALUES_CP, UPVEC_START_REAL_VALUES_CP, 394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count, row-valueColumns, valueColumns, pErrorCode); 395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* 400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * Move vector contents up to a contiguous array with only unique 401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * vector values, and call the handler function for each vector. 402b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * 403b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * This destroys the Properties Vector structure and replaces it 404b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * with an array of just vector values. 405b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 406b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row=pv->v; 407b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count=-valueColumns; 408b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru for(i=0; i<rows; ++i) { 409b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* fetch these first before memmove() may overwrite them */ 410b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru start=(UChar32)row[0]; 411b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru limit=(UChar32)row[1]; 412b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 413b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* add a new values vector if it is different from the current one */ 414b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(count<0 || 0!=uprv_memcmp(row+2, pv->v+count, valueColumns*4)) { 415b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru count+=valueColumns; 416b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memmove(pv->v+count, row+2, valueColumns*4); 417b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 418b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 419b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(start<UPVEC_FIRST_SPECIAL_CP) { 420b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru handler(context, start, limit-1, count, pv->v+count, valueColumns, pErrorCode); 421b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 422b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return; 423b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 424b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 425b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 426b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru row+=columns; 427b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 428b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 429b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* count is at the beginning of the last vector, add one to include that last vector */ 430b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru pv->rows=count/valueColumns+1; 431b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 432b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 433b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI const uint32_t * U_EXPORT2 434b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_getArray(const UPropsVectors *pv, int32_t *pRows, int32_t *pColumns) { 435b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(!pv->isCompacted) { 436b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 437b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 438b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pRows!=NULL) { 439b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pRows=pv->rows; 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 441b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pColumns!=NULL) { 442b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pColumns=pv->columns-2; 443b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 444b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return pv->v; 445b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 446b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 447b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI uint32_t * U_EXPORT2 448b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_cloneArray(const UPropsVectors *pv, 449b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t *pRows, int32_t *pColumns, UErrorCode *pErrorCode) { 450b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uint32_t *clonedArray; 451b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t byteLength; 452b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 453b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 454b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 455b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 456b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(!pv->isCompacted) { 457b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 458b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 459b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 460b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru byteLength=pv->rows*(pv->columns-2)*4; 461b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru clonedArray=(uint32_t *)uprv_malloc(byteLength); 462b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(clonedArray==NULL) { 463b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 464b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return NULL; 465b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 466b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru uprv_memcpy(clonedArray, pv->v, byteLength); 467b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pRows!=NULL) { 468b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pRows=pv->rows; 469b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 470b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(pColumns!=NULL) { 471b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pColumns=pv->columns-2; 472b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 473b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return clonedArray; 474b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 475b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 476b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI UTrie2 * U_EXPORT2 477b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_compactToUTrie2WithRowIndexes(UPropsVectors *pv, UErrorCode *pErrorCode) { 478b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UPVecToUTrie2Context toUTrie2={ NULL }; 479b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru upvec_compact(pv, upvec_compactToUTrie2Handler, &toUTrie2, pErrorCode); 480b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utrie2_freeze(toUTrie2.trie, UTRIE2_16_VALUE_BITS, pErrorCode); 481b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(U_FAILURE(*pErrorCode)) { 482b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utrie2_close(toUTrie2.trie); 483b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie2.trie=NULL; 484b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 485b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru return toUTrie2.trie; 486b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 487b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 488b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* 489b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * TODO(markus): Add upvec_16BitsToUTrie2() function that enumerates all rows, extracts 490b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru * some 16-bit field and builds and returns a UTrie2. 491b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru */ 492b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 493b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI void U_CALLCONV 494b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_compactToUTrieHandler(void *context, 495b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 start, UChar32 end, 496b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t rowIndex, uint32_t *row, int32_t columns, 497b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode *pErrorCode) { 498b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UPVecToUTrieContext *toUTrie=(UPVecToUTrieContext *)context; 499b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(start<UPVEC_FIRST_SPECIAL_CP) { 500b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(!utrie_setRange32(toUTrie->newTrie, start, end+1, (uint32_t)rowIndex, TRUE)) { 501b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_BUFFER_OVERFLOW_ERROR; 502b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 503b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 504b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru switch(start) { 505b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case UPVEC_INITIAL_VALUE_CP: 506b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie->initialValue=rowIndex; 507b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 508b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case UPVEC_START_REAL_VALUES_CP: 509b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(rowIndex>0xffff) { 510b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* too many rows for a 16-bit trie */ 511b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 512b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 513b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie->newTrie=utrie_open(NULL, NULL, toUTrie->capacity, 514b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie->initialValue, toUTrie->initialValue, 515b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie->latin1Linear); 516b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(toUTrie->newTrie==NULL) { 517b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 518b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 519b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 520b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 521b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru default: 522b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 523b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 524b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 525b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 526b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 527b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI void U_CALLCONV 528b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruupvec_compactToUTrie2Handler(void *context, 529b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UChar32 start, UChar32 end, 530b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru int32_t rowIndex, uint32_t *row, int32_t columns, 531b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UErrorCode *pErrorCode) { 532b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru UPVecToUTrie2Context *toUTrie2=(UPVecToUTrie2Context *)context; 533b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(start<UPVEC_FIRST_SPECIAL_CP) { 534b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru utrie2_setRange32(toUTrie2->trie, start, end, (uint32_t)rowIndex, TRUE, pErrorCode); 535b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 536b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru switch(start) { 537b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case UPVEC_INITIAL_VALUE_CP: 538b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie2->initialValue=rowIndex; 539b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 540b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case UPVEC_ERROR_VALUE_CP: 541b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie2->errorValue=rowIndex; 542b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 543b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru case UPVEC_START_REAL_VALUES_CP: 544b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie2->maxValue=rowIndex; 545b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru if(rowIndex>0xffff) { 546b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru /* too many rows for a 16-bit trie */ 547b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 548b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } else { 549b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie2->trie=utrie2_open(toUTrie2->initialValue, 550b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru toUTrie2->errorValue, pErrorCode); 551b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 552b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 553b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru default: 554b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru break; 555b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 556b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru } 557b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru} 558