1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/unorm_it.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,646 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* 1.7 +* Copyright (C) 2003-2011, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************* 1.11 +* file name: unorm_it.c 1.12 +* encoding: US-ASCII 1.13 +* tab size: 8 (not used) 1.14 +* indentation:4 1.15 +* 1.16 +* created on: 2003jan21 1.17 +* created by: Markus W. Scherer 1.18 +*/ 1.19 + 1.20 +#include "unicode/utypes.h" 1.21 + 1.22 +#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_NORMALIZATION 1.23 + 1.24 +#include "unicode/uiter.h" 1.25 +#include "unicode/unorm.h" 1.26 +#include "unicode/utf.h" 1.27 +#include "unorm_it.h" 1.28 +#include "cmemory.h" 1.29 + 1.30 +/* UNormIterator ------------------------------------------------------------ */ 1.31 + 1.32 +enum { 1.33 + INITIAL_CAPACITY=100 1.34 +}; 1.35 + 1.36 +struct UNormIterator { 1.37 + UCharIterator api; 1.38 + UCharIterator *iter; 1.39 + 1.40 + /* 1.41 + * chars and states either use the static buffers 1.42 + * or are allocated in the same memory block 1.43 + * 1.44 + * They are parallel arrays with states[] holding the getState() values 1.45 + * from normalization boundaries, and UITER_NO_STATE in between. 1.46 + */ 1.47 + UChar *chars; 1.48 + uint32_t *states; 1.49 + 1.50 + /* 1.51 + * api.start: first valid character & state in the arrays 1.52 + * api.index: current position 1.53 + * api.limit: one past the last valid character in chars[], but states[limit] is valid 1.54 + * capacity: length of allocated arrays 1.55 + */ 1.56 + int32_t capacity; 1.57 + 1.58 + /* the current iter->getState(), saved to avoid unnecessary setState() calls; may not correspond to api->index! */ 1.59 + uint32_t state; 1.60 + 1.61 + /* there are UChars available before start or after limit? */ 1.62 + UBool hasPrevious, hasNext, isStackAllocated; 1.63 + 1.64 + UNormalizationMode mode; 1.65 + 1.66 + UChar charsBuffer[INITIAL_CAPACITY]; 1.67 + uint32_t statesBuffer[INITIAL_CAPACITY+1]; /* one more than charsBuffer[]! */ 1.68 +}; 1.69 + 1.70 +static void 1.71 +initIndexes(UNormIterator *uni, UCharIterator *iter) { 1.72 + /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 1.73 + UCharIterator *api=&uni->api; 1.74 + 1.75 + if(!iter->hasPrevious(iter)) { 1.76 + /* set indexes to the beginning of the arrays */ 1.77 + api->start=api->index=api->limit=0; 1.78 + uni->hasPrevious=FALSE; 1.79 + uni->hasNext=iter->hasNext(iter); 1.80 + } else if(!iter->hasNext(iter)) { 1.81 + /* set indexes to the end of the arrays */ 1.82 + api->start=api->index=api->limit=uni->capacity; 1.83 + uni->hasNext=FALSE; 1.84 + uni->hasPrevious=iter->hasPrevious(iter); 1.85 + } else { 1.86 + /* set indexes into the middle of the arrays */ 1.87 + api->start=api->index=api->limit=uni->capacity/2; 1.88 + uni->hasPrevious=uni->hasNext=TRUE; 1.89 + } 1.90 +} 1.91 + 1.92 +static UBool 1.93 +reallocArrays(UNormIterator *uni, int32_t capacity, UBool addAtStart) { 1.94 + /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 1.95 + UCharIterator *api=&uni->api; 1.96 + 1.97 + uint32_t *states; 1.98 + UChar *chars; 1.99 + int32_t start, limit; 1.100 + 1.101 + states=(uint32_t *)uprv_malloc((capacity+1)*4+capacity*2); 1.102 + if(states==NULL) { 1.103 + return FALSE; 1.104 + } 1.105 + 1.106 + chars=(UChar *)(states+(capacity+1)); 1.107 + uni->capacity=capacity; 1.108 + 1.109 + start=api->start; 1.110 + limit=api->limit; 1.111 + 1.112 + if(addAtStart) { 1.113 + /* copy old contents to the end of the new arrays */ 1.114 + int32_t delta; 1.115 + 1.116 + delta=capacity-uni->capacity; 1.117 + uprv_memcpy(states+delta+start, uni->states+start, (limit-start+1)*4); 1.118 + uprv_memcpy(chars+delta+start, uni->chars+start, (limit-start)*4); 1.119 + 1.120 + api->start=start+delta; 1.121 + api->index+=delta; 1.122 + api->limit=limit+delta; 1.123 + } else { 1.124 + /* copy old contents to the beginning of the new arrays */ 1.125 + uprv_memcpy(states+start, uni->states+start, (limit-start+1)*4); 1.126 + uprv_memcpy(chars+start, uni->chars+start, (limit-start)*4); 1.127 + } 1.128 + 1.129 + uni->chars=chars; 1.130 + uni->states=states; 1.131 + 1.132 + return TRUE; 1.133 +} 1.134 + 1.135 +static void 1.136 +moveContentsTowardStart(UCharIterator *api, UChar chars[], uint32_t states[], int32_t delta) { 1.137 + /* move array contents up to make room */ 1.138 + int32_t srcIndex, destIndex, limit; 1.139 + 1.140 + limit=api->limit; 1.141 + srcIndex=delta; 1.142 + if(srcIndex>api->start) { 1.143 + /* look for a position in the arrays with a known state */ 1.144 + while(srcIndex<limit && states[srcIndex]==UITER_NO_STATE) { 1.145 + ++srcIndex; 1.146 + } 1.147 + } 1.148 + 1.149 + /* now actually move the array contents */ 1.150 + api->start=destIndex=0; 1.151 + while(srcIndex<limit) { 1.152 + chars[destIndex]=chars[srcIndex]; 1.153 + states[destIndex++]=states[srcIndex++]; 1.154 + } 1.155 + 1.156 + /* copy states[limit] as well! */ 1.157 + states[destIndex]=states[srcIndex]; 1.158 + 1.159 + api->limit=destIndex; 1.160 +} 1.161 + 1.162 +static void 1.163 +moveContentsTowardEnd(UCharIterator *api, UChar chars[], uint32_t states[], int32_t delta) { 1.164 + /* move array contents up to make room */ 1.165 + int32_t srcIndex, destIndex, start; 1.166 + 1.167 + start=api->start; 1.168 + destIndex=((UNormIterator *)api)->capacity; 1.169 + srcIndex=destIndex-delta; 1.170 + if(srcIndex<api->limit) { 1.171 + /* look for a position in the arrays with a known state */ 1.172 + while(srcIndex>start && states[srcIndex]==UITER_NO_STATE) { 1.173 + --srcIndex; 1.174 + } 1.175 + } 1.176 + 1.177 + /* now actually move the array contents */ 1.178 + api->limit=destIndex; 1.179 + 1.180 + /* copy states[limit] as well! */ 1.181 + states[destIndex]=states[srcIndex]; 1.182 + 1.183 + while(srcIndex>start) { 1.184 + chars[--destIndex]=chars[--srcIndex]; 1.185 + states[destIndex]=states[srcIndex]; 1.186 + } 1.187 + 1.188 + api->start=destIndex; 1.189 +} 1.190 + 1.191 +/* normalize forward from the limit, assume hasNext is true */ 1.192 +static UBool 1.193 +readNext(UNormIterator *uni, UCharIterator *iter) { 1.194 + /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 1.195 + UCharIterator *api=&uni->api; 1.196 + 1.197 + /* make capacity/4 room at the end of the arrays */ 1.198 + int32_t limit, capacity, room; 1.199 + UErrorCode errorCode; 1.200 + 1.201 + limit=api->limit; 1.202 + capacity=uni->capacity; 1.203 + room=capacity/4; 1.204 + if(room>(capacity-limit)) { 1.205 + /* move array contents to make room */ 1.206 + moveContentsTowardStart(api, uni->chars, uni->states, room); 1.207 + api->index=limit=api->limit; 1.208 + uni->hasPrevious=TRUE; 1.209 + } 1.210 + 1.211 + /* normalize starting from the limit position */ 1.212 + errorCode=U_ZERO_ERROR; 1.213 + if(uni->state!=uni->states[limit]) { 1.214 + uiter_setState(iter, uni->states[limit], &errorCode); 1.215 + if(U_FAILURE(errorCode)) { 1.216 + uni->state=UITER_NO_STATE; 1.217 + uni->hasNext=FALSE; 1.218 + return FALSE; 1.219 + } 1.220 + } 1.221 + 1.222 + room=unorm_next(iter, uni->chars+limit, capacity-limit, uni->mode, 0, TRUE, NULL, &errorCode); 1.223 + if(errorCode==U_BUFFER_OVERFLOW_ERROR) { 1.224 + if(room<=capacity) { 1.225 + /* empty and re-use the arrays */ 1.226 + uni->states[0]=uni->states[limit]; 1.227 + api->start=api->index=api->limit=limit=0; 1.228 + uni->hasPrevious=TRUE; 1.229 + } else { 1.230 + capacity+=room+100; 1.231 + if(!reallocArrays(uni, capacity, FALSE)) { 1.232 + uni->state=UITER_NO_STATE; 1.233 + uni->hasNext=FALSE; 1.234 + return FALSE; 1.235 + } 1.236 + limit=api->limit; 1.237 + } 1.238 + 1.239 + errorCode=U_ZERO_ERROR; 1.240 + uiter_setState(iter, uni->states[limit], &errorCode); 1.241 + room=unorm_next(iter, uni->chars+limit, capacity-limit, uni->mode, 0, TRUE, NULL, &errorCode); 1.242 + } 1.243 + if(U_FAILURE(errorCode) || room==0) { 1.244 + uni->state=UITER_NO_STATE; 1.245 + uni->hasNext=FALSE; 1.246 + return FALSE; 1.247 + } 1.248 + 1.249 + /* room>0 */ 1.250 + ++limit; /* leave the known states[limit] alone */ 1.251 + for(--room; room>0; --room) { 1.252 + /* set unknown states for all but the normalization boundaries */ 1.253 + uni->states[limit++]=UITER_NO_STATE; 1.254 + } 1.255 + uni->states[limit]=uni->state=uiter_getState(iter); 1.256 + uni->hasNext=iter->hasNext(iter); 1.257 + api->limit=limit; 1.258 + return TRUE; 1.259 +} 1.260 + 1.261 +/* normalize backward from the start, assume hasPrevious is true */ 1.262 +static UBool 1.263 +readPrevious(UNormIterator *uni, UCharIterator *iter) { 1.264 + /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 1.265 + UCharIterator *api=&uni->api; 1.266 + 1.267 + /* make capacity/4 room at the start of the arrays */ 1.268 + int32_t start, capacity, room; 1.269 + UErrorCode errorCode; 1.270 + 1.271 + start=api->start; 1.272 + capacity=uni->capacity; 1.273 + room=capacity/4; 1.274 + if(room>start) { 1.275 + /* move array contents to make room */ 1.276 + moveContentsTowardEnd(api, uni->chars, uni->states, room); 1.277 + api->index=start=api->start; 1.278 + uni->hasNext=TRUE; 1.279 + } 1.280 + 1.281 + /* normalize ending at the start position */ 1.282 + errorCode=U_ZERO_ERROR; 1.283 + if(uni->state!=uni->states[start]) { 1.284 + uiter_setState(iter, uni->states[start], &errorCode); 1.285 + if(U_FAILURE(errorCode)) { 1.286 + uni->state=UITER_NO_STATE; 1.287 + uni->hasPrevious=FALSE; 1.288 + return FALSE; 1.289 + } 1.290 + } 1.291 + 1.292 + room=unorm_previous(iter, uni->chars, start, uni->mode, 0, TRUE, NULL, &errorCode); 1.293 + if(errorCode==U_BUFFER_OVERFLOW_ERROR) { 1.294 + if(room<=capacity) { 1.295 + /* empty and re-use the arrays */ 1.296 + uni->states[capacity]=uni->states[start]; 1.297 + api->start=api->index=api->limit=start=capacity; 1.298 + uni->hasNext=TRUE; 1.299 + } else { 1.300 + capacity+=room+100; 1.301 + if(!reallocArrays(uni, capacity, TRUE)) { 1.302 + uni->state=UITER_NO_STATE; 1.303 + uni->hasPrevious=FALSE; 1.304 + return FALSE; 1.305 + } 1.306 + start=api->start; 1.307 + } 1.308 + 1.309 + errorCode=U_ZERO_ERROR; 1.310 + uiter_setState(iter, uni->states[start], &errorCode); 1.311 + room=unorm_previous(iter, uni->chars, start, uni->mode, 0, TRUE, NULL, &errorCode); 1.312 + } 1.313 + if(U_FAILURE(errorCode) || room==0) { 1.314 + uni->state=UITER_NO_STATE; 1.315 + uni->hasPrevious=FALSE; 1.316 + return FALSE; 1.317 + } 1.318 + 1.319 + /* room>0 */ 1.320 + do { 1.321 + /* copy the UChars from chars[0..room[ to chars[(start-room)..start[ */ 1.322 + uni->chars[--start]=uni->chars[--room]; 1.323 + /* set unknown states for all but the normalization boundaries */ 1.324 + uni->states[start]=UITER_NO_STATE; 1.325 + } while(room>0); 1.326 + uni->states[start]=uni->state=uiter_getState(iter); 1.327 + uni->hasPrevious=iter->hasPrevious(iter); 1.328 + api->start=start; 1.329 + return TRUE; 1.330 +} 1.331 + 1.332 +/* Iterator runtime API functions ------------------------------------------- */ 1.333 + 1.334 +static int32_t U_CALLCONV 1.335 +unormIteratorGetIndex(UCharIterator *api, UCharIteratorOrigin origin) { 1.336 + switch(origin) { 1.337 + case UITER_ZERO: 1.338 + case UITER_START: 1.339 + return 0; 1.340 + case UITER_CURRENT: 1.341 + case UITER_LIMIT: 1.342 + case UITER_LENGTH: 1.343 + return UITER_UNKNOWN_INDEX; 1.344 + default: 1.345 + /* not a valid origin */ 1.346 + /* Should never get here! */ 1.347 + return -1; 1.348 + } 1.349 +} 1.350 + 1.351 +static int32_t U_CALLCONV 1.352 +unormIteratorMove(UCharIterator *api, int32_t delta, UCharIteratorOrigin origin) { 1.353 + UNormIterator *uni=(UNormIterator *)api; 1.354 + UCharIterator *iter=uni->iter; 1.355 + int32_t pos; 1.356 + 1.357 + switch(origin) { 1.358 + case UITER_ZERO: 1.359 + case UITER_START: 1.360 + /* restart from the beginning */ 1.361 + if(uni->hasPrevious) { 1.362 + iter->move(iter, 0, UITER_START); 1.363 + api->start=api->index=api->limit=0; 1.364 + uni->states[api->limit]=uni->state=uiter_getState(iter); 1.365 + uni->hasPrevious=FALSE; 1.366 + uni->hasNext=iter->hasNext(iter); 1.367 + } else { 1.368 + /* we already have the beginning of the normalized text */ 1.369 + api->index=api->start; 1.370 + } 1.371 + break; 1.372 + case UITER_CURRENT: 1.373 + break; 1.374 + case UITER_LIMIT: 1.375 + case UITER_LENGTH: 1.376 + /* restart from the end */ 1.377 + if(uni->hasNext) { 1.378 + iter->move(iter, 0, UITER_LIMIT); 1.379 + api->start=api->index=api->limit=uni->capacity; 1.380 + uni->states[api->limit]=uni->state=uiter_getState(iter); 1.381 + uni->hasPrevious=iter->hasPrevious(iter); 1.382 + uni->hasNext=FALSE; 1.383 + } else { 1.384 + /* we already have the end of the normalized text */ 1.385 + api->index=api->limit; 1.386 + } 1.387 + break; 1.388 + default: 1.389 + return -1; /* Error */ 1.390 + } 1.391 + 1.392 + /* move relative to the current position by delta normalized UChars */ 1.393 + if(delta==0) { 1.394 + /* nothing to do */ 1.395 + } else if(delta>0) { 1.396 + /* go forward until the requested position is in the buffer */ 1.397 + for(;;) { 1.398 + pos=api->index+delta; /* requested position */ 1.399 + delta=pos-api->limit; /* remainder beyond buffered text */ 1.400 + if(delta<=0) { 1.401 + api->index=pos; /* position reached */ 1.402 + break; 1.403 + } 1.404 + 1.405 + /* go to end of buffer and normalize further */ 1.406 + api->index=api->limit; 1.407 + if(!uni->hasNext || !readNext(uni, iter)) { 1.408 + break; /* reached end of text */ 1.409 + } 1.410 + } 1.411 + } else /* delta<0 */ { 1.412 + /* go backward until the requested position is in the buffer */ 1.413 + for(;;) { 1.414 + pos=api->index+delta; /* requested position */ 1.415 + delta=pos-api->start; /* remainder beyond buffered text */ 1.416 + if(delta>=0) { 1.417 + api->index=pos; /* position reached */ 1.418 + break; 1.419 + } 1.420 + 1.421 + /* go to start of buffer and normalize further */ 1.422 + api->index=api->start; 1.423 + if(!uni->hasPrevious || !readPrevious(uni, iter)) { 1.424 + break; /* reached start of text */ 1.425 + } 1.426 + } 1.427 + } 1.428 + 1.429 + if(api->index==api->start && !uni->hasPrevious) { 1.430 + return 0; 1.431 + } else { 1.432 + return UITER_UNKNOWN_INDEX; 1.433 + } 1.434 +} 1.435 + 1.436 +static UBool U_CALLCONV 1.437 +unormIteratorHasNext(UCharIterator *api) { 1.438 + return api->index<api->limit || ((UNormIterator *)api)->hasNext; 1.439 +} 1.440 + 1.441 +static UBool U_CALLCONV 1.442 +unormIteratorHasPrevious(UCharIterator *api) { 1.443 + return api->index>api->start || ((UNormIterator *)api)->hasPrevious; 1.444 +} 1.445 + 1.446 +static UChar32 U_CALLCONV 1.447 +unormIteratorCurrent(UCharIterator *api) { 1.448 + UNormIterator *uni=(UNormIterator *)api; 1.449 + 1.450 + if( api->index<api->limit || 1.451 + (uni->hasNext && readNext(uni, uni->iter)) 1.452 + ) { 1.453 + return uni->chars[api->index]; 1.454 + } else { 1.455 + return U_SENTINEL; 1.456 + } 1.457 +} 1.458 + 1.459 +static UChar32 U_CALLCONV 1.460 +unormIteratorNext(UCharIterator *api) { 1.461 + UNormIterator *uni=(UNormIterator *)api; 1.462 + 1.463 + if( api->index<api->limit || 1.464 + (uni->hasNext && readNext(uni, uni->iter)) 1.465 + ) { 1.466 + return uni->chars[api->index++]; 1.467 + } else { 1.468 + return U_SENTINEL; 1.469 + } 1.470 +} 1.471 + 1.472 +static UChar32 U_CALLCONV 1.473 +unormIteratorPrevious(UCharIterator *api) { 1.474 + UNormIterator *uni=(UNormIterator *)api; 1.475 + 1.476 + if( api->index>api->start || 1.477 + (uni->hasPrevious && readPrevious(uni, uni->iter)) 1.478 + ) { 1.479 + return uni->chars[--api->index]; 1.480 + } else { 1.481 + return U_SENTINEL; 1.482 + } 1.483 +} 1.484 + 1.485 +static uint32_t U_CALLCONV 1.486 +unormIteratorGetState(const UCharIterator *api) { 1.487 + /* not uni->state because that may not be at api->index */ 1.488 + return ((UNormIterator *)api)->states[api->index]; 1.489 +} 1.490 + 1.491 +static void U_CALLCONV 1.492 +unormIteratorSetState(UCharIterator *api, uint32_t state, UErrorCode *pErrorCode) { 1.493 + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1.494 + /* do nothing */ 1.495 + } else if(api==NULL) { 1.496 + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1.497 + } else if(state==UITER_NO_STATE) { 1.498 + *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 1.499 + } else { 1.500 + UNormIterator *uni=(UNormIterator *)api; 1.501 + UCharIterator *iter=((UNormIterator *)api)->iter; 1.502 + if(state!=uni->state) { 1.503 + uni->state=state; 1.504 + uiter_setState(iter, state, pErrorCode); 1.505 + } 1.506 + 1.507 + /* 1.508 + * Try shortcuts: If the requested state is in the array contents 1.509 + * then just set the index there. 1.510 + * 1.511 + * We assume that the state is unique per position! 1.512 + */ 1.513 + if(state==uni->states[api->index]) { 1.514 + return; 1.515 + } else if(state==uni->states[api->limit]) { 1.516 + api->index=api->limit; 1.517 + return; 1.518 + } else { 1.519 + /* search for the index with this state */ 1.520 + int32_t i; 1.521 + 1.522 + for(i=api->start; i<api->limit; ++i) { 1.523 + if(state==uni->states[i]) { 1.524 + api->index=i; 1.525 + return; 1.526 + } 1.527 + } 1.528 + } 1.529 + 1.530 + /* there is no array index for this state, reset for fresh contents */ 1.531 + initIndexes((UNormIterator *)api, iter); 1.532 + uni->states[api->limit]=state; 1.533 + } 1.534 +} 1.535 + 1.536 +static const UCharIterator unormIterator={ 1.537 + NULL, 0, 0, 0, 0, 0, 1.538 + unormIteratorGetIndex, 1.539 + unormIteratorMove, 1.540 + unormIteratorHasNext, 1.541 + unormIteratorHasPrevious, 1.542 + unormIteratorCurrent, 1.543 + unormIteratorNext, 1.544 + unormIteratorPrevious, 1.545 + NULL, 1.546 + unormIteratorGetState, 1.547 + unormIteratorSetState 1.548 +}; 1.549 + 1.550 +/* Setup functions ---------------------------------------------------------- */ 1.551 + 1.552 +U_CAPI UNormIterator * U_EXPORT2 1.553 +unorm_openIter(void *stackMem, int32_t stackMemSize, UErrorCode *pErrorCode) { 1.554 + UNormIterator *uni; 1.555 + 1.556 + /* argument checking */ 1.557 + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1.558 + return NULL; 1.559 + } 1.560 + 1.561 + /* allocate */ 1.562 + uni=NULL; 1.563 + if(stackMem!=NULL && stackMemSize>=sizeof(UNormIterator)) { 1.564 + if(U_ALIGNMENT_OFFSET(stackMem)==0) { 1.565 + /* already aligned */ 1.566 + uni=(UNormIterator *)stackMem; 1.567 + } else { 1.568 + int32_t align=(int32_t)U_ALIGNMENT_OFFSET_UP(stackMem); 1.569 + if((stackMemSize-=align)>=(int32_t)sizeof(UNormIterator)) { 1.570 + /* needs alignment */ 1.571 + uni=(UNormIterator *)((char *)stackMem+align); 1.572 + } 1.573 + } 1.574 + /* else does not fit */ 1.575 + } 1.576 + 1.577 + if(uni!=NULL) { 1.578 + uni->isStackAllocated=TRUE; 1.579 + } else { 1.580 + uni=(UNormIterator *)uprv_malloc(sizeof(UNormIterator)); 1.581 + if(uni==NULL) { 1.582 + *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 1.583 + return NULL; 1.584 + } 1.585 + uni->isStackAllocated=FALSE; 1.586 + } 1.587 + 1.588 + /* 1.589 + * initialize 1.590 + * do not memset because that would unnecessarily initialize the arrays 1.591 + */ 1.592 + uni->iter=NULL; 1.593 + uni->chars=uni->charsBuffer; 1.594 + uni->states=uni->statesBuffer; 1.595 + uni->capacity=INITIAL_CAPACITY; 1.596 + uni->state=UITER_NO_STATE; 1.597 + uni->hasPrevious=uni->hasNext=FALSE; 1.598 + uni->mode=UNORM_NONE; 1.599 + 1.600 + /* set a no-op iterator into the api */ 1.601 + uiter_setString(&uni->api, NULL, 0); 1.602 + return uni; 1.603 +} 1.604 + 1.605 +U_CAPI void U_EXPORT2 1.606 +unorm_closeIter(UNormIterator *uni) { 1.607 + if(uni!=NULL) { 1.608 + if(uni->states!=uni->statesBuffer) { 1.609 + /* chars and states are allocated in the same memory block */ 1.610 + uprv_free(uni->states); 1.611 + } 1.612 + if(!uni->isStackAllocated) { 1.613 + uprv_free(uni); 1.614 + } 1.615 + } 1.616 +} 1.617 + 1.618 +U_CAPI UCharIterator * U_EXPORT2 1.619 +unorm_setIter(UNormIterator *uni, UCharIterator *iter, UNormalizationMode mode, UErrorCode *pErrorCode) { 1.620 + /* argument checking */ 1.621 + if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 1.622 + return NULL; 1.623 + } 1.624 + if(uni==NULL) { 1.625 + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1.626 + return NULL; 1.627 + } 1.628 + if( iter==NULL || iter->getState==NULL || iter->setState==NULL || 1.629 + mode<UNORM_NONE || UNORM_MODE_COUNT<=mode 1.630 + ) { 1.631 + /* set a no-op iterator into the api */ 1.632 + uiter_setString(&uni->api, NULL, 0); 1.633 + *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 1.634 + return NULL; 1.635 + } 1.636 + 1.637 + /* set the iterator and initialize */ 1.638 + uprv_memcpy(&uni->api, &unormIterator, sizeof(unormIterator)); 1.639 + 1.640 + uni->iter=iter; 1.641 + uni->mode=mode; 1.642 + 1.643 + initIndexes(uni, iter); 1.644 + uni->states[uni->api.limit]=uni->state=uiter_getState(iter); 1.645 + 1.646 + return &uni->api; 1.647 +} 1.648 + 1.649 +#endif /* uconfig.h switches */