1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius* Copyright (C) 2003-2011, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* file name: unorm_it.c 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* encoding: US-ASCII 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* tab size: 8 (not used) 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* indentation:4 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created on: 2003jan21 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* created by: Markus W. Scherer 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_NORMALIZATION 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uiter.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unorm.h" 2383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "unicode/utf.h" 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unorm_it.h" 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* UNormIterator ------------------------------------------------------------ */ 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru INITIAL_CAPACITY=100 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustruct UNormIterator { 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator api; 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *iter; 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * chars and states either use the static buffers 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * or are allocated in the same memory block 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * They are parallel arrays with states[] holding the getState() values 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * from normalization boundaries, and UITER_NO_STATE in between. 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *chars; 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t *states; 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * api.start: first valid character & state in the arrays 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * api.index: current position 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * api.limit: one past the last valid character in chars[], but states[limit] is valid 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * capacity: length of allocated arrays 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t capacity; 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* the current iter->getState(), saved to avoid unnecessary setState() calls; may not correspond to api->index! */ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t state; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there are UChars available before start or after limit? */ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool hasPrevious, hasNext, isStackAllocated; 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormalizationMode mode; 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar charsBuffer[INITIAL_CAPACITY]; 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t statesBuffer[INITIAL_CAPACITY+1]; /* one more than charsBuffer[]! */ 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruinitIndexes(UNormIterator *uni, UCharIterator *iter) { 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *api=&uni->api; 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!iter->hasPrevious(iter)) { 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set indexes to the beginning of the arrays */ 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=0; 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=FALSE; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=iter->hasNext(iter); 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(!iter->hasNext(iter)) { 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set indexes to the end of the arrays */ 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=uni->capacity; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=FALSE; 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=iter->hasPrevious(iter); 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set indexes into the middle of the arrays */ 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=uni->capacity/2; 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=uni->hasNext=TRUE; 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerureallocArrays(UNormIterator *uni, int32_t capacity, UBool addAtStart) { 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *api=&uni->api; 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t *states; 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar *chars; 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t start, limit; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru states=(uint32_t *)uprv_malloc((capacity+1)*4+capacity*2); 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(states==NULL) { 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru chars=(UChar *)(states+(capacity+1)); 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->capacity=capacity; 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start=api->start; 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit=api->limit; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(addAtStart) { 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy old contents to the end of the new arrays */ 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t delta; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delta=capacity-uni->capacity; 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(states+delta+start, uni->states+start, (limit-start+1)*4); 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(chars+delta+start, uni->chars+start, (limit-start)*4); 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=start+delta; 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index+=delta; 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->limit=limit+delta; 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy old contents to the beginning of the new arrays */ 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(states+start, uni->states+start, (limit-start+1)*4); 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(chars+start, uni->chars+start, (limit-start)*4); 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->chars=chars; 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states=states; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerumoveContentsTowardStart(UCharIterator *api, UChar chars[], uint32_t states[], int32_t delta) { 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move array contents up to make room */ 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t srcIndex, destIndex, limit; 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit=api->limit; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcIndex=delta; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcIndex>api->start) { 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* look for a position in the arrays with a known state */ 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(srcIndex<limit && states[srcIndex]==UITER_NO_STATE) { 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++srcIndex; 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* now actually move the array contents */ 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=destIndex=0; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(srcIndex<limit) { 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru chars[destIndex]=chars[srcIndex]; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru states[destIndex++]=states[srcIndex++]; 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy states[limit] as well! */ 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru states[destIndex]=states[srcIndex]; 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->limit=destIndex; 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerumoveContentsTowardEnd(UCharIterator *api, UChar chars[], uint32_t states[], int32_t delta) { 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move array contents up to make room */ 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t srcIndex, destIndex, start; 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start=api->start; 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru destIndex=((UNormIterator *)api)->capacity; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru srcIndex=destIndex-delta; 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(srcIndex<api->limit) { 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* look for a position in the arrays with a known state */ 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(srcIndex>start && states[srcIndex]==UITER_NO_STATE) { 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru --srcIndex; 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* now actually move the array contents */ 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->limit=destIndex; 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy states[limit] as well! */ 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru states[destIndex]=states[srcIndex]; 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while(srcIndex>start) { 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru chars[--destIndex]=chars[--srcIndex]; 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru states[destIndex]=states[srcIndex]; 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=destIndex; 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* normalize forward from the limit, assume hasNext is true */ 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerureadNext(UNormIterator *uni, UCharIterator *iter) { 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *api=&uni->api; 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* make capacity/4 room at the end of the arrays */ 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t limit, capacity, room; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode; 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit=api->limit; 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru capacity=uni->capacity; 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru room=capacity/4; 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(room>(capacity-limit)) { 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move array contents to make room */ 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru moveContentsTowardStart(api, uni->chars, uni->states, room); 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=limit=api->limit; 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=TRUE; 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* normalize starting from the limit position */ 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni->state!=uni->states[limit]) { 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setState(iter, uni->states[limit], &errorCode); 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=FALSE; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru room=unorm_next(iter, uni->chars+limit, capacity-limit, uni->mode, 0, TRUE, NULL, &errorCode); 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(errorCode==U_BUFFER_OVERFLOW_ERROR) { 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(room<=capacity) { 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* empty and re-use the arrays */ 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[0]=uni->states[limit]; 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=limit=0; 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=TRUE; 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru capacity+=room+100; 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!reallocArrays(uni, capacity, FALSE)) { 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=FALSE; 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit=api->limit; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setState(iter, uni->states[limit], &errorCode); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru room=unorm_next(iter, uni->chars+limit, capacity-limit, uni->mode, 0, TRUE, NULL, &errorCode); 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode) || room==0) { 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=FALSE; 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* room>0 */ 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++limit; /* leave the known states[limit] alone */ 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(--room; room>0; --room) { 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set unknown states for all but the normalization boundaries */ 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[limit++]=UITER_NO_STATE; 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[limit]=uni->state=uiter_getState(iter); 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=iter->hasNext(iter); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->limit=limit; 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* normalize backward from the start, assume hasPrevious is true */ 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QuerureadPrevious(UNormIterator *uni, UCharIterator *iter) { 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do not pass api so that the compiler knows it's an alias pointer to uni itself */ 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *api=&uni->api; 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* make capacity/4 room at the start of the arrays */ 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t start, capacity, room; 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode errorCode; 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start=api->start; 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru capacity=uni->capacity; 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru room=capacity/4; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(room>start) { 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move array contents to make room */ 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru moveContentsTowardEnd(api, uni->chars, uni->states, room); 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=start=api->start; 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=TRUE; 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* normalize ending at the start position */ 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni->state!=uni->states[start]) { 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setState(iter, uni->states[start], &errorCode); 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode)) { 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=FALSE; 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru room=unorm_previous(iter, uni->chars, start, uni->mode, 0, TRUE, NULL, &errorCode); 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(errorCode==U_BUFFER_OVERFLOW_ERROR) { 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(room<=capacity) { 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* empty and re-use the arrays */ 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[capacity]=uni->states[start]; 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=start=capacity; 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=TRUE; 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru capacity+=room+100; 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!reallocArrays(uni, capacity, TRUE)) { 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=FALSE; 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start=api->start; 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru errorCode=U_ZERO_ERROR; 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setState(iter, uni->states[start], &errorCode); 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru room=unorm_previous(iter, uni->chars, start, uni->mode, 0, TRUE, NULL, &errorCode); 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(errorCode) || room==0) { 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=FALSE; 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* room>0 */ 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* copy the UChars from chars[0..room[ to chars[(start-room)..start[ */ 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->chars[--start]=uni->chars[--room]; 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set unknown states for all but the normalization boundaries */ 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[start]=UITER_NO_STATE; 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } while(room>0); 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[start]=uni->state=uiter_getState(iter); 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=iter->hasPrevious(iter); 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=start; 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Iterator runtime API functions ------------------------------------------- */ 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorGetIndex(UCharIterator *api, UCharIteratorOrigin origin) { 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(origin) { 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_ZERO: 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_START: 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_CURRENT: 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_LIMIT: 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_LENGTH: 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UITER_UNKNOWN_INDEX; 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* not a valid origin */ 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* Should never get here! */ 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t U_CALLCONV 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorMove(UCharIterator *api, int32_t delta, UCharIteratorOrigin origin) { 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormIterator *uni=(UNormIterator *)api; 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *iter=uni->iter; 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t pos; 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch(origin) { 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_ZERO: 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_START: 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restart from the beginning */ 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni->hasPrevious) { 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru iter->move(iter, 0, UITER_START); 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=0; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[api->limit]=uni->state=uiter_getState(iter); 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=FALSE; 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=iter->hasNext(iter); 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* we already have the beginning of the normalized text */ 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=api->start; 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_CURRENT: 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_LIMIT: 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case UITER_LENGTH: 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* restart from the end */ 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni->hasNext) { 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru iter->move(iter, 0, UITER_LIMIT); 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->start=api->index=api->limit=uni->capacity; 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[api->limit]=uni->state=uiter_getState(iter); 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=iter->hasPrevious(iter); 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasNext=FALSE; 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* we already have the end of the normalized text */ 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=api->limit; 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; /* Error */ 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* move relative to the current position by delta normalized UChars */ 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(delta==0) { 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* nothing to do */ 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(delta>0) { 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* go forward until the requested position is in the buffer */ 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos=api->index+delta; /* requested position */ 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delta=pos-api->limit; /* remainder beyond buffered text */ 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(delta<=0) { 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=pos; /* position reached */ 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* go to end of buffer and normalize further */ 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=api->limit; 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!uni->hasNext || !readNext(uni, iter)) { 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* reached end of text */ 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else /* delta<0 */ { 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* go backward until the requested position is in the buffer */ 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(;;) { 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pos=api->index+delta; /* requested position */ 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delta=pos-api->start; /* remainder beyond buffered text */ 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(delta>=0) { 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=pos; /* position reached */ 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* go to start of buffer and normalize further */ 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=api->start; 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!uni->hasPrevious || !readPrevious(uni, iter)) { 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; /* reached start of text */ 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(api->index==api->start && !uni->hasPrevious) { 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return UITER_UNKNOWN_INDEX; 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorHasNext(UCharIterator *api) { 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return api->index<api->limit || ((UNormIterator *)api)->hasNext; 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool U_CALLCONV 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorHasPrevious(UCharIterator *api) { 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return api->index>api->start || ((UNormIterator *)api)->hasPrevious; 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UChar32 U_CALLCONV 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorCurrent(UCharIterator *api) { 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormIterator *uni=(UNormIterator *)api; 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( api->index<api->limit || 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uni->hasNext && readNext(uni, uni->iter)) 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return uni->chars[api->index]; 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return U_SENTINEL; 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UChar32 U_CALLCONV 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorNext(UCharIterator *api) { 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormIterator *uni=(UNormIterator *)api; 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( api->index<api->limit || 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uni->hasNext && readNext(uni, uni->iter)) 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return uni->chars[api->index++]; 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return U_SENTINEL; 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UChar32 U_CALLCONV 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorPrevious(UCharIterator *api) { 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormIterator *uni=(UNormIterator *)api; 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( api->index>api->start || 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uni->hasPrevious && readPrevious(uni, uni->iter)) 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return uni->chars[--api->index]; 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return U_SENTINEL; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic uint32_t U_CALLCONV 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorGetState(const UCharIterator *api) { 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* not uni->state because that may not be at api->index */ 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return ((UNormIterator *)api)->states[api->index]; 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void U_CALLCONV 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruunormIteratorSetState(UCharIterator *api, uint32_t state, UErrorCode *pErrorCode) { 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* do nothing */ 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(api==NULL) { 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(state==UITER_NO_STATE) { 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormIterator *uni=(UNormIterator *)api; 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UCharIterator *iter=((UNormIterator *)api)->iter; 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(state!=uni->state) { 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=state; 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setState(iter, state, pErrorCode); 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Try shortcuts: If the requested state is in the array contents 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * then just set the index there. 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * We assume that the state is unique per position! 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(state==uni->states[api->index]) { 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if(state==uni->states[api->limit]) { 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=api->limit; 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* search for the index with this state */ 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t i; 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for(i=api->start; i<api->limit; ++i) { 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(state==uni->states[i]) { 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru api->index=i; 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* there is no array index for this state, reset for fresh contents */ 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initIndexes((UNormIterator *)api, iter); 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[api->limit]=state; 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UCharIterator unormIterator={ 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 0, 0, 0, 0, 0, 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorGetIndex, 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorMove, 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorHasNext, 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorHasPrevious, 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorCurrent, 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorNext, 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorPrevious, 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorGetState, 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru unormIteratorSetState 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* Setup functions ---------------------------------------------------------- */ 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UNormIterator * U_EXPORT2 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruunorm_openIter(void *stackMem, int32_t stackMemSize, UErrorCode *pErrorCode) { 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UNormIterator *uni; 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* argument checking */ 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allocate */ 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni=NULL; 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(stackMem!=NULL && stackMemSize>=sizeof(UNormIterator)) { 56185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if(U_ALIGNMENT_OFFSET(stackMem)==0) { 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* already aligned */ 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni=(UNormIterator *)stackMem; 56485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 56585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t align=(int32_t)U_ALIGNMENT_OFFSET_UP(stackMem); 56685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if((stackMemSize-=align)>=(int32_t)sizeof(UNormIterator)) { 56785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho /* needs alignment */ 56885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho uni=(UNormIterator *)((char *)stackMem+align); 56985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* else does not fit */ 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni!=NULL) { 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->isStackAllocated=TRUE; 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni=(UNormIterator *)uprv_malloc(sizeof(UNormIterator)); 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni==NULL) { 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_MEMORY_ALLOCATION_ERROR; 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->isStackAllocated=FALSE; 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * initialize 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * do not memset because that would unnecessarily initialize the arrays 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->iter=NULL; 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->chars=uni->charsBuffer; 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states=uni->statesBuffer; 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->capacity=INITIAL_CAPACITY; 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->state=UITER_NO_STATE; 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->hasPrevious=uni->hasNext=FALSE; 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->mode=UNORM_NONE; 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set a no-op iterator into the api */ 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setString(&uni->api, NULL, 0); 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return uni; 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruunorm_closeIter(UNormIterator *uni) { 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni!=NULL) { 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni->states!=uni->statesBuffer) { 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* chars and states are allocated in the same memory block */ 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(uni->states); 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!uni->isStackAllocated) { 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(uni); 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI UCharIterator * U_EXPORT2 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruunorm_setIter(UNormIterator *uni, UCharIterator *iter, UNormalizationMode mode, UErrorCode *pErrorCode) { 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* argument checking */ 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(uni==NULL) { 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if( iter==NULL || iter->getState==NULL || iter->setState==NULL || 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mode<UNORM_NONE || UNORM_MODE_COUNT<=mode 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ) { 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set a no-op iterator into the api */ 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uiter_setString(&uni->api, NULL, 0); 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* set the iterator and initialize */ 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(&uni->api, &unormIterator, sizeof(unormIterator)); 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->iter=iter; 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->mode=mode; 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initIndexes(uni, iter); 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uni->states[uni->api.limit]=uni->state=uiter_getState(iter); 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return &uni->api; 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* uconfig.h switches */ 647