1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   Copyright (C) 2001-2008 IBM and others. All rights reserved.
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Date        Name        Description
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*  03/22/2000   helena      Creation.
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru**********************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !UCONFIG_NO_COLLATION && !UCONFIG_NO_BREAK_ITERATION
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/stsearch.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "usrchimp.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(StringSearch)
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// public constructors and destructors -----------------------------------
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::StringSearch(const UnicodeString &pattern,
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           const UnicodeString &text,
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           const Locale        &locale,
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 BreakIterator *breakiter,
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 UErrorCode    &status) :
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           SearchIterator(text, breakiter),
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_collator_(),
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_pattern_(pattern)
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_strsrch_ = usearch_open(m_pattern_.getBuffer(), m_pattern_.length(),
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              m_text_.getBuffer(), m_text_.length(),
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              locale.getName(), (UBreakIterator *)breakiter,
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              &status);
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_free(m_search_);
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_search_ = NULL;
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // !!! dlf m_collator_ is an odd beast.  basically it is an aliasing
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // wrapper around the internal collator and rules, which (here) are
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // owned by this stringsearch object.  this means 1) it's destructor
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // _should not_ delete the ucollator or rules, and 2) changes made
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // to the exposed collator (setStrength etc) _should_ modify the
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // ucollator.  thus the collator is not a copy-on-write alias, and it
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // needs to distinguish itself not merely from 'stand alone' colators
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // but also from copy-on-write ones.  it needs additional state, which
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // setUCollator should set.
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Alias the collator
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // m_search_ has been created by the base SearchIterator class
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_search_        = m_strsrch_->search;
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::StringSearch(const UnicodeString     &pattern,
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           const UnicodeString     &text,
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 RuleBasedCollator *coll,
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 BreakIterator     *breakiter,
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 UErrorCode        &status) :
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           SearchIterator(text, breakiter),
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_collator_(),
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_pattern_(pattern)
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (coll == NULL) {
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status     = U_ILLEGAL_ARGUMENT_ERROR;
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(),
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          m_pattern_.length(),
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          m_text_.getBuffer(),
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          m_text_.length(), coll->ucollator,
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          (UBreakIterator *)breakiter,
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          &status);
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_free(m_search_);
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_search_ = NULL;
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Alias the collator
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // m_search_ has been created by the base SearchIterator class
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_search_ = m_strsrch_->search;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::StringSearch(const UnicodeString     &pattern,
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 CharacterIterator &text,
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           const Locale            &locale,
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 BreakIterator     *breakiter,
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 UErrorCode        &status) :
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           SearchIterator(text, breakiter),
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_collator_(),
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_pattern_(pattern)
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_strsrch_ = usearch_open(m_pattern_.getBuffer(), m_pattern_.length(),
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              m_text_.getBuffer(), m_text_.length(),
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              locale.getName(), (UBreakIterator *)breakiter,
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              &status);
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_free(m_search_);
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_search_ = NULL;
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Alias the collator
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // m_search_ has been created by the base SearchIterator class
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_search_ = m_strsrch_->search;
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::StringSearch(const UnicodeString     &pattern,
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 CharacterIterator &text,
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 RuleBasedCollator *coll,
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 BreakIterator     *breakiter,
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                 UErrorCode        &status) :
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           SearchIterator(text, breakiter),
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_collator_(),
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           m_pattern_(pattern)
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (coll == NULL) {
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status     = U_ILLEGAL_ARGUMENT_ERROR;
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(),
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          m_pattern_.length(),
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          m_text_.getBuffer(),
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          m_text_.length(), coll->ucollator,
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          (UBreakIterator *)breakiter,
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                          &status);
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_free(m_search_);
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_search_ = NULL;
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Alias the collator
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // m_search_ has been created by the base SearchIterator class
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_search_ = m_strsrch_->search;
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::StringSearch(const StringSearch &that) :
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       SearchIterator(that.m_text_, that.m_breakiterator_),
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       m_collator_(),
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                       m_pattern_(that.m_pattern_)
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Free m_search_ from the superclass
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    uprv_free(m_search_);
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    m_search_ = NULL;
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (that.m_strsrch_ == NULL) {
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // This was not a good copy
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = NULL;
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    else {
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Make a deep copy
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(),
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              m_pattern_.length(),
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              m_text_.getBuffer(),
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              m_text_.length(),
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              that.m_strsrch_->collator,
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                             (UBreakIterator *)that.m_breakiterator_,
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              &status);
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (U_SUCCESS(status)) {
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // Alias the collator
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // m_search_ has been created by the base SearchIterator class
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            m_search_        = m_strsrch_->search;
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::~StringSearch()
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (m_strsrch_ != NULL) {
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usearch_close(m_strsrch_);
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_search_ = NULL;
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch *
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch::clone() const {
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return new StringSearch(*this);
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// operator overloading ---------------------------------------------
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringSearch & StringSearch::operator=(const StringSearch &that)
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if ((*this) != that) {
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_text_          = that.m_text_;
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_breakiterator_ = that.m_breakiterator_;
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_pattern_       = that.m_pattern_;
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // all m_search_ in the parent class is linked up with m_strsrch_
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usearch_close(m_strsrch_);
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_strsrch_ = usearch_openFromCollator(m_pattern_.getBuffer(),
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              m_pattern_.length(),
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              m_text_.getBuffer(),
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              m_text_.length(),
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              that.m_strsrch_->collator,
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                              NULL, &status);
22385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        // Check null pointer
22485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        if (m_strsrch_ != NULL) {
22585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho	        // Alias the collator
22685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho	        m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
22785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho	        m_search_ = m_strsrch_->search;
22885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return *this;
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool StringSearch::operator==(const SearchIterator &that) const
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (this == &that) {
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return TRUE;
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (SearchIterator::operator ==(that)) {
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        StringSearch &thatsrch = (StringSearch &)that;
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return (this->m_pattern_ == thatsrch.m_pattern_ &&
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                this->m_strsrch_->collator == thatsrch.m_strsrch_->collator);
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return FALSE;
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// public get and set methods ----------------------------------------
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid StringSearch::setOffset(int32_t position, UErrorCode &status)
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // status checked in usearch_setOffset
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    usearch_setOffset(m_strsrch_, position, &status);
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t StringSearch::getOffset(void) const
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return usearch_getOffset(m_strsrch_);
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid StringSearch::setText(const UnicodeString &text, UErrorCode &status)
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_text_ = text;
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usearch_setText(m_strsrch_, text.getBuffer(), text.length(), &status);
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid StringSearch::setText(CharacterIterator &text, UErrorCode &status)
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        text.getText(m_text_);
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usearch_setText(m_strsrch_, m_text_.getBuffer(), m_text_.length(), &status);
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedCollator * StringSearch::getCollator() const
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return (RuleBasedCollator *)&m_collator_;
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid StringSearch::setCollator(RuleBasedCollator *coll, UErrorCode &status)
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usearch_setCollator(m_strsrch_, coll->getUCollator(), &status);
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Alias the collator
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_collator_.setUCollator((UCollator *)m_strsrch_->collator);
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid StringSearch::setPattern(const UnicodeString &pattern,
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                    UErrorCode    &status)
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        m_pattern_ = pattern;
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        usearch_setPattern(m_strsrch_, m_pattern_.getBuffer(), m_pattern_.length(),
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           &status);
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UnicodeString & StringSearch::getPattern() const
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return m_pattern_;
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// public methods ----------------------------------------------------
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid StringSearch::reset()
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    usearch_reset(m_strsrch_);
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruSearchIterator * StringSearch::safeClone(void) const
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    StringSearch *result = new StringSearch(m_pattern_, m_text_,
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                            (RuleBasedCollator *)&m_collator_,
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                            m_breakiterator_,
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                            status);
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /* test for NULL */
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (result == 0) {
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_MEMORY_ALLOCATION_ERROR;
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return 0;
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result->setOffset(getOffset(), status);
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result->setMatchStart(m_strsrch_->search->matchedIndex);
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    result->setMatchLength(m_strsrch_->search->matchedLength);
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return result;
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// protected method -------------------------------------------------
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t StringSearch::handleNext(int32_t position, UErrorCode &status)
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // values passed here are already in the pre-shift position
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (m_strsrch_->pattern.CELength == 0) {
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            m_search_->matchedIndex =
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                    m_search_->matchedIndex == USEARCH_DONE ?
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                    getOffset() : m_search_->matchedIndex + 1;
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            m_search_->matchedLength = 0;
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex,
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                           &status);
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (m_search_->matchedIndex == m_search_->textLength) {
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                m_search_->matchedIndex = USEARCH_DONE;
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // looking at usearch.cpp, this part is shifted out to
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // StringSearch instead of SearchIterator because m_strsrch_ is
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // not accessible in SearchIterator
35385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if 0
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (position + m_strsrch_->pattern.defaultShiftSize
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                > m_search_->textLength) {
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                setMatchNotFound();
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return USEARCH_DONE;
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
35985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (m_search_->matchedLength <= 0) {
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // the flipping direction issue has already been handled
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // in next()
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // for boundary check purposes. this will ensure that the
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // next match will not preceed the current offset
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // note search->matchedIndex will always be set to something
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // in the code
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                m_search_->matchedIndex = position - 1;
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ucol_setOffset(m_strsrch_->textIter, position, &status);
37185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
37285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if 0
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for (;;) {
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (m_search_->isCanonicalMatch) {
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    // can't use exact here since extra accents are allowed.
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    usearch_handleNextCanonical(m_strsrch_, &status);
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    usearch_handleNextExact(m_strsrch_, &status);
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (U_FAILURE(status)) {
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return USEARCH_DONE;
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (m_breakiterator_ == NULL
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_BREAK_ITERATION
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ||
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    m_search_->matchedIndex == USEARCH_DONE ||
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    (m_breakiterator_->isBoundary(m_search_->matchedIndex) &&
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     m_breakiterator_->isBoundary(m_search_->matchedIndex +
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                  m_search_->matchedLength))
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ) {
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (m_search_->matchedIndex == USEARCH_DONE) {
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ucol_setOffset(m_strsrch_->textIter,
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       m_search_->textLength, &status);
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    else {
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        ucol_setOffset(m_strsrch_->textIter,
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                       m_search_->matchedIndex, &status);
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return m_search_->matchedIndex;
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
40485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
40585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // if m_strsrch_->breakIter is always the same as m_breakiterator_
40685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // then we don't need to check the match boundaries here because
40785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            // usearch_handleNextXXX will already have done it.
40885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (m_search_->isCanonicalMatch) {
40985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	// *could* actually use exact here 'cause no extra accents allowed...
41085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	usearch_handleNextCanonical(m_strsrch_, &status);
41185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
41285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	usearch_handleNextExact(m_strsrch_, &status);
41385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
41485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
41585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (U_FAILURE(status)) {
41685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	return USEARCH_DONE;
41785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
41885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
41985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (m_search_->matchedIndex == USEARCH_DONE) {
42085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	ucol_setOffset(m_strsrch_->textIter, m_search_->textLength, &status);
42185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
42285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex, &status);
42385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
42485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
42585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return m_search_->matchedIndex;
42685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return USEARCH_DONE;
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t StringSearch::handlePrev(int32_t position, UErrorCode &status)
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // values passed here are already in the pre-shift position
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_SUCCESS(status)) {
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (m_strsrch_->pattern.CELength == 0) {
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            m_search_->matchedIndex =
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                  (m_search_->matchedIndex == USEARCH_DONE ? getOffset() :
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                   m_search_->matchedIndex);
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (m_search_->matchedIndex == 0) {
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                setMatchNotFound();
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            else {
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                m_search_->matchedIndex --;
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ucol_setOffset(m_strsrch_->textIter, m_search_->matchedIndex,
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               &status);
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                m_search_->matchedLength = 0;
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // looking at usearch.cpp, this part is shifted out to
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // StringSearch instead of SearchIterator because m_strsrch_ is
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // not accessible in SearchIterator
45485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if 0
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (!m_search_->isOverlap &&
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                position - m_strsrch_->pattern.defaultShiftSize < 0) {
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                setMatchNotFound();
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return USEARCH_DONE;
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
46085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for (;;) {
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (m_search_->isCanonicalMatch) {
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    // can't use exact here since extra accents are allowed.
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    usearch_handlePreviousCanonical(m_strsrch_, &status);
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    usearch_handlePreviousExact(m_strsrch_, &status);
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (U_FAILURE(status)) {
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return USEARCH_DONE;
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (m_breakiterator_ == NULL
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_BREAK_ITERATION
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    ||
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    m_search_->matchedIndex == USEARCH_DONE ||
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    (m_breakiterator_->isBoundary(m_search_->matchedIndex) &&
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     m_breakiterator_->isBoundary(m_search_->matchedIndex +
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                                  m_search_->matchedLength))
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                ) {
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    return m_search_->matchedIndex;
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
48485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#else
48585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            ucol_setOffset(m_strsrch_->textIter, position, &status);
48685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
48785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (m_search_->isCanonicalMatch) {
48885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	// *could* use exact match here since extra accents *not* allowed!
48985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	usearch_handlePreviousCanonical(m_strsrch_, &status);
49085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            } else {
49185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	usearch_handlePreviousExact(m_strsrch_, &status);
49285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
49385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            if (U_FAILURE(status)) {
49585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            	return USEARCH_DONE;
49685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
49785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
49885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return m_search_->matchedIndex;
49985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return m_search_->matchedIndex;
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return USEARCH_DONE;
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */
510