1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*******************************************************************************
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Copyright (C) 1996-2009, International Business Machines Corporation and    *
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* others. All Rights Reserved.                                                *
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*******************************************************************************
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* File coleitr.cpp
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Created by: Helena Shih
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Modification History:
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*  Date      Name        Description
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*  6/23/97   helena      Adding comments to make code more readable.
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* 08/03/98   erm         Synched with 1.2 version of CollationElementIterator.java
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* 12/10/99   aliu        Ported Thai collation support from Java.
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* 01/25/01   swquek      Modified to a C++ wrapper calling C APIs (ucoliter.h)
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* 02/19/01   swquek      Removed CollationElementsIterator() since it is
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*                        private constructor and no calls are made to it
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "unicode/utypes.h"
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if !UCONFIG_NO_COLLATION
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "unicode/coleitr.h"
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "unicode/ustring.h"
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "ucol_imp.h"
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "cmemory.h"
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* Constants --------------------------------------------------------------- */
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_NAMESPACE_BEGIN
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottUOBJECT_DEFINE_RTTI_IMPLEMENTATION(CollationElementIterator)
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* CollationElementIterator public constructor/destructor ------------------ */
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCollationElementIterator::CollationElementIterator(
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const CollationElementIterator& other)
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         : UObject(other), isDataOwned_(TRUE)
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UErrorCode status = U_ZERO_ERROR;
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_ = ucol_openElements(other.m_data_->iteratordata_.coll, NULL, 0,
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                &status);
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *this = other;
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCollationElementIterator::~CollationElementIterator()
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (isDataOwned_) {
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ucol_closeElements(m_data_);
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* CollationElementIterator public methods --------------------------------- */
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32_t CollationElementIterator::getOffset() const
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return ucol_getOffset(m_data_);
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/**
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Get the ordering priority of the next character in the string.
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* @return the next character's ordering. Returns NULLORDER if an error has
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*         occured or if the end of string has been reached
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32_t CollationElementIterator::next(UErrorCode& status)
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return ucol_next(m_data_, &status);
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottUBool CollationElementIterator::operator!=(
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                  const CollationElementIterator& other) const
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return !(*this == other);
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottUBool CollationElementIterator::operator==(
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                    const CollationElementIterator& that) const
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (this == &that || m_data_ == that.m_data_) {
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return TRUE;
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // option comparison
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (m_data_->iteratordata_.coll != that.m_data_->iteratordata_.coll)
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return FALSE;
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // the constructor and setText always sets a length
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // and we only compare the string not the contents of the normalization
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // buffer
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int thislength = m_data_->iteratordata_.endp -
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     m_data_->iteratordata_.string;
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int thatlength = that.m_data_->iteratordata_.endp -
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                     that.m_data_->iteratordata_.string;
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (thislength != thatlength) {
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return FALSE;
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (uprv_memcmp(m_data_->iteratordata_.string,
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    that.m_data_->iteratordata_.string,
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    thislength * U_SIZEOF_UCHAR) != 0) {
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return FALSE;
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (getOffset() != that.getOffset()) {
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return FALSE;
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // checking normalization buffer
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if ((m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) == 0) {
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if ((that.m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) != 0) {
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return FALSE;
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // both are in the normalization buffer
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (m_data_->iteratordata_.pos
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            - m_data_->iteratordata_.writableBuffer
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            != that.m_data_->iteratordata_.pos
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            - that.m_data_->iteratordata_.writableBuffer) {
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            // not in the same position in the normalization buffer
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return FALSE;
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if ((that.m_data_->iteratordata_.flags & UCOL_ITER_HASLEN) == 0) {
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return FALSE;
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // checking ce position
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return (m_data_->iteratordata_.CEpos - m_data_->iteratordata_.CEs)
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            == (that.m_data_->iteratordata_.CEpos
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                        - that.m_data_->iteratordata_.CEs);
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/**
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Get the ordering priority of the previous collation element in the string.
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* @param status the error code status.
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* @return the previous element's ordering. Returns NULLORDER if an error has
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*         occured or if the start of string has been reached.
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32_t CollationElementIterator::previous(UErrorCode& status)
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return ucol_previous(m_data_, &status);
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/**
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Resets the cursor to the beginning of the string.
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CollationElementIterator::reset()
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucol_reset(m_data_);
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CollationElementIterator::setOffset(int32_t newOffset,
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         UErrorCode& status)
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucol_setOffset(m_data_, newOffset, &status);
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/**
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* Sets the source to the new source string.
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CollationElementIterator::setText(const UnicodeString& source,
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                       UErrorCode& status)
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(status)) {
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t length = source.length();
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *string = NULL;
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (m_data_->isWritable && m_data_->iteratordata_.string != NULL) {
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(m_data_->iteratordata_.string);
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_->isWritable = TRUE;
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (length > 0) {
185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length);
186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (string == NULL) {
188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        u_memcpy(string, source.getBuffer(), length);
192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else {
194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR);
195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (string == NULL) {
197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *string = 0;
201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Free offsetBuffer before initializing it. */
203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucol_freeOffsetBuffer(&(m_data_->iteratordata_));
204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_init_collIterate(m_data_->iteratordata_.coll, string, length,
205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        &m_data_->iteratordata_);
206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_->reset_   = TRUE;
208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Sets the source to the new character iterator.
211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid CollationElementIterator::setText(CharacterIterator& source,
212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                       UErrorCode& status)
213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(status))
215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t length = source.getLength();
218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *buffer = NULL;
219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (length == 0) {
221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR);
222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (buffer == NULL) {
224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *buffer = 0;
228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else {
230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length);
231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (buffer == NULL) {
233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*
237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Using this constructor will prevent buffer from being removed when
238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string gets removed
239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        */
240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        UnicodeString string;
241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        source.getText(string);
242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        u_memcpy(buffer, string.getBuffer(), length);
243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
245c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (m_data_->isWritable && m_data_->iteratordata_.string != NULL) {
246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        uprv_free(m_data_->iteratordata_.string);
247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_->isWritable = TRUE;
249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Free offsetBuffer before initializing it. */
250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    ucol_freeOffsetBuffer(&(m_data_->iteratordata_));
251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    uprv_init_collIterate(m_data_->iteratordata_.coll, buffer, length,
252c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        &m_data_->iteratordata_);
253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_->reset_   = TRUE;
254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32_t CollationElementIterator::strengthOrder(int32_t order) const
257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UCollationStrength s = ucol_getStrength(m_data_->iteratordata_.coll);
259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // Mask off the unwanted differences.
260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (s == UCOL_PRIMARY) {
261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        order &= RuleBasedCollator::PRIMARYDIFFERENCEONLY;
262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else if (s == UCOL_SECONDARY) {
264c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        order &= RuleBasedCollator::SECONDARYDIFFERENCEONLY;
265c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return order;
268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
269c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
270c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* CollationElementIterator private constructors/destructors --------------- */
271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/**
273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* This is the "real" constructor for this class; it constructs an iterator
274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* over the source text using the specified collator
275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCollationElementIterator::CollationElementIterator(
277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                               const UnicodeString& sourceText,
278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                               const RuleBasedCollator* order,
279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                               UErrorCode& status)
280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                               : isDataOwned_(TRUE)
281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(status)) {
283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t length = sourceText.length();
287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *string = NULL;
288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (length > 0) {
290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length);
291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (string == NULL) {
293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*
297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Using this constructor will prevent buffer from being removed when
298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string gets removed
299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        */
300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        u_memcpy(string, sourceText.getBuffer(), length);
301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else {
303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string = (UChar *)uprv_malloc(U_SIZEOF_UCHAR);
304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (string == NULL) {
306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *string = 0;
310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_ = ucol_openElements(order->ucollator, string, length, &status);
312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Test for buffer overflows */
314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(status)) {
315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_->isWritable = TRUE;
318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/**
321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* This is the "real" constructor for this class; it constructs an iterator over
322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott* the source text using the specified collator
323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott*/
324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCollationElementIterator::CollationElementIterator(
325c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const CharacterIterator& sourceText,
326c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           const RuleBasedCollator* order,
327c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           UErrorCode& status)
328c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                           : isDataOwned_(TRUE)
329c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
330c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(status))
331c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
332c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    // **** should I just drop this test? ****
334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /*
335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if ( sourceText.endIndex() != 0 )
336c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // A CollationElementIterator is really a two-layered beast.
338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // Internally it uses a Normalizer to munge the source text into a form
339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // where all "composed" Unicode characters (such as \u00FC) are split into a
340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // normal character and a combining accent character.
341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // Afterward, CollationElementIterator does its own processing to handle
342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // expanding and contracting collation sequences, ignorables, and so on.
343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Normalizer::EMode decomp = order->getStrength() == Collator::IDENTICAL
345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                ? Normalizer::NO_OP : order->getDecomposition();
346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        text = new Normalizer(sourceText, decomp);
348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (text == NULL)
349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        status = U_MEMORY_ALLOCATION_ERROR;
350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    */
352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    int32_t length = sourceText.getLength();
353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    UChar *buffer;
354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (length > 0) {
355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR * length);
356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (buffer == NULL) {
358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /*
362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        Using this constructor will prevent buffer from being removed when
363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        string gets removed
364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        */
365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        UnicodeString string(buffer, length, length);
366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ((CharacterIterator &)sourceText).getText(string);
367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        const UChar *temp = string.getBuffer();
368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        u_memcpy(buffer, temp, length);
369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    else {
371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        buffer = (UChar *)uprv_malloc(U_SIZEOF_UCHAR);
372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* test for NULL */
373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (buffer == NULL) {
374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            status = U_MEMORY_ALLOCATION_ERROR;
375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            return;
376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        *buffer = 0;
378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_ = ucol_openElements(order->ucollator, buffer, length, &status);
380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    /* Test for buffer overflows */
382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (U_FAILURE(status)) {
383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        return;
384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    m_data_->isWritable = TRUE;
386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* CollationElementIterator protected methods ----------------------------- */
389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst CollationElementIterator& CollationElementIterator::operator=(
391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                                         const CollationElementIterator& other)
392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    if (this != &other)
394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    {
395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        UCollationElements *ucolelem      = this->m_data_;
396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        UCollationElements *otherucolelem = other.m_data_;
397c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        collIterate        *coliter       = &(ucolelem->iteratordata_);
398c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        collIterate        *othercoliter  = &(otherucolelem->iteratordata_);
399c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        int                length         = 0;
400c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
401c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // checking only UCOL_ITER_HASLEN is not enough here as we may be in
402c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        // the normalization buffer
403c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        length = othercoliter->endp - othercoliter->string;
404c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
405c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ucolelem->reset_         = otherucolelem->reset_;
406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        ucolelem->isWritable     = TRUE;
407c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
408c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* create a duplicate of string */
409c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (length > 0) {
410c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->string = (UChar *)uprv_malloc(length * U_SIZEOF_UCHAR);
411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if(coliter->string != NULL) {
412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uprv_memcpy(coliter->string, othercoliter->string,
413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    length * U_SIZEOF_UCHAR);
414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            } else { // Error: couldn't allocate memory. No copying should be done
415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                length = 0;
416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else {
419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->string = NULL;
420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* start and end of string */
423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        coliter->endp = coliter->string + length;
424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* handle writable buffer here */
426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (othercoliter->flags & UCOL_ITER_INNORMBUF) {
428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uint32_t wlength = u_strlen(othercoliter->writableBuffer) + 1;
429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (wlength < coliter->writableBufSize) {
430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uprv_memcpy(coliter->stackWritableBuffer,
431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    othercoliter->stackWritableBuffer,
432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    wlength * U_SIZEOF_UCHAR);
433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            else {
435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if (coliter->writableBuffer != coliter->stackWritableBuffer) {
436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    uprv_free(coliter->writableBuffer);
437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                coliter->writableBuffer = (UChar *)uprv_malloc(
439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    wlength * U_SIZEOF_UCHAR);
440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                if(coliter->writableBuffer != NULL) {
441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    uprv_memcpy(coliter->writableBuffer,
442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        othercoliter->writableBuffer,
443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                        wlength * U_SIZEOF_UCHAR);
444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    coliter->writableBufSize = wlength;
445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                } else { // Error: couldn't allocate memory for writableBuffer
446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                    coliter->writableBufSize = 0;
447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                }
448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* current position */
452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (othercoliter->pos >= othercoliter->string &&
453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            othercoliter->pos <= othercoliter->endp)
454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        {
455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->pos = coliter->string +
456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                (othercoliter->pos - othercoliter->string);
457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else if (coliter->writableBuffer != NULL) {
459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->pos = coliter->writableBuffer +
460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                (othercoliter->pos - othercoliter->writableBuffer);
461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else {
463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            // Error: couldn't allocate memory for writableBuffer
464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->pos = NULL;
465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        /* CE buffer */
468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        int32_t CEsize;
469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (coliter->extendCEs) {
470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            uprv_memcpy(coliter->CEs, othercoliter->CEs, sizeof(uint32_t) * UCOL_EXPAND_CE_BUFFER_SIZE);
471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            CEsize = sizeof(othercoliter->extendCEs);
472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (CEsize > 0) {
473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                othercoliter->extendCEs = (uint32_t *)uprv_malloc(CEsize);
474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uprv_memcpy(coliter->extendCEs, othercoliter->extendCEs, CEsize);
475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->toReturn = coliter->extendCEs +
477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                (othercoliter->toReturn - othercoliter->extendCEs);
478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->CEpos    = coliter->extendCEs + CEsize;
479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        } else {
480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            CEsize = (int32_t)(othercoliter->CEpos - othercoliter->CEs);
481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            if (CEsize > 0) {
482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                uprv_memcpy(coliter->CEs, othercoliter->CEs, CEsize);
483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            }
484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->toReturn = coliter->CEs +
485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                (othercoliter->toReturn - othercoliter->CEs);
486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->CEpos    = coliter->CEs + CEsize;
487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        if (othercoliter->fcdPosition != NULL) {
490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->fcdPosition = coliter->string +
491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                (othercoliter->fcdPosition
492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott                - othercoliter->string);
493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        else {
495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott            coliter->fcdPosition = NULL;
496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        }
497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        coliter->flags       = othercoliter->flags/*| UCOL_ITER_HASLEN*/;
498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        coliter->origFlags   = othercoliter->origFlags;
499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        coliter->coll = othercoliter->coll;
500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott        this->isDataOwned_ = TRUE;
501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    }
502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    return *this;
504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottU_NAMESPACE_END
507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif /* #if !UCONFIG_NO_COLLATION */
509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* eof */
511