search.cpp revision c69afcec261fc345fda8daf46f0ea6b4351dc777
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru**********************************************************************
3c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru*   Copyright (C) 2001-2008 IBM and others. All rights reserved.
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru**********************************************************************
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Date        Name        Description
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*  03/22/2000   helena      Creation.
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru**********************************************************************
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
12c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/brkiter.h"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/schriter.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/search.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "usrchimp.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h"
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// public constructors and destructors -----------------------------------
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSearchIterator::SearchIterator(const SearchIterator &other)
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    : UObject(other)
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_breakiterator_            = other.m_breakiterator_;
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_text_                     = other.m_text_;
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_                   = (USearch *)uprv_malloc(sizeof(USearch));
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->breakIter        = other.m_search_->breakIter;
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isCanonicalMatch = other.m_search_->isCanonicalMatch;
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isOverlap        = other.m_search_->isOverlap;
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedIndex     = other.m_search_->matchedIndex;
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedLength    = other.m_search_->matchedLength;
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->text             = other.m_search_->text;
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->textLength       = other.m_search_->textLength;
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSearchIterator::~SearchIterator()
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (m_search_ != NULL) {
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uprv_free(m_search_);
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// public get and set methods ----------------------------------------
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setAttribute(USearchAttribute       attribute,
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  USearchAttributeValue  value,
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                  UErrorCode            &status)
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        switch (attribute)
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        {
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case USEARCH_OVERLAP :
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isOverlap = (value == USEARCH_ON ? TRUE : FALSE);
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        case USEARCH_CANONICAL_MATCH :
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isCanonicalMatch = (value == USEARCH_ON ? TRUE : FALSE);
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        default:
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ILLEGAL_ARGUMENT_ERROR;
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (value == USEARCH_ATTRIBUTE_VALUE_COUNT) {
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUSearchAttributeValue SearchIterator::getAttribute(
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                          USearchAttribute  attribute) const
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    switch (attribute) {
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    case USEARCH_OVERLAP :
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return (m_search_->isOverlap == TRUE ? USEARCH_ON : USEARCH_OFF);
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    case USEARCH_CANONICAL_MATCH :
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return (m_search_->isCanonicalMatch == TRUE ? USEARCH_ON :
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                                                USEARCH_OFF);
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    default :
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return USEARCH_DEFAULT;
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::getMatchedStart() const
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return m_search_->matchedIndex;
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::getMatchedLength() const
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return m_search_->matchedLength;
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::getMatchedText(UnicodeString &result) const
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t matchedindex  = m_search_->matchedIndex;
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t     matchedlength = m_search_->matchedLength;
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (matchedindex != USEARCH_DONE && matchedlength != 0) {
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result.setTo(m_search_->text + matchedindex, matchedlength);
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        result.remove();
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setBreakIterator(BreakIterator *breakiter,
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                      UErrorCode &status)
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
109c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#if 0
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->breakIter = NULL;
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // the c++ breakiterator may not make use of ubreakiterator.
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        // so we'll have to keep track of it ourselves.
113c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#else
114c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // Well, gee... the Constructors that take a BreakIterator
115c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // all cast the BreakIterator to a UBreakIterator and
116c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // pass it to the corresponding usearch_openFromXXX
117c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // routine, so there's no reason not to do this.
118c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        //
119c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // Besides, a UBreakIterator is a BreakIterator, so
120c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        // any subclass of BreakIterator should work fine here...
121c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru        m_search_->breakIter = (UBreakIterator *) breakiter;
122c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#endif
123c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_breakiterator_ = breakiter;
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst BreakIterator * SearchIterator::getBreakIterator(void) const
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return m_breakiterator_;
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setText(const UnicodeString &text, UErrorCode &status)
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (text.length() == 0) {
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_ILLEGAL_ARGUMENT_ERROR;
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_text_        = text;
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->text = m_text_.getBuffer();
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->textLength = m_text_.length();
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setText(CharacterIterator &text, UErrorCode &status)
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        text.getText(m_text_);
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setText(m_text_, status);
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UnicodeString & SearchIterator::getText(void) const
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return m_text_;
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// operator overloading ----------------------------------------------
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool SearchIterator::operator==(const SearchIterator &that) const
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (this == &that) {
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return TRUE;
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (m_breakiterator_            == that.m_breakiterator_ &&
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isCanonicalMatch == that.m_search_->isCanonicalMatch &&
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isOverlap        == that.m_search_->isOverlap &&
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->matchedIndex     == that.m_search_->matchedIndex &&
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->matchedLength    == that.m_search_->matchedLength &&
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->textLength       == that.m_search_->textLength &&
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            getOffset() == that.getOffset() &&
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            (uprv_memcmp(m_search_->text, that.m_search_->text,
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                              m_search_->textLength * sizeof(UChar)) == 0));
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// public methods ----------------------------------------------------
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::first(UErrorCode &status)
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return USEARCH_DONE;
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setOffset(0, status);
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return handleNext(0, status);
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::following(int32_t position,
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                      UErrorCode &status)
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return USEARCH_DONE;
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setOffset(position, status);
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return handleNext(position, status);
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::last(UErrorCode &status)
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return USEARCH_DONE;
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setOffset(m_search_->textLength, status);
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return handlePrev(m_search_->textLength, status);
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::preceding(int32_t position,
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                      UErrorCode &status)
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return USEARCH_DONE;
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setOffset(position, status);
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return handlePrev(position, status);
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::next(UErrorCode &status)
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t offset = getOffset();
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t matchindex  = m_search_->matchedIndex;
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t     matchlength = m_search_->matchedLength;
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->reset = FALSE;
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (m_search_->isForwardSearching == TRUE) {
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t textlength = m_search_->textLength;
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (offset == textlength || matchindex == textlength ||
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                (matchindex != USEARCH_DONE &&
229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                matchindex + matchlength >= textlength)) {
230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // not enough characters to match
231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMatchNotFound();
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return USEARCH_DONE;
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // switching direction.
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // if matchedIndex == USEARCH_DONE, it means that either a
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // setOffset has been called or that previous ran off the text
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // string. the iterator would have been set to offset 0 if a
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // match is not found.
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isForwardSearching = TRUE;
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (m_search_->matchedIndex != USEARCH_DONE) {
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // there's no need to set the collation element iterator
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // the next call to next will set the offset.
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return matchindex;
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (matchlength > 0) {
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // if matchlength is 0 we are at the start of the iteration
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (m_search_->isOverlap) {
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                offset ++;
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else {
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                offset += matchlength;
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return handleNext(offset, status);
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return USEARCH_DONE;
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t SearchIterator::previous(UErrorCode &status)
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t offset;
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (m_search_->reset) {
268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            offset                       = m_search_->textLength;
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isForwardSearching = FALSE;
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->reset              = FALSE;
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            setOffset(offset, status);
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            offset = getOffset();
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int32_t matchindex = m_search_->matchedIndex;
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (m_search_->isForwardSearching == TRUE) {
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // switching direction.
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // if matchedIndex == USEARCH_DONE, it means that either a
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // setOffset has been called or that next ran off the text
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // string. the iterator would have been set to offset textLength if
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // a match is not found.
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            m_search_->isForwardSearching = FALSE;
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (matchindex != USEARCH_DONE) {
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return matchindex;
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (offset == 0 || matchindex == 0) {
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                // not enough characters to match
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                setMatchNotFound();
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return USEARCH_DONE;
294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (matchindex != USEARCH_DONE) {
298c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            if (m_search_->isOverlap) {
299c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru                matchindex += m_search_->matchedLength - 2;
300c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru            }
301c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return handlePrev(matchindex, status);
303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
304c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return handlePrev(offset, status);
306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
307c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru
308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return USEARCH_DONE;
309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::reset()
312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setMatchNotFound();
315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setOffset(0, status);
316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isOverlap          = FALSE;
317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isCanonicalMatch   = FALSE;
318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isForwardSearching = TRUE;
319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->reset              = TRUE;
320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// protected constructors and destructors -----------------------------
323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSearchIterator::SearchIterator()
325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_                     = (USearch *)uprv_malloc(sizeof(USearch));
327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->breakIter          = NULL;
328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isOverlap          = FALSE;
329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isCanonicalMatch   = FALSE;
330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isForwardSearching = TRUE;
331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->reset              = TRUE;
332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedIndex       = USEARCH_DONE;
333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedLength      = 0;
334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->text               = NULL;
335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->textLength         = 0;
336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_breakiterator_              = NULL;
337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSearchIterator::SearchIterator(const UnicodeString &text,
340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                     BreakIterator *breakiter) :
341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                     m_breakiterator_(breakiter),
342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                     m_text_(text)
343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_                     = (USearch *)uprv_malloc(sizeof(USearch));
345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->breakIter          = NULL;
346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isOverlap          = FALSE;
347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isCanonicalMatch   = FALSE;
348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isForwardSearching = TRUE;
349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->reset              = TRUE;
350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedIndex       = USEARCH_DONE;
351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedLength      = 0;
352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->text               = m_text_.getBuffer();
353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->textLength         = text.length();
354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSearchIterator::SearchIterator(CharacterIterator &text,
357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               BreakIterator     *breakiter) :
358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                               m_breakiterator_(breakiter)
359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_                     = (USearch *)uprv_malloc(sizeof(USearch));
361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->breakIter          = NULL;
362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isOverlap          = FALSE;
363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isCanonicalMatch   = FALSE;
364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->isForwardSearching = TRUE;
365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->reset              = TRUE;
366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedIndex       = USEARCH_DONE;
367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedLength      = 0;
368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    text.getText(m_text_);
369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->text               = m_text_.getBuffer();
370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->textLength         = m_text_.length();
371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_breakiterator_             = breakiter;
372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// protected methods ------------------------------------------------------
375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSearchIterator & SearchIterator::operator=(const SearchIterator &that)
377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (this != &that) {
379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_breakiterator_            = that.m_breakiterator_;
380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_text_                     = that.m_text_;
381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->breakIter        = that.m_search_->breakIter;
382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->isCanonicalMatch = that.m_search_->isCanonicalMatch;
383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->isOverlap        = that.m_search_->isOverlap;
384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->matchedIndex     = that.m_search_->matchedIndex;
385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->matchedLength    = that.m_search_->matchedLength;
386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->text             = that.m_search_->text;
387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        m_search_->textLength       = that.m_search_->textLength;
388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return *this;
390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setMatchLength(int32_t length)
393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedLength = length;
395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setMatchStart(int32_t position)
398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    m_search_->matchedIndex = position;
400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SearchIterator::setMatchNotFound()
403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setMatchStart(USEARCH_DONE);
405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    setMatchLength(0);
406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // by default no errors should be returned here since offsets are within
408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // range.
409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (m_search_->isForwardSearching) {
410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setOffset(m_search_->textLength, status);
411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    else {
413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        setOffset(0, status);
414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */
421