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