• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ******************************************************************************
3 *   Copyright (C) 2001-2006, International Business Machines
4 *   Corporation and others.  All Rights Reserved.
5 ******************************************************************************
6 *
7 * File ucoleitr.cpp
8 *
9 * Modification History:
10 *
11 * Date        Name        Description
12 * 02/15/2001  synwee      Modified all methods to process its own function
13 *                         instead of calling the equivalent c++ api (coleitr.h)
14 ******************************************************************************/
15 
16 #include "unicode/utypes.h"
17 
18 #if !UCONFIG_NO_COLLATION
19 
20 #include "unicode/ucoleitr.h"
21 #include "unicode/ustring.h"
22 #include "unicode/sortkey.h"
23 #include "ucol_imp.h"
24 #include "cmemory.h"
25 
26 U_NAMESPACE_USE
27 
28 #define BUFFER_LENGTH             100
29 
30 typedef struct collIterate collIterator;
31 
32 /* public methods ---------------------------------------------------- */
33 
34 U_CAPI UCollationElements* U_EXPORT2
ucol_openElements(const UCollator * coll,const UChar * text,int32_t textLength,UErrorCode * status)35 ucol_openElements(const UCollator  *coll,
36                   const UChar      *text,
37                         int32_t    textLength,
38                         UErrorCode *status)
39 {
40   UCollationElements *result;
41 
42   if (U_FAILURE(*status)) {
43     return NULL;
44   }
45 
46   result = (UCollationElements *)uprv_malloc(sizeof(UCollationElements));
47   /* test for NULL */
48   if (result == NULL) {
49       *status = U_MEMORY_ALLOCATION_ERROR;
50       return NULL;
51   }
52 
53   result->reset_   = TRUE;
54   result->isWritable = FALSE;
55 
56   if (text == NULL) {
57       textLength = 0;
58   }
59   uprv_init_collIterate(coll, text, textLength, &result->iteratordata_);
60 
61   return result;
62 }
63 
64 U_CAPI void U_EXPORT2
ucol_closeElements(UCollationElements * elems)65 ucol_closeElements(UCollationElements *elems)
66 {
67   collIterate *ci = &elems->iteratordata_;
68   if (ci->writableBuffer != ci->stackWritableBuffer) {
69     uprv_free(ci->writableBuffer);
70   }
71   if (elems->isWritable && elems->iteratordata_.string != NULL)
72   {
73     uprv_free(elems->iteratordata_.string);
74   }
75   uprv_free(elems);
76 }
77 
78 U_CAPI void U_EXPORT2
ucol_reset(UCollationElements * elems)79 ucol_reset(UCollationElements *elems)
80 {
81   collIterate *ci = &(elems->iteratordata_);
82   elems->reset_   = TRUE;
83   ci->pos         = ci->string;
84   if ((ci->flags & UCOL_ITER_HASLEN) == 0 || ci->endp == NULL) {
85     ci->endp      = ci->string + u_strlen(ci->string);
86   }
87   ci->CEpos       = ci->toReturn = ci->CEs;
88   ci->flags       = UCOL_ITER_HASLEN;
89   if (ci->coll->normalizationMode == UCOL_ON) {
90     ci->flags |= UCOL_ITER_NORM;
91   }
92 
93   if (ci->stackWritableBuffer != ci->writableBuffer) {
94     uprv_free(ci->writableBuffer);
95     ci->writableBuffer = ci->stackWritableBuffer;
96     ci->writableBufSize = UCOL_WRITABLE_BUFFER_SIZE;
97   }
98   ci->fcdPosition = NULL;
99 }
100 
101 U_CAPI int32_t U_EXPORT2
ucol_next(UCollationElements * elems,UErrorCode * status)102 ucol_next(UCollationElements *elems,
103           UErrorCode         *status)
104 {
105   int32_t result;
106   if (U_FAILURE(*status)) {
107     return UCOL_NULLORDER;
108   }
109 
110   elems->reset_ = FALSE;
111 
112   result = (int32_t)ucol_getNextCE(elems->iteratordata_.coll,
113                                    &elems->iteratordata_,
114                                    status);
115 
116   if (result == UCOL_NO_MORE_CES) {
117     result = UCOL_NULLORDER;
118   }
119   return result;
120 }
121 
122 U_CAPI int32_t U_EXPORT2
ucol_previous(UCollationElements * elems,UErrorCode * status)123 ucol_previous(UCollationElements *elems,
124               UErrorCode         *status)
125 {
126   if(U_FAILURE(*status)) {
127     return UCOL_NULLORDER;
128   }
129   else
130   {
131     int32_t result;
132 
133     if (elems->reset_ &&
134         (elems->iteratordata_.pos == elems->iteratordata_.string)) {
135         if (elems->iteratordata_.endp == NULL) {
136             elems->iteratordata_.endp = elems->iteratordata_.string +
137                                         u_strlen(elems->iteratordata_.string);
138             elems->iteratordata_.flags |= UCOL_ITER_HASLEN;
139         }
140         elems->iteratordata_.pos = elems->iteratordata_.endp;
141         elems->iteratordata_.fcdPosition = elems->iteratordata_.endp;
142     }
143 
144     elems->reset_ = FALSE;
145 
146     result = (int32_t)ucol_getPrevCE(elems->iteratordata_.coll,
147                                      &(elems->iteratordata_),
148                                      status);
149 
150     if (result == UCOL_NO_MORE_CES) {
151       result = UCOL_NULLORDER;
152     }
153 
154     return result;
155   }
156 }
157 
158 U_CAPI int32_t U_EXPORT2
ucol_getMaxExpansion(const UCollationElements * elems,int32_t order)159 ucol_getMaxExpansion(const UCollationElements *elems,
160                            int32_t            order)
161 {
162   uint8_t result;
163   UCOL_GETMAXEXPANSION(elems->iteratordata_.coll, (uint32_t)order, result);
164   return result;
165 }
166 
167 U_CAPI void U_EXPORT2
ucol_setText(UCollationElements * elems,const UChar * text,int32_t textLength,UErrorCode * status)168 ucol_setText(      UCollationElements *elems,
169              const UChar              *text,
170                    int32_t            textLength,
171                    UErrorCode         *status)
172 {
173   if (U_FAILURE(*status)) {
174     return;
175   }
176 
177   if (elems->isWritable && elems->iteratordata_.string != NULL)
178   {
179     uprv_free(elems->iteratordata_.string);
180   }
181 
182   if (text == NULL) {
183       textLength = 0;
184   }
185 
186   elems->isWritable = FALSE;
187   uprv_init_collIterate(elems->iteratordata_.coll, text, textLength,
188                    &elems->iteratordata_);
189 
190   elems->reset_   = TRUE;
191 }
192 
193 U_CAPI int32_t U_EXPORT2
ucol_getOffset(const UCollationElements * elems)194 ucol_getOffset(const UCollationElements *elems)
195 {
196   const collIterate *ci = &(elems->iteratordata_);
197   // while processing characters in normalization buffer getOffset will
198   // return the next non-normalized character.
199   // should be inline with the old implementation since the old codes uses
200   // nextDecomp in normalizer which also decomposes the string till the
201   // first base character is found.
202   if (ci->flags & UCOL_ITER_INNORMBUF) {
203       if (ci->fcdPosition == NULL) {
204         return 0;
205       }
206       return (int32_t)(ci->fcdPosition - ci->string);
207   }
208   else {
209       return (int32_t)(ci->pos - ci->string);
210   }
211 }
212 
213 U_CAPI void U_EXPORT2
ucol_setOffset(UCollationElements * elems,int32_t offset,UErrorCode * status)214 ucol_setOffset(UCollationElements    *elems,
215                int32_t           offset,
216                UErrorCode            *status)
217 {
218   if (U_FAILURE(*status)) {
219     return;
220   }
221 
222   // this methods will clean up any use of the writable buffer and points to
223   // the original string
224   collIterate *ci = &(elems->iteratordata_);
225   ci->pos         = ci->string + offset;
226   ci->CEpos       = ci->toReturn = ci->CEs;
227   if (ci->flags & UCOL_ITER_INNORMBUF) {
228     ci->flags = ci->origFlags;
229   }
230   if ((ci->flags & UCOL_ITER_HASLEN) == 0) {
231       ci->endp  = ci->string + u_strlen(ci->string);
232       ci->flags |= UCOL_ITER_HASLEN;
233   }
234   ci->fcdPosition = NULL;
235   elems->reset_ = FALSE;
236 }
237 
238 U_CAPI int32_t U_EXPORT2
ucol_primaryOrder(int32_t order)239 ucol_primaryOrder (int32_t order)
240 {
241   order &= UCOL_PRIMARYMASK;
242   return (order >> UCOL_PRIMARYORDERSHIFT);
243 }
244 
245 U_CAPI int32_t U_EXPORT2
ucol_secondaryOrder(int32_t order)246 ucol_secondaryOrder (int32_t order)
247 {
248   order &= UCOL_SECONDARYMASK;
249   return (order >> UCOL_SECONDARYORDERSHIFT);
250 }
251 
252 U_CAPI int32_t U_EXPORT2
ucol_tertiaryOrder(int32_t order)253 ucol_tertiaryOrder (int32_t order)
254 {
255   return (order & UCOL_TERTIARYMASK);
256 }
257 
258 #endif /* #if !UCONFIG_NO_COLLATION */
259