16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2002-2011, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************* 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* file name: propsvec.c 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* encoding: US-ASCII 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* tab size: 8 (not used) 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* indentation:4 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created on: 2002feb22 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* created by: Markus W. Scherer 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Store bits (Unicode character properties) in bit set vectors. 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <stdlib.h> 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utrie.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utrie2.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uarrsort.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "propsvec.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstruct UPropsVectors { 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *v; 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t columns; /* number of columns, plus two for start & limit values */ 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t maxRows; 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t rows; 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevRow; /* search optimization: remember last row seen */ 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool isCompacted; 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UPVEC_INITIAL_ROWS (1<<12) 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UPVEC_MEDIUM_ROWS ((int32_t)1<<16) 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define UPVEC_MAX_ROWS (UPVEC_MAX_CP+1) 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UPropsVectors * U_EXPORT2 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_open(int32_t columns, UErrorCode *pErrorCode) { 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UPropsVectors *pv; 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *v, *row; 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t cp; 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(columns<1) { 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org columns+=2; /* count range start and limit columns */ 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv=(UPropsVectors *)uprv_malloc(sizeof(UPropsVectors)); 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org v=(uint32_t *)uprv_malloc(UPVEC_INITIAL_ROWS*columns*4); 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv==NULL || v==NULL) { 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pv); 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(v); 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(pv, 0, sizeof(UPropsVectors)); 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->v=v; 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->columns=columns; 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->maxRows=UPVEC_INITIAL_ROWS; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->rows=2+(UPVEC_MAX_CP-UPVEC_FIRST_SPECIAL_CP); 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the all-Unicode row and the special-value rows */ 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=pv->v; 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(row, 0, pv->rows*columns*4); 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row[0]=0; 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row[1]=0x110000; 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row+=columns; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(cp=UPVEC_FIRST_SPECIAL_CP; cp<=UPVEC_MAX_CP; ++cp) { 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row[0]=cp; 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row[1]=cp+1; 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row+=columns; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pv; 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_close(UPropsVectors *pv) { 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv!=NULL) { 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pv->v); 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pv); 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic uint32_t * 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org_findRow(UPropsVectors *pv, UChar32 rangeStart) { 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *row; 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t columns, i, start, limit, prevRow; 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org columns=pv->columns; 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=pv->rows; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevRow=pv->prevRow; 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* check the vicinity of the last-seen row (start searching with an unrolled loop) */ 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=pv->v+prevRow*columns; 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(rangeStart>=(UChar32)row[0]) { 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(rangeStart<(UChar32)row[1]) { 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* same row as last seen */ 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row; 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(rangeStart<(UChar32)(row+=columns)[1]) { 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* next row after the last one */ 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=prevRow+1; 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row; 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(rangeStart<(UChar32)(row+=columns)[1]) { 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* second row after the last one */ 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=prevRow+2; 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row; 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if((rangeStart-(UChar32)row[1])<10) { 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* we are close, continue looping */ 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevRow+=2; 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++prevRow; 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row+=columns; 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(rangeStart>=(UChar32)row[1]); 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=prevRow; 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row; 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(rangeStart<(UChar32)pv->v[1]) { 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* the very first row */ 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=0; 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pv->v; 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* do a binary search for the start of the range */ 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=0; 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(start<limit-1) { 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=(start+limit)/2; 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=pv->v+i*columns; 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(rangeStart<(UChar32)row[0]) { 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=i; 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(rangeStart<(UChar32)row[1]) { 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=i; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row; 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=i; 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* must be found because all ranges together always cover all of Unicode */ 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=start; 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pv->v+start*columns; 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_setValue(UPropsVectors *pv, 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 start, UChar32 end, 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t column, 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t value, uint32_t mask, 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *firstRow, *lastRow; 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t columns; 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 limit; 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool splitFirstRow, splitLastRow; 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* argument checking */ 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( pv==NULL || 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start<0 || start>end || end>UPVEC_MAX_CP || 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org column<0 || column>=(pv->columns-2) 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv->isCompacted) { 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_NO_WRITE_PERMISSION; 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=end+1; 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* initialize */ 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org columns=pv->columns; 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org column+=2; /* skip range start and limit columns */ 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org value&=mask; 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* find the rows whose ranges overlap with the input range */ 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* find the first and last rows, always successful */ 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstRow=_findRow(pv, start); 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow=_findRow(pv, end); 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Rows need to be split if they partially overlap with the 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * input range (only possible for the first and last rows) 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and if their value differs from the input value. 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org splitFirstRow= (UBool)(start!=(UChar32)firstRow[0] && value!=(firstRow[column]&mask)); 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org splitLastRow= (UBool)(limit!=(UChar32)lastRow[1] && value!=(lastRow[column]&mask)); 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* split first/last rows if necessary */ 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(splitFirstRow || splitLastRow) { 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count, rows; 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rows=pv->rows; 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((rows+splitFirstRow+splitLastRow)>pv->maxRows) { 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *newVectors; 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t newMaxRows; 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv->maxRows<UPVEC_MEDIUM_ROWS) { 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newMaxRows=UPVEC_MEDIUM_ROWS; 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(pv->maxRows<UPVEC_MAX_ROWS) { 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newMaxRows=UPVEC_MAX_ROWS; 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Implementation bug, or UPVEC_MAX_ROWS too low. */ 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newVectors=(uint32_t *)uprv_malloc(newMaxRows*columns*4); 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(newVectors==NULL) { 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(newVectors, pv->v, rows*columns*4); 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstRow=newVectors+(firstRow-pv->v); 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow=newVectors+(lastRow-pv->v); 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pv->v); 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->v=newVectors; 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->maxRows=newMaxRows; 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* count the number of row cells to move after the last row, and move them */ 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count = (int32_t)((pv->v+rows*columns)-(lastRow+columns)); 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(count>0) { 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove( 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow+(1+splitFirstRow+splitLastRow)*columns, 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow+columns, 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count*4); 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->rows=rows+splitFirstRow+splitLastRow; 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* split the first row, and move the firstRow pointer to the second part */ 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(splitFirstRow) { 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy all affected rows up one and move the lastRow pointer */ 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count = (int32_t)((lastRow-firstRow)+columns); 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(firstRow+columns, firstRow, count*4); 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow+=columns; 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* split the range and move the firstRow pointer */ 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstRow[1]=firstRow[columns]=(uint32_t)start; 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstRow+=columns; 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* split the last row */ 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(splitLastRow) { 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* copy the last row data */ 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(lastRow+columns, lastRow, columns*4); 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* split the range and move the firstRow pointer */ 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow[1]=lastRow[columns]=(uint32_t)limit; 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the "row last seen" to the last row for the range */ 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->prevRow=(int32_t)((lastRow-(pv->v))/columns); 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* set the input value in all remaining rows */ 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstRow+=column; 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org lastRow+=column; 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org mask=~mask; 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(;;) { 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *firstRow=(*firstRow&mask)|value; 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(firstRow==lastRow) { 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org firstRow+=columns; 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI uint32_t U_EXPORT2 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_getValue(const UPropsVectors *pv, UChar32 c, int32_t column) { 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *row; 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UPropsVectors *ncpv; 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv->isCompacted || c<0 || c>UPVEC_MAX_CP || column<0 || column>=(pv->columns-2)) { 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ncpv=(UPropsVectors *)pv; 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=_findRow(ncpv, c); 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row[2+column]; 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI uint32_t * U_EXPORT2 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_getRow(const UPropsVectors *pv, int32_t rowIndex, 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 *pRangeStart, UChar32 *pRangeEnd) { 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *row; 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t columns; 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv->isCompacted || rowIndex<0 || rowIndex>=pv->rows) { 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org columns=pv->columns; 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=pv->v+rowIndex*columns; 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pRangeStart!=NULL) { 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pRangeStart=(UChar32)row[0]; 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pRangeEnd!=NULL) { 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pRangeEnd=(UChar32)row[1]-1; 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return row+2; 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t U_CALLCONV 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_compareRows(const void *context, const void *l, const void *r) { 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const uint32_t *left=(const uint32_t *)l, *right=(const uint32_t *)r; 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UPropsVectors *pv=(const UPropsVectors *)context; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, count, columns; 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=columns=pv->columns; /* includes start/limit columns */ 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* start comparing after start/limit but wrap around to them */ 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=2; 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(left[i]!=right[i]) { 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return left[i]<right[i] ? -1 : 1; 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(++i==columns) { 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=0; 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(--count>0); 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_compact(UPropsVectors *pv, UPVecCompactHandler *handler, void *context, UErrorCode *pErrorCode) { 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *row; 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t i, columns, valueColumns, rows, count; 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 start, limit; 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* argument checking */ 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(handler==NULL) { 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pv->isCompacted) { 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Set the flag now: Sorting and compacting destroys the builder data structure. */ 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->isCompacted=TRUE; 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rows=pv->rows; 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org columns=pv->columns; 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(columns>=3); /* upvec_open asserts this */ 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org valueColumns=columns-2; /* not counting start & limit */ 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* sort the properties vectors to find unique vector values */ 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_sortArray(pv->v, rows, columns*4, 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org upvec_compareRows, pv, FALSE, pErrorCode); 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Find and set the special values. 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This has to do almost the same work as the compaction below, 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * to find the indexes where the special-value rows will move. 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=pv->v; 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=-valueColumns; 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<rows; ++i) { 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=(UChar32)row[0]; 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* count a new values vector if it is different from the current one */ 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(count<0 || 0!=uprv_memcmp(row+2, row-valueColumns, valueColumns*4)) { 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count+=valueColumns; 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start>=UPVEC_FIRST_SPECIAL_CP) { 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handler(context, start, start, count, row+2, valueColumns, pErrorCode); 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row+=columns; 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* count is at the beginning of the last vector, add valueColumns to include that last vector */ 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count+=valueColumns; 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* Call the handler once more to signal the start of delivering real values. */ 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handler(context, UPVEC_START_REAL_VALUES_CP, UPVEC_START_REAL_VALUES_CP, 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count, row-valueColumns, valueColumns, pErrorCode); 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Move vector contents up to a contiguous array with only unique 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * vector values, and call the handler function for each vector. 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * This destroys the Properties Vector structure and replaces it 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * with an array of just vector values. 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row=pv->v; 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count=-valueColumns; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(i=0; i<rows; ++i) { 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* fetch these first before memmove() may overwrite them */ 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start=(UChar32)row[0]; 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org limit=(UChar32)row[1]; 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* add a new values vector if it is different from the current one */ 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(count<0 || 0!=uprv_memcmp(row+2, pv->v+count, valueColumns*4)) { 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count+=valueColumns; 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memmove(pv->v+count, row+2, valueColumns*4); 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start<UPVEC_FIRST_SPECIAL_CP) { 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org handler(context, start, limit-1, count, pv->v+count, valueColumns, pErrorCode); 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org row+=columns; 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* count is at the beginning of the last vector, add one to include that last vector */ 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pv->rows=count/valueColumns+1; 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const uint32_t * U_EXPORT2 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_getArray(const UPropsVectors *pv, int32_t *pRows, int32_t *pColumns) { 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!pv->isCompacted) { 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pRows!=NULL) { 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pRows=pv->rows; 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pColumns!=NULL) { 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pColumns=pv->columns-2; 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pv->v; 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI uint32_t * U_EXPORT2 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_cloneArray(const UPropsVectors *pv, 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t *pRows, int32_t *pColumns, UErrorCode *pErrorCode) { 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uint32_t *clonedArray; 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t byteLength; 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!pv->isCompacted) { 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org byteLength=pv->rows*(pv->columns-2)*4; 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clonedArray=(uint32_t *)uprv_malloc(byteLength); 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(clonedArray==NULL) { 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(clonedArray, pv->v, byteLength); 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pRows!=NULL) { 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pRows=pv->rows; 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pColumns!=NULL) { 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pColumns=pv->columns-2; 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return clonedArray; 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI UTrie2 * U_EXPORT2 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_compactToUTrie2WithRowIndexes(UPropsVectors *pv, UErrorCode *pErrorCode) { 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UPVecToUTrie2Context toUTrie2={ NULL }; 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org upvec_compact(pv, upvec_compactToUTrie2Handler, &toUTrie2, pErrorCode); 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org utrie2_freeze(toUTrie2.trie, UTRIE2_16_VALUE_BITS, pErrorCode); 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(*pErrorCode)) { 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org utrie2_close(toUTrie2.trie); 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTrie2.trie=NULL; 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return toUTrie2.trie; 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * TODO(markus): Add upvec_16BitsToUTrie2() function that enumerates all rows, extracts 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * some 16-bit field and builds and returns a UTrie2. 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_CALLCONV 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgupvec_compactToUTrie2Handler(void *context, 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar32 start, UChar32 end, 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t rowIndex, uint32_t *row, int32_t columns, 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode *pErrorCode) { 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UPVecToUTrie2Context *toUTrie2=(UPVecToUTrie2Context *)context; 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(start<UPVEC_FIRST_SPECIAL_CP) { 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org utrie2_setRange32(toUTrie2->trie, start, end, (uint32_t)rowIndex, TRUE, pErrorCode); 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch(start) { 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UPVEC_INITIAL_VALUE_CP: 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTrie2->initialValue=rowIndex; 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UPVEC_ERROR_VALUE_CP: 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTrie2->errorValue=rowIndex; 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UPVEC_START_REAL_VALUES_CP: 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTrie2->maxValue=rowIndex; 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(rowIndex>0xffff) { 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* too many rows for a 16-bit trie */ 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTrie2->trie=utrie2_open(toUTrie2->initialValue, 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org toUTrie2->errorValue, pErrorCode); 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 526