2 ******************************************************************************
3 * Copyright (C) 2001-2006, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 ******************************************************************************
9 * Modification History:
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 ******************************************************************************/
16 #include "unicode/utypes.h"
18 #if !UCONFIG_NO_COLLATION
20 #include "unicode/ucoleitr.h"
21 #include "unicode/ustring.h"
22 #include "unicode/sortkey.h"
28 #define BUFFER_LENGTH 100
30 typedef struct collIterate collIterator
;
32 /* public methods ---------------------------------------------------- */
34 U_CAPI UCollationElements
* U_EXPORT2
35 ucol_openElements(const UCollator
*coll
,
40 UCollationElements
*result
;
42 if (U_FAILURE(*status
)) {
46 result
= (UCollationElements
*)uprv_malloc(sizeof(UCollationElements
));
49 *status
= U_MEMORY_ALLOCATION_ERROR
;
53 result
->reset_
= TRUE
;
54 result
->isWritable
= FALSE
;
59 uprv_init_collIterate(coll
, text
, textLength
, &result
->iteratordata_
);
65 ucol_closeElements(UCollationElements
*elems
)
67 collIterate
*ci
= &elems
->iteratordata_
;
68 if (ci
->writableBuffer
!= ci
->stackWritableBuffer
) {
69 uprv_free(ci
->writableBuffer
);
71 if (elems
->isWritable
&& elems
->iteratordata_
.string
!= NULL
)
73 uprv_free(elems
->iteratordata_
.string
);
79 ucol_reset(UCollationElements
*elems
)
81 collIterate
*ci
= &(elems
->iteratordata_
);
84 if ((ci
->flags
& UCOL_ITER_HASLEN
) == 0 || ci
->endp
== NULL
) {
85 ci
->endp
= ci
->string
+ u_strlen(ci
->string
);
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
;
93 if (ci
->stackWritableBuffer
!= ci
->writableBuffer
) {
94 uprv_free(ci
->writableBuffer
);
95 ci
->writableBuffer
= ci
->stackWritableBuffer
;
96 ci
->writableBufSize
= UCOL_WRITABLE_BUFFER_SIZE
;
98 ci
->fcdPosition
= NULL
;
101 U_CAPI
int32_t U_EXPORT2
102 ucol_next(UCollationElements
*elems
,
106 if (U_FAILURE(*status
)) {
107 return UCOL_NULLORDER
;
110 elems
->reset_
= FALSE
;
112 result
= (int32_t)ucol_getNextCE(elems
->iteratordata_
.coll
,
113 &elems
->iteratordata_
,
116 if (result
== UCOL_NO_MORE_CES
) {
117 result
= UCOL_NULLORDER
;
122 U_CAPI
int32_t U_EXPORT2
123 ucol_previous(UCollationElements
*elems
,
126 if(U_FAILURE(*status
)) {
127 return UCOL_NULLORDER
;
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
;
140 elems
->iteratordata_
.pos
= elems
->iteratordata_
.endp
;
141 elems
->iteratordata_
.fcdPosition
= elems
->iteratordata_
.endp
;
144 elems
->reset_
= FALSE
;
146 result
= (int32_t)ucol_getPrevCE(elems
->iteratordata_
.coll
,
147 &(elems
->iteratordata_
),
150 if (result
== UCOL_NO_MORE_CES
) {
151 result
= UCOL_NULLORDER
;
158 U_CAPI
int32_t U_EXPORT2
159 ucol_getMaxExpansion(const UCollationElements
*elems
,
163 UCOL_GETMAXEXPANSION(elems
->iteratordata_
.coll
, (uint32_t)order
, result
);
167 U_CAPI
void U_EXPORT2
168 ucol_setText( UCollationElements
*elems
,
173 if (U_FAILURE(*status
)) {
177 if (elems
->isWritable
&& elems
->iteratordata_
.string
!= NULL
)
179 uprv_free(elems
->iteratordata_
.string
);
186 elems
->isWritable
= FALSE
;
187 uprv_init_collIterate(elems
->iteratordata_
.coll
, text
, textLength
,
188 &elems
->iteratordata_
);
190 elems
->reset_
= TRUE
;
193 U_CAPI
int32_t U_EXPORT2
194 ucol_getOffset(const UCollationElements
*elems
)
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
) {
206 return (int32_t)(ci
->fcdPosition
- ci
->string
);
209 return (int32_t)(ci
->pos
- ci
->string
);
213 U_CAPI
void U_EXPORT2
214 ucol_setOffset(UCollationElements
*elems
,
218 if (U_FAILURE(*status
)) {
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
;
230 if ((ci
->flags
& UCOL_ITER_HASLEN
) == 0) {
231 ci
->endp
= ci
->string
+ u_strlen(ci
->string
);
232 ci
->flags
|= UCOL_ITER_HASLEN
;
234 ci
->fcdPosition
= NULL
;
235 elems
->reset_
= FALSE
;
238 U_CAPI
int32_t U_EXPORT2
239 ucol_primaryOrder (int32_t order
)
241 order
&= UCOL_PRIMARYMASK
;
242 return (order
>> UCOL_PRIMARYORDERSHIFT
);
245 U_CAPI
int32_t U_EXPORT2
246 ucol_secondaryOrder (int32_t order
)
248 order
&= UCOL_SECONDARYMASK
;
249 return (order
>> UCOL_SECONDARYORDERSHIFT
);
252 U_CAPI
int32_t U_EXPORT2
253 ucol_tertiaryOrder (int32_t order
)
255 return (order
& UCOL_TERTIARYMASK
);
258 #endif /* #if !UCONFIG_NO_COLLATION */