1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho*   Copyright (C) 2001-2011, International Business Machines
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File ucoleitr.cpp
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History:
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date        Name        Description
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/15/2001  synwee      Modified all methods to process its own function
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*                         instead of calling the equivalent c++ api (coleitr.h)
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************/
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ucoleitr.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/sortkey.h"
23c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "unicode/uobject.h"
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucol_imp.h"
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_USE
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define BUFFER_LENGTH             100
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
31c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define DEFAULT_BUFFER_SIZE 16
32c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define BUFFER_GROW 8
33c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
34c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
35c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
36c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define ARRAY_COPY(dst, src, count) uprv_memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0])
37c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
38c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define NEW_ARRAY(type, count) (type *) uprv_malloc((count) * sizeof(type))
39c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
40c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define GROW_ARRAY(array, newSize) uprv_realloc((void *) (array), (newSize) * sizeof (array)[0])
41c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
42c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#define DELETE_ARRAY(array) uprv_free((void *) (array))
43c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
4483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Corneliustypedef struct icu::collIterate collIterator;
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
46c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct RCEI
47c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
48c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uint32_t ce;
49c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t  low;
50c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t  high;
51c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru};
52c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
53c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_NAMESPACE_BEGIN
54c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
55c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct RCEBuffer
56c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
57c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    RCEI    defaultBuffer[DEFAULT_BUFFER_SIZE];
58c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    RCEI   *buffer;
59c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t bufferIndex;
60c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t bufferSize;
61c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
62c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    RCEBuffer();
63c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ~RCEBuffer();
64c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
65c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool empty() const;
66c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    void  put(uint32_t ce, int32_t ixLow, int32_t ixHigh);
67c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const RCEI *get();
68c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru};
69c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
70c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruRCEBuffer::RCEBuffer()
71c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
72c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer = defaultBuffer;
73c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferIndex = 0;
74c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferSize = DEFAULT_BUFFER_SIZE;
75c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
76c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
77c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruRCEBuffer::~RCEBuffer()
78c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
79c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (buffer != defaultBuffer) {
80c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        DELETE_ARRAY(buffer);
81c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
82c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
83c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
84c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUBool RCEBuffer::empty() const
85c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
86c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return bufferIndex <= 0;
87c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
88c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
89c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid RCEBuffer::put(uint32_t ce, int32_t ixLow, int32_t ixHigh)
90c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
91c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (bufferIndex >= bufferSize) {
92c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        RCEI *newBuffer = NEW_ARRAY(RCEI, bufferSize + BUFFER_GROW);
93c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
94c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ARRAY_COPY(newBuffer, buffer, bufferSize);
95c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
96c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (buffer != defaultBuffer) {
97c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            DELETE_ARRAY(buffer);
98c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
99c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
100c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        buffer = newBuffer;
101c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        bufferSize += BUFFER_GROW;
102c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
103c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
104c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer[bufferIndex].ce   = ce;
105c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer[bufferIndex].low  = ixLow;
106c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer[bufferIndex].high = ixHigh;
107c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
108c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferIndex += 1;
109c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
110c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
111c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruconst RCEI *RCEBuffer::get()
112c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
113c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (bufferIndex > 0) {
114c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru     return &buffer[--bufferIndex];
115c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
116c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
117c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return NULL;
118c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
119c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
120c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct PCEI
121c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
122c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uint64_t ce;
123c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t  low;
124c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t  high;
125c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru};
126c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
127c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct PCEBuffer
128c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
129c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    PCEI    defaultBuffer[DEFAULT_BUFFER_SIZE];
130c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    PCEI   *buffer;
131c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t bufferIndex;
132c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t bufferSize;
133c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
134c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    PCEBuffer();
135c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ~PCEBuffer();
136c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
137c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    void  reset();
138c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool empty() const;
139c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    void  put(uint64_t ce, int32_t ixLow, int32_t ixHigh);
140c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const PCEI *get();
141c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru};
142c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
143c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruPCEBuffer::PCEBuffer()
144c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
145c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer = defaultBuffer;
146c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferIndex = 0;
147c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferSize = DEFAULT_BUFFER_SIZE;
148c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
149c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
150c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruPCEBuffer::~PCEBuffer()
151c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
152c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (buffer != defaultBuffer) {
153c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        DELETE_ARRAY(buffer);
154c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
155c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
156c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
157c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid PCEBuffer::reset()
158c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
159c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferIndex = 0;
160c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
161c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
162c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUBool PCEBuffer::empty() const
163c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
164c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return bufferIndex <= 0;
165c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
166c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
167c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid PCEBuffer::put(uint64_t ce, int32_t ixLow, int32_t ixHigh)
168c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
169c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (bufferIndex >= bufferSize) {
170c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        PCEI *newBuffer = NEW_ARRAY(PCEI, bufferSize + BUFFER_GROW);
171c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
172c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ARRAY_COPY(newBuffer, buffer, bufferSize);
173c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
174c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (buffer != defaultBuffer) {
175c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            DELETE_ARRAY(buffer);
176c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
177c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
178c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        buffer = newBuffer;
179c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        bufferSize += BUFFER_GROW;
180c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
181c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
182c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer[bufferIndex].ce   = ce;
183c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer[bufferIndex].low  = ixLow;
184c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    buffer[bufferIndex].high = ixHigh;
185c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
186c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    bufferIndex += 1;
187c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
188c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
189c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruconst PCEI *PCEBuffer::get()
190c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
191c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (bufferIndex > 0) {
192c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru     return &buffer[--bufferIndex];
193c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
194c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
195c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return NULL;
196c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
197c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
198c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru/*
199c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * This inherits from UObject so that
200c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * it can be allocated by new and the
201c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru * constructor for PCEBuffer is called.
202c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru */
203c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querustruct UCollationPCE : public UObject
204c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
205c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    PCEBuffer          pceBuffer;
206c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UCollationStrength strength;
207c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool              toShift;
208c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UBool              isShifted;
209c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uint32_t           variableTop;
210c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
211c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UCollationPCE(UCollationElements *elems);
212c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ~UCollationPCE();
213c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
214c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    void init(const UCollator *coll);
215c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
216c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    virtual UClassID getDynamicClassID() const;
217c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    static UClassID getStaticClassID();
218c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru};
219c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
220c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(UCollationPCE)
221c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
222c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUCollationPCE::UCollationPCE(UCollationElements *elems)
223c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
224c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    init(elems->iteratordata_.coll);
225c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
226c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
227c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruvoid UCollationPCE::init(const UCollator *coll)
228c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
229c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
230c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
231c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    strength    = ucol_getStrength(coll);
232c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    toShift     = ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, &status) == UCOL_SHIFTED;
233c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    isShifted   = FALSE;
234c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    variableTop = coll->variableTopValue << 16;
235c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
236c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
237c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruUCollationPCE::~UCollationPCE()
238c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
239c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // nothing to do
240c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
241c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
242c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
243c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_NAMESPACE_END
244c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
245c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
246c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruinline uint64_t processCE(UCollationElements *elems, uint32_t ce)
247c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
248c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uint64_t primary = 0, secondary = 0, tertiary = 0, quaternary = 0;
249c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
250c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // This is clean, but somewhat slow...
251c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // We could apply the mask to ce and then
252c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // just get all three orders...
253c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    switch(elems->pce->strength) {
254c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    default:
255c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        tertiary = ucol_tertiaryOrder(ce);
256c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        /* note fall-through */
257c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
258c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    case UCOL_SECONDARY:
259c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        secondary = ucol_secondaryOrder(ce);
260c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        /* note fall-through */
261c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
262c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    case UCOL_PRIMARY:
263c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        primary = ucol_primaryOrder(ce);
264c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
265c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
266b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** This should probably handle continuations too.  ****
267b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** That means that we need 24 bits for the primary ****
268b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** instead of the 16 that we're currently using.   ****
269b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** So we can lay out the 64 bits as: 24.12.12.16.  ****
270b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** Another complication with continuations is that ****
271b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** the *second* CE is marked as a continuation, so ****
272b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** we always have to peek ahead to know how long   ****
273b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    // **** the primary is...                               ****
27427f654740f2a26ad62a5c155af9199af9e69b889claireho    if ((elems->pce->toShift && elems->pce->variableTop > ce && primary != 0)
275c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                || (elems->pce->isShifted && primary == 0)) {
276c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
277c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (primary == 0) {
278c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            return UCOL_IGNORABLE;
279c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
280c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
281c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (elems->pce->strength >= UCOL_QUATERNARY) {
282c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            quaternary = primary;
283c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
284c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
285c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        primary = secondary = tertiary = 0;
286c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->pce->isShifted = TRUE;
287c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } else {
288c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (elems->pce->strength >= UCOL_QUATERNARY) {
289c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            quaternary = 0xFFFF;
290c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
291c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
292c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->pce->isShifted = FALSE;
293c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
294c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
295c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return primary << 48 | secondary << 32 | tertiary << 16 | quaternary;
296c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
297c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
298c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI void U_EXPORT2
299c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruuprv_init_pce(const UCollationElements *elems)
300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
301c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (elems->pce != NULL) {
302c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->pce->init(elems->iteratordata_.coll);
303c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
304c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
305c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
306c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
307c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* public methods ---------------------------------------------------- */
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UCollationElements* U_EXPORT2
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_openElements(const UCollator  *coll,
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                  const UChar      *text,
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        int32_t    textLength,
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        UErrorCode *status)
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
316c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (U_FAILURE(*status)) {
317c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return NULL;
318c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
32050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UCollationElements *result = new UCollationElements;
321c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (result == NULL) {
322c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        *status = U_MEMORY_ALLOCATION_ERROR;
323c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return NULL;
324c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
32550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho
326c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    result->reset_ = TRUE;
327c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    result->isWritable = FALSE;
328c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    result->pce = NULL;
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
330c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (text == NULL) {
331c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        textLength = 0;
332c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
33350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    uprv_init_collIterate(coll, text, textLength, &result->iteratordata_, status);
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
335c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return result;
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
338b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_closeElements(UCollationElements *elems)
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
342c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	if (elems != NULL) {
343c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  collIterate *ci = &elems->iteratordata_;
344c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
34550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	  if (ci->extendCEs) {
34650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		  uprv_free(ci->extendCEs);
34750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	  }
348c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
34950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	  if (ci->offsetBuffer) {
35050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		  uprv_free(ci->offsetBuffer);
351c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  }
352c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
353c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  if (elems->isWritable && elems->iteratordata_.string != NULL)
354c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  {
35550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho		uprv_free((UChar *)elems->iteratordata_.string);
356c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  }
357c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
358c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  if (elems->pce != NULL) {
359c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru		  delete elems->pce;
360c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	  }
361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
36250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho	  delete elems;
363c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	}
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_reset(UCollationElements *elems)
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
369c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    collIterate *ci = &(elems->iteratordata_);
370c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    elems->reset_   = TRUE;
371c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->pos         = ci->string;
372c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ((ci->flags & UCOL_ITER_HASLEN) == 0 || ci->endp == NULL) {
373c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ci->endp      = ci->string + u_strlen(ci->string);
374c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
375c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->CEpos       = ci->toReturn = ci->CEs;
376b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ci->flags       = (ci->flags & UCOL_FORCE_HAN_IMPLICIT) | UCOL_ITER_HASLEN;
377c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (ci->coll->normalizationMode == UCOL_ON) {
378c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ci->flags |= UCOL_ITER_NORM;
379c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
380c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
38150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    ci->writableBuffer.remove();
382c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->fcdPosition = NULL;
383c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
384c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  //ci->offsetReturn = ci->offsetStore = NULL;
385c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	ci->offsetRepeatCount = ci->offsetRepeatValue = 0;
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
388b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste QueruU_CAPI void U_EXPORT2
389b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruucol_forceHanImplicit(UCollationElements *elems, UErrorCode *status)
390b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru{
391b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (U_FAILURE(*status)) {
392b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
393b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
394b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
395b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (elems == NULL) {
396b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        *status = U_ILLEGAL_ARGUMENT_ERROR;
397b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        return;
398b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
399b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
400b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    elems->iteratordata_.flags |= UCOL_FORCE_HAN_IMPLICIT;
401b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
402b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_next(UCollationElements *elems,
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru          UErrorCode         *status)
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
407c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t result;
408c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (U_FAILURE(*status)) {
409c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return UCOL_NULLORDER;
410c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
412c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    elems->reset_ = FALSE;
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
414c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    result = (int32_t)ucol_getNextCE(elems->iteratordata_.coll,
415c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     &elems->iteratordata_,
416c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                     status);
417c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
418c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (result == UCOL_NO_MORE_CES) {
419c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        result = UCOL_NULLORDER;
420c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
421c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return result;
422c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
423c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
424c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI int64_t U_EXPORT2
425c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_nextProcessed(UCollationElements *elems,
426c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                   int32_t            *ixLow,
427c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                   int32_t            *ixHigh,
428c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                   UErrorCode         *status)
429c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
430c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UCollator *coll = elems->iteratordata_.coll;
431c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int64_t result = UCOL_IGNORABLE;
432c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uint32_t low = 0, high = 0;
433c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
434c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (U_FAILURE(*status)) {
435c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return UCOL_PROCESSED_NULLORDER;
436c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
437c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
438c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (elems->pce == NULL) {
439c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->pce = new UCollationPCE(elems);
440c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } else {
441c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->pce->pceBuffer.reset();
442c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
443c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
444c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    elems->reset_ = FALSE;
445c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
446c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    do {
447c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        low = ucol_getOffset(elems);
448c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        uint32_t ce = (uint32_t) ucol_getNextCE(coll, &elems->iteratordata_, status);
449c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        high = ucol_getOffset(elems);
450c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
451c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (ce == UCOL_NO_MORE_CES) {
452c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru             result = UCOL_PROCESSED_NULLORDER;
453c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru             break;
454c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
455c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
456c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        result = processCE(elems, ce);
457c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } while (result == UCOL_IGNORABLE);
458c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
459c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (ixLow != NULL) {
460c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        *ixLow = low;
461c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
462c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
463c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (ixHigh != NULL) {
464c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        *ixHigh = high;
465c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
466c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
467c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return result;
468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_previous(UCollationElements *elems,
472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru              UErrorCode         *status)
473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
474c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if(U_FAILURE(*status)) {
475c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return UCOL_NULLORDER;
476c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
477c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    else
478c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    {
479c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        int32_t result;
480c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
481c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (elems->reset_ && (elems->iteratordata_.pos == elems->iteratordata_.string)) {
482c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if (elems->iteratordata_.endp == NULL) {
483c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                elems->iteratordata_.endp = elems->iteratordata_.string +
484c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                            u_strlen(elems->iteratordata_.string);
485c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                elems->iteratordata_.flags |= UCOL_ITER_HASLEN;
486c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
487c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            elems->iteratordata_.pos = elems->iteratordata_.endp;
488c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            elems->iteratordata_.fcdPosition = elems->iteratordata_.endp;
489c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
490c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
491c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->reset_ = FALSE;
492c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
493c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        result = (int32_t)ucol_getPrevCE(elems->iteratordata_.coll,
494c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                         &(elems->iteratordata_),
495c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                                         status);
496c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
497c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (result == UCOL_NO_MORE_CES) {
498c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            result = UCOL_NULLORDER;
499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
501c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return result;
502c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
503c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru}
504c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
505c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI int64_t U_EXPORT2
506c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_previousProcessed(UCollationElements *elems,
507c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                   int32_t            *ixLow,
508c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                   int32_t            *ixHigh,
509c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                   UErrorCode         *status)
510c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{
511c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UCollator *coll = elems->iteratordata_.coll;
512c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int64_t result = UCOL_IGNORABLE;
513c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // int64_t primary = 0, secondary = 0, tertiary = 0, quaternary = 0;
514c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // UCollationStrength strength = ucol_getStrength(coll);
515c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru //  UBool toShift   = ucol_getAttribute(coll, UCOL_ALTERNATE_HANDLING, status) ==  UCOL_SHIFTED;
516c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // uint32_t variableTop = coll->variableTopValue;
517c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    int32_t  low = 0, high = 0;
518c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
519c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (U_FAILURE(*status)) {
520c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return UCOL_PROCESSED_NULLORDER;
521c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (elems->reset_ &&
524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        (elems->iteratordata_.pos == elems->iteratordata_.string)) {
525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (elems->iteratordata_.endp == NULL) {
526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            elems->iteratordata_.endp = elems->iteratordata_.string +
527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                        u_strlen(elems->iteratordata_.string);
528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            elems->iteratordata_.flags |= UCOL_ITER_HASLEN;
529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
530c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        elems->iteratordata_.pos = elems->iteratordata_.endp;
532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        elems->iteratordata_.fcdPosition = elems->iteratordata_.endp;
533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
535c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (elems->pce == NULL) {
536c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        elems->pce = new UCollationPCE(elems);
537c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } else {
538c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      //elems->pce->pceBuffer.reset();
539c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
540c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    elems->reset_ = FALSE;
542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
543c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    while (elems->pce->pceBuffer.empty()) {
544c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // buffer raw CEs up to non-ignorable primary
545c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        RCEBuffer rceb;
546c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        uint32_t ce;
547c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
548c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // **** do we need to reset rceb, or will it always be empty at this point ****
549c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        do {
550c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            high = ucol_getOffset(elems);
551c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            ce   = ucol_getPrevCE(coll, &elems->iteratordata_, status);
552c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            low  = ucol_getOffset(elems);
553c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
554c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if (ce == UCOL_NO_MORE_CES) {
555c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                if (! rceb.empty()) {
556c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                    break;
557c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                }
558c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
559c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                goto finish;
560c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
561c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
562c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            rceb.put(ce, low, high);
563c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        } while ((ce & UCOL_PRIMARYMASK) == 0);
564c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
565c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // process the raw CEs
566c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        while (! rceb.empty()) {
567c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            const RCEI *rcei = rceb.get();
568c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
569c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            result = processCE(elems, rcei->ce);
570c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
571c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if (result != UCOL_IGNORABLE) {
572c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                elems->pce->pceBuffer.put(result, rcei->low, rcei->high);
573c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
574c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
575c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
577c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Querufinish:
578c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (elems->pce->pceBuffer.empty()) {
579c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // **** Is -1 the right value for ixLow, ixHigh? ****
580c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    	if (ixLow != NULL) {
581c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    		*ixLow = -1;
582c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    	}
583c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
584c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    	if (ixHigh != NULL) {
585c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    		*ixHigh = -1
586c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    		;
587c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    	}
588c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return UCOL_PROCESSED_NULLORDER;
589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
591c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const PCEI *pcei = elems->pce->pceBuffer.get();
592c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
593c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (ixLow != NULL) {
594c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        *ixLow = pcei->low;
595c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
596c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
597c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (ixHigh != NULL) {
598c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        *ixHigh = pcei->high;
599c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
600c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
601c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return pcei->ce;
602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getMaxExpansion(const UCollationElements *elems,
606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                           int32_t            order)
607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
608c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uint8_t result;
609c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
610c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#if 0
611c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    UCOL_GETMAXEXPANSION(elems->iteratordata_.coll, (uint32_t)order, result);
612c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#else
613c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const UCollator *coll = elems->iteratordata_.coll;
614c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const uint32_t *start;
615c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const uint32_t *limit;
616c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    const uint32_t *mid;
617c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru          uint32_t strengthMask = 0;
618c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru          uint32_t mOrder = (uint32_t) order;
619c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
620c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    switch (coll->strength)
621c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    {
622c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    default:
623c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        strengthMask |= UCOL_TERTIARYORDERMASK;
624c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        /* fall through */
625c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
626c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    case UCOL_SECONDARY:
627c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        strengthMask |= UCOL_SECONDARYORDERMASK;
628c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        /* fall through */
629c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
630c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    case UCOL_PRIMARY:
631c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        strengthMask |= UCOL_PRIMARYORDERMASK;
632c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
633c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
634c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    mOrder &= strengthMask;
635c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    start = (coll)->endExpansionCE;
636c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    limit = (coll)->lastEndExpansionCE;
637c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
638c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    while (start < limit - 1) {
639c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        mid = start + ((limit - start) >> 1);
640c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        if (mOrder <= (*mid & strengthMask)) {
641c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru          limit = mid;
642c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        } else {
643c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru          start = mid;
644c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        }
645c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
646c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
647c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // FIXME: with a masked search, there might be more than one hit,
648c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // so we need to look forward and backward from the match to find all
649c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // of the hits...
650c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ((*start & strengthMask) == mOrder) {
651c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        result = *((coll)->expansionCESize + (start - (coll)->endExpansionCE));
652c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    } else if ((*limit & strengthMask) == mOrder) {
653c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru         result = *(coll->expansionCESize + (limit - coll->endExpansionCE));
654c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru   } else if ((mOrder & 0xFFFF) == 0x00C0) {
655c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        result = 2;
656c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru   } else {
657c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru       result = 1;
658c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru   }
659c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
660c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
661c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return result;
662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_setText(      UCollationElements *elems,
666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru             const UChar              *text,
667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   int32_t            textLength,
668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                   UErrorCode         *status)
669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
670c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (U_FAILURE(*status)) {
671c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
672c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
674c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (elems->isWritable && elems->iteratordata_.string != NULL)
675c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    {
67650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_free((UChar *)elems->iteratordata_.string);
677c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
678c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
679c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (text == NULL) {
680c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        textLength = 0;
681c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
683c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    elems->isWritable = FALSE;
684c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
685c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    /* free offset buffer to avoid memory leak before initializing. */
686b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    ucol_freeOffsetBuffer(&(elems->iteratordata_));
68750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    /* Ensure that previously allocated extendCEs is freed before setting to NULL. */
68850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    if (elems->iteratordata_.extendCEs != NULL) {
68950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho        uprv_free(elems->iteratordata_.extendCEs);
69050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    }
691c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    uprv_init_collIterate(elems->iteratordata_.coll, text, textLength,
69250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho                          &elems->iteratordata_, status);
693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
694c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    elems->reset_   = TRUE;
695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getOffset(const UCollationElements *elems)
699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  const collIterate *ci = &(elems->iteratordata_);
701c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
702c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  if (ci->offsetRepeatCount > 0 && ci->offsetRepeatValue != 0) {
703c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      return ci->offsetRepeatValue;
704c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  }
705c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
706c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  if (ci->offsetReturn != NULL) {
707c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru      return *ci->offsetReturn;
708c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru  }
709c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // while processing characters in normalization buffer getOffset will
711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // return the next non-normalized character.
712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // should be inline with the old implementation since the old codes uses
713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // nextDecomp in normalizer which also decomposes the string till the
714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  // first base character is found.
715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  if (ci->flags & UCOL_ITER_INNORMBUF) {
716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      if (ci->fcdPosition == NULL) {
717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return 0;
718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      }
719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return (int32_t)(ci->fcdPosition - ci->string);
720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  else {
722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru      return (int32_t)(ci->pos - ci->string);
723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru  }
724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2
727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_setOffset(UCollationElements    *elems,
728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               int32_t           offset,
729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru               UErrorCode            *status)
730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
731c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (U_FAILURE(*status)) {
732c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        return;
733c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
735c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // this methods will clean up any use of the writable buffer and points to
736c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    // the original string
737c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    collIterate *ci = &(elems->iteratordata_);
738c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->pos         = ci->string + offset;
739c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->CEpos       = ci->toReturn = ci->CEs;
740c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if (ci->flags & UCOL_ITER_INNORMBUF) {
741c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ci->flags = ci->origFlags;
742c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
743c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    if ((ci->flags & UCOL_ITER_HASLEN) == 0) {
744c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ci->endp  = ci->string + u_strlen(ci->string);
745c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        ci->flags |= UCOL_ITER_HASLEN;
746c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    }
747c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->fcdPosition = NULL;
748c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    elems->reset_ = FALSE;
749c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
750c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	ci->offsetReturn = NULL;
751c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    ci->offsetStore = ci->offsetBuffer;
752c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru	ci->offsetRepeatCount = ci->offsetRepeatValue = 0;
753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_primaryOrder (int32_t order)
757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
758c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    order &= UCOL_PRIMARYMASK;
759c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return (order >> UCOL_PRIMARYORDERSHIFT);
760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_secondaryOrder (int32_t order)
764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
765c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    order &= UCOL_SECONDARYMASK;
766c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return (order >> UCOL_SECONDARYORDERSHIFT);
767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2
770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_tertiaryOrder (int32_t order)
771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
772c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru    return (order & UCOL_TERTIARYMASK);
773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
775b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
776b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queruvoid ucol_freeOffsetBuffer(collIterate *s) {
777b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    if (s != NULL && s->offsetBuffer != NULL) {
778b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        uprv_free(s->offsetBuffer);
779b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        s->offsetBuffer = NULL;
780b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru        s->offsetBufferSize = 0;
781b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru    }
782b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru}
783b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru
784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */
785