/*
*******************************************************************************
* Copyright (C) 2010-2014, International Business Machines
* Corporation and others.  All Rights Reserved.
*******************************************************************************
* collationiterator.cpp
*
* created on: 2010oct27
* created by: Markus W. Scherer
*/

#include "utypeinfo.h"  // for 'typeid' to work

#include "unicode/utypes.h"

#if !UCONFIG_NO_COLLATION

#include "unicode/ucharstrie.h"
#include "unicode/ustringtrie.h"
#include "charstr.h"
#include "cmemory.h"
#include "collation.h"
#include "collationdata.h"
#include "collationfcd.h"
#include "collationiterator.h"
#include "normalizer2impl.h"
#include "uassert.h"
#include "uvectr32.h"

U_NAMESPACE_BEGIN

CollationIterator::CEBuffer::~CEBuffer() {}

UBool
CollationIterator::CEBuffer::ensureAppendCapacity(int32_t appCap, UErrorCode &errorCode) {
    int32_t capacity = buffer.getCapacity();
    if((length + appCap) <= capacity) { return TRUE; }
    if(U_FAILURE(errorCode)) { return FALSE; }
    do {
        if(capacity < 1000) {
            capacity *= 4;
        } else {
            capacity *= 2;
        }
    } while(capacity < (length + appCap));
    int64_t *p = buffer.resize(capacity, length);
    if(p == NULL) {
        errorCode = U_MEMORY_ALLOCATION_ERROR;
        return FALSE;
    }
    return TRUE;
}

// State of combining marks skipped in discontiguous contraction.
// We create a state object on first use and keep it around deactivated between uses.
class SkippedState : public UMemory {
public:
    // Born active but empty.
    SkippedState() : pos(0), skipLengthAtMatch(0) {}
    void clear() {
        oldBuffer.remove();
        pos = 0;
        // The newBuffer is reset by setFirstSkipped().
    }

    UBool isEmpty() const { return oldBuffer.isEmpty(); }

    UBool hasNext() const { return pos < oldBuffer.length(); }

    // Requires hasNext().
    UChar32 next() {
        UChar32 c = oldBuffer.char32At(pos);
        pos += U16_LENGTH(c);
        return c;
    }

    // Accounts for one more input code point read beyond the end of the marks buffer.
    void incBeyond() {
        U_ASSERT(!hasNext());
        ++pos;
    }

    // Goes backward through the skipped-marks buffer.
    // Returns the number of code points read beyond the skipped marks
    // that need to be backtracked through normal input.
    int32_t backwardNumCodePoints(int32_t n) {
        int32_t length = oldBuffer.length();
        int32_t beyond = pos - length;
        if(beyond > 0) {
            if(beyond >= n) {
                // Not back far enough to re-enter the oldBuffer.
                pos -= n;
                return n;
            } else {
                // Back out all beyond-oldBuffer code points and re-enter the buffer.
                pos = oldBuffer.moveIndex32(length, beyond - n);
                return beyond;
            }
        } else {
            // Go backwards from inside the oldBuffer.
            pos = oldBuffer.moveIndex32(pos, -n);
            return 0;
        }
    }

    void setFirstSkipped(UChar32 c) {
        skipLengthAtMatch = 0;
        newBuffer.setTo(c);
    }

    void skip(UChar32 c) {
        newBuffer.append(c);
    }

    void recordMatch() { skipLengthAtMatch = newBuffer.length(); }

    // Replaces the characters we consumed with the newly skipped ones.
    void replaceMatch() {
        // Note: UnicodeString.replace() pins pos to at most length().
        oldBuffer.replace(0, pos, newBuffer, 0, skipLengthAtMatch);
        pos = 0;
    }

    void saveTrieState(const UCharsTrie &trie) { trie.saveState(state); }
    void resetToTrieState(UCharsTrie &trie) const { trie.resetToState(state); }

private:
    // Combining marks skipped in previous discontiguous-contraction matching.
    // After that discontiguous contraction was completed, we start reading them from here.
    UnicodeString oldBuffer;
    // Combining marks newly skipped in current discontiguous-contraction matching.
    // These might have been read from the normal text or from the oldBuffer.
    UnicodeString newBuffer;
    // Reading index in oldBuffer,
    // or counter for how many code points have been read beyond oldBuffer (pos-oldBuffer.length()).
    int32_t pos;
    // newBuffer.length() at the time of the last matching character.
    // When a partial match fails, we back out skipped and partial-matching input characters.
    int32_t skipLengthAtMatch;
    // We save the trie state before we attempt to match a character,
    // so that we can skip it and try the next one.
    UCharsTrie::State state;
};

CollationIterator::CollationIterator(const CollationIterator &other)
        : UObject(other),
          trie(other.trie),
          data(other.data),
          cesIndex(other.cesIndex),
          skipped(NULL),
          numCpFwd(other.numCpFwd),
          isNumeric(other.isNumeric) {
    UErrorCode errorCode = U_ZERO_ERROR;
    int32_t length = other.ceBuffer.length;
    if(length > 0 && ceBuffer.ensureAppendCapacity(length, errorCode)) {
        for(int32_t i = 0; i < length; ++i) {
            ceBuffer.set(i, other.ceBuffer.get(i));
        }
        ceBuffer.length = length;
    } else {
        cesIndex = 0;
    }
}

CollationIterator::~CollationIterator() {
    delete skipped;
}

UBool
CollationIterator::operator==(const CollationIterator &other) const {
    // Subclasses: Call this method and then add more specific checks.
    // Compare the iterator state but not the collation data (trie & data fields):
    // Assume that the caller compares the data.
    // Ignore skipped since that should be unused between calls to nextCE().
    // (It only stays around to avoid another memory allocation.)
    if(!(typeid(*this) == typeid(other) &&
            ceBuffer.length == other.ceBuffer.length &&
            cesIndex == other.cesIndex &&
            numCpFwd == other.numCpFwd &&
            isNumeric == other.isNumeric)) {
        return FALSE;
    }
    for(int32_t i = 0; i < ceBuffer.length; ++i) {
        if(ceBuffer.get(i) != other.ceBuffer.get(i)) { return FALSE; }
    }
    return TRUE;
}

void
CollationIterator::reset() {
    cesIndex = ceBuffer.length = 0;
    if(skipped != NULL) { skipped->clear(); }
}

int32_t
CollationIterator::fetchCEs(UErrorCode &errorCode) {
    while(U_SUCCESS(errorCode) && nextCE(errorCode) != Collation::NO_CE) {
        // No need to loop for each expansion CE.
        cesIndex = ceBuffer.length;
    }
    return ceBuffer.length;
}

uint32_t
CollationIterator::handleNextCE32(UChar32 &c, UErrorCode &errorCode) {
    c = nextCodePoint(errorCode);
    return (c < 0) ? Collation::FALLBACK_CE32 : data->getCE32(c);
}

UChar
CollationIterator::handleGetTrailSurrogate() {
    return 0;
}

UBool
CollationIterator::foundNULTerminator() {
    return FALSE;
}

UBool
CollationIterator::forbidSurrogateCodePoints() const {
    return FALSE;
}

uint32_t
CollationIterator::getDataCE32(UChar32 c) const {
    return data->getCE32(c);
}

uint32_t
CollationIterator::getCE32FromBuilderData(uint32_t /*ce32*/, UErrorCode &errorCode) {
    if(U_SUCCESS(errorCode)) { errorCode = U_INTERNAL_PROGRAM_ERROR; }
    return 0;
}

int64_t
CollationIterator::nextCEFromCE32(const CollationData *d, UChar32 c, uint32_t ce32,
                                  UErrorCode &errorCode) {
    --ceBuffer.length;  // Undo ceBuffer.incLength().
    appendCEsFromCE32(d, c, ce32, TRUE, errorCode);
    if(U_SUCCESS(errorCode)) {
        return ceBuffer.get(cesIndex++);
    } else {
        return Collation::NO_CE_PRIMARY;
    }
}

void
CollationIterator::appendCEsFromCE32(const CollationData *d, UChar32 c, uint32_t ce32,
                                     UBool forward, UErrorCode &errorCode) {
    while(Collation::isSpecialCE32(ce32)) {
        switch(Collation::tagFromCE32(ce32)) {
        case Collation::FALLBACK_TAG:
        case Collation::RESERVED_TAG_3:
            if(U_SUCCESS(errorCode)) { errorCode = U_INTERNAL_PROGRAM_ERROR; }
            return;
        case Collation::LONG_PRIMARY_TAG:
            ceBuffer.append(Collation::ceFromLongPrimaryCE32(ce32), errorCode);
            return;
        case Collation::LONG_SECONDARY_TAG:
            ceBuffer.append(Collation::ceFromLongSecondaryCE32(ce32), errorCode);
            return;
        case Collation::LATIN_EXPANSION_TAG:
            if(ceBuffer.ensureAppendCapacity(2, errorCode)) {
                ceBuffer.set(ceBuffer.length, Collation::latinCE0FromCE32(ce32));
                ceBuffer.set(ceBuffer.length + 1, Collation::latinCE1FromCE32(ce32));
                ceBuffer.length += 2;
            }
            return;
        case Collation::EXPANSION32_TAG: {
            const uint32_t *ce32s = d->ce32s + Collation::indexFromCE32(ce32);
            int32_t length = Collation::lengthFromCE32(ce32);
            if(ceBuffer.ensureAppendCapacity(length, errorCode)) {
                do {
                    ceBuffer.appendUnsafe(Collation::ceFromCE32(*ce32s++));
                } while(--length > 0);
            }
            return;
        }
        case Collation::EXPANSION_TAG: {
            const int64_t *ces = d->ces + Collation::indexFromCE32(ce32);
            int32_t length = Collation::lengthFromCE32(ce32);
            if(ceBuffer.ensureAppendCapacity(length, errorCode)) {
                do {
                    ceBuffer.appendUnsafe(*ces++);
                } while(--length > 0);
            }
            return;
        }
        case Collation::BUILDER_DATA_TAG:
            ce32 = getCE32FromBuilderData(ce32, errorCode);
            if(U_FAILURE(errorCode)) { return; }
            if(ce32 == Collation::FALLBACK_CE32) {
                d = data->base;
                ce32 = d->getCE32(c);
            }
            break;
        case Collation::PREFIX_TAG:
            if(forward) { backwardNumCodePoints(1, errorCode); }
            ce32 = getCE32FromPrefix(d, ce32, errorCode);
            if(forward) { forwardNumCodePoints(1, errorCode); }
            break;
        case Collation::CONTRACTION_TAG: {
            const UChar *p = d->contexts + Collation::indexFromCE32(ce32);
            uint32_t defaultCE32 = CollationData::readCE32(p);  // Default if no suffix match.
            if(!forward) {
                // Backward contractions are handled by previousCEUnsafe().
                // c has contractions but they were not found.
                ce32 = defaultCE32;
                break;
            }
            UChar32 nextCp;
            if(skipped == NULL && numCpFwd < 0) {
                // Some portion of nextCE32FromContraction() pulled out here as an ASCII fast path,
                // avoiding the function call and the nextSkippedCodePoint() overhead.
                nextCp = nextCodePoint(errorCode);
                if(nextCp < 0) {
                    // No more text.
                    ce32 = defaultCE32;
                    break;
                } else if((ce32 & Collation::CONTRACT_NEXT_CCC) != 0 &&
                        !CollationFCD::mayHaveLccc(nextCp)) {
                    // All contraction suffixes start with characters with lccc!=0
                    // but the next code point has lccc==0.
                    backwardNumCodePoints(1, errorCode);
                    ce32 = defaultCE32;
                    break;
                }
            } else {
                nextCp = nextSkippedCodePoint(errorCode);
                if(nextCp < 0) {
                    // No more text.
                    ce32 = defaultCE32;
                    break;
                } else if((ce32 & Collation::CONTRACT_NEXT_CCC) != 0 &&
                        !CollationFCD::mayHaveLccc(nextCp)) {
                    // All contraction suffixes start with characters with lccc!=0
                    // but the next code point has lccc==0.
                    backwardNumSkipped(1, errorCode);
                    ce32 = defaultCE32;
                    break;
                }
            }
            ce32 = nextCE32FromContraction(d, ce32, p + 2, defaultCE32, nextCp, errorCode);
            if(ce32 == Collation::NO_CE32) {
                // CEs from a discontiguous contraction plus the skipped combining marks
                // have been appended already.
                return;
            }
            break;
        }
        case Collation::DIGIT_TAG:
            if(isNumeric) {
                appendNumericCEs(ce32, forward, errorCode);
                return;
            } else {
                // Fetch the non-numeric-collation CE32 and continue.
                ce32 = d->ce32s[Collation::indexFromCE32(ce32)];
                break;
            }
        case Collation::U0000_TAG:
            U_ASSERT(c == 0);
            if(forward && foundNULTerminator()) {
                // Handle NUL-termination. (Not needed in Java.)
                ceBuffer.append(Collation::NO_CE, errorCode);
                return;
            } else {
                // Fetch the normal ce32 for U+0000 and continue.
                ce32 = d->ce32s[0];
                break;
            }
        case Collation::HANGUL_TAG: {
            const uint32_t *jamoCE32s = d->jamoCE32s;
            c -= Hangul::HANGUL_BASE;
            UChar32 t = c % Hangul::JAMO_T_COUNT;
            c /= Hangul::JAMO_T_COUNT;
            UChar32 v = c % Hangul::JAMO_V_COUNT;
            c /= Hangul::JAMO_V_COUNT;
            if((ce32 & Collation::HANGUL_NO_SPECIAL_JAMO) != 0) {
                // None of the Jamo CE32s are isSpecialCE32().
                // Avoid recursive function calls and per-Jamo tests.
                if(ceBuffer.ensureAppendCapacity(t == 0 ? 2 : 3, errorCode)) {
                    ceBuffer.set(ceBuffer.length, Collation::ceFromCE32(jamoCE32s[c]));
                    ceBuffer.set(ceBuffer.length + 1, Collation::ceFromCE32(jamoCE32s[19 + v]));
                    ceBuffer.length += 2;
                    if(t != 0) {
                        ceBuffer.appendUnsafe(Collation::ceFromCE32(jamoCE32s[39 + t]));
                    }
                }
                return;
            } else {
                // We should not need to compute each Jamo code point.
                // In particular, there should be no offset or implicit ce32.
                appendCEsFromCE32(d, U_SENTINEL, jamoCE32s[c], forward, errorCode);
                appendCEsFromCE32(d, U_SENTINEL, jamoCE32s[19 + v], forward, errorCode);
                if(t == 0) { return; }
                // offset 39 = 19 + 21 - 1:
                // 19 = JAMO_L_COUNT
                // 21 = JAMO_T_COUNT
                // -1 = omit t==0
                ce32 = jamoCE32s[39 + t];
                c = U_SENTINEL;
                break;
            }
        }
        case Collation::LEAD_SURROGATE_TAG: {
            U_ASSERT(forward);  // Backward iteration should never see lead surrogate code _unit_ data.
            U_ASSERT(U16_IS_LEAD(c));
            UChar trail;
            if(U16_IS_TRAIL(trail = handleGetTrailSurrogate())) {
                c = U16_GET_SUPPLEMENTARY(c, trail);
                ce32 &= Collation::LEAD_TYPE_MASK;
                if(ce32 == Collation::LEAD_ALL_UNASSIGNED) {
                    ce32 = Collation::UNASSIGNED_CE32;  // unassigned-implicit
                } else if(ce32 == Collation::LEAD_ALL_FALLBACK ||
                        (ce32 = d->getCE32FromSupplementary(c)) == Collation::FALLBACK_CE32) {
                    // fall back to the base data
                    d = d->base;
                    ce32 = d->getCE32FromSupplementary(c);
                }
            } else {
                // c is an unpaired surrogate.
                ce32 = Collation::UNASSIGNED_CE32;
            }
            break;
        }
        case Collation::OFFSET_TAG:
            U_ASSERT(c >= 0);
            ceBuffer.append(d->getCEFromOffsetCE32(c, ce32), errorCode);
            return;
        case Collation::IMPLICIT_TAG:
            U_ASSERT(c >= 0);
            if(U_IS_SURROGATE(c) && forbidSurrogateCodePoints()) {
                ce32 = Collation::FFFD_CE32;
                break;
            } else {
                ceBuffer.append(Collation::unassignedCEFromCodePoint(c), errorCode);
                return;
            }
        }
    }
    ceBuffer.append(Collation::ceFromSimpleCE32(ce32), errorCode);
}

uint32_t
CollationIterator::getCE32FromPrefix(const CollationData *d, uint32_t ce32,
                                     UErrorCode &errorCode) {
    const UChar *p = d->contexts + Collation::indexFromCE32(ce32);
    ce32 = CollationData::readCE32(p);  // Default if no prefix match.
    p += 2;
    // Number of code points read before the original code point.
    int32_t lookBehind = 0;
    UCharsTrie prefixes(p);
    for(;;) {
        UChar32 c = previousCodePoint(errorCode);
        if(c < 0) { break; }
        ++lookBehind;
        UStringTrieResult match = prefixes.nextForCodePoint(c);
        if(USTRINGTRIE_HAS_VALUE(match)) {
            ce32 = (uint32_t)prefixes.getValue();
        }
        if(!USTRINGTRIE_HAS_NEXT(match)) { break; }
    }
    forwardNumCodePoints(lookBehind, errorCode);
    return ce32;
}

UChar32
CollationIterator::nextSkippedCodePoint(UErrorCode &errorCode) {
    if(skipped != NULL && skipped->hasNext()) { return skipped->next(); }
    if(numCpFwd == 0) { return U_SENTINEL; }
    UChar32 c = nextCodePoint(errorCode);
    if(skipped != NULL && !skipped->isEmpty() && c >= 0) { skipped->incBeyond(); }
    if(numCpFwd > 0 && c >= 0) { --numCpFwd; }
    return c;
}

void
CollationIterator::backwardNumSkipped(int32_t n, UErrorCode &errorCode) {
    if(skipped != NULL && !skipped->isEmpty()) {
        n = skipped->backwardNumCodePoints(n);
    }
    backwardNumCodePoints(n, errorCode);
    if(numCpFwd >= 0) { numCpFwd += n; }
}

uint32_t
CollationIterator::nextCE32FromContraction(const CollationData *d, uint32_t contractionCE32,
                                           const UChar *p, uint32_t ce32, UChar32 c,
                                           UErrorCode &errorCode) {
    // c: next code point after the original one

    // Number of code points read beyond the original code point.
    // Needed for discontiguous contraction matching.
    int32_t lookAhead = 1;
    // Number of code points read since the last match (initially only c).
    int32_t sinceMatch = 1;
    // Normally we only need a contiguous match,
    // and therefore need not remember the suffixes state from before a mismatch for retrying.
    // If we are already processing skipped combining marks, then we do track the state.
    UCharsTrie suffixes(p);
    if(skipped != NULL && !skipped->isEmpty()) { skipped->saveTrieState(suffixes); }
    UStringTrieResult match = suffixes.firstForCodePoint(c);
    for(;;) {
        UChar32 nextCp;
        if(USTRINGTRIE_HAS_VALUE(match)) {
            ce32 = (uint32_t)suffixes.getValue();
            if(!USTRINGTRIE_HAS_NEXT(match) || (c = nextSkippedCodePoint(errorCode)) < 0) {
                return ce32;
            }
            if(skipped != NULL && !skipped->isEmpty()) { skipped->saveTrieState(suffixes); }
            sinceMatch = 1;
        } else if(match == USTRINGTRIE_NO_MATCH || (nextCp = nextSkippedCodePoint(errorCode)) < 0) {
            // No match for c, or partial match (USTRINGTRIE_NO_VALUE) and no further text.
            // Back up if necessary, and try a discontiguous contraction.
            if((contractionCE32 & Collation::CONTRACT_TRAILING_CCC) != 0 &&
                    // Discontiguous contraction matching extends an existing match.
                    // If there is no match yet, then there is nothing to do.
                    ((contractionCE32 & Collation::CONTRACT_SINGLE_CP_NO_MATCH) == 0 ||
                        sinceMatch < lookAhead)) {
                // The last character of at least one suffix has lccc!=0,
                // allowing for discontiguous contractions.
                // UCA S2.1.1 only processes non-starters immediately following
                // "a match in the table" (sinceMatch=1).
                if(sinceMatch > 1) {
                    // Return to the state after the last match.
                    // (Return to sinceMatch=0 and re-fetch the first partially-matched character.)
                    backwardNumSkipped(sinceMatch, errorCode);
                    c = nextSkippedCodePoint(errorCode);
                    lookAhead -= sinceMatch - 1;
                    sinceMatch = 1;
                }
                if(d->getFCD16(c) > 0xff) {
                    return nextCE32FromDiscontiguousContraction(
                        d, suffixes, ce32, lookAhead, c, errorCode);
                }
            }
            break;
        } else {
            // Continue after partial match (USTRINGTRIE_NO_VALUE) for c.
            // It does not have a result value, therefore it is not itself "a match in the table".
            // If a partially-matched c has ccc!=0 then
            // it might be skipped in discontiguous contraction.
            c = nextCp;
            ++sinceMatch;
        }
        ++lookAhead;
        match = suffixes.nextForCodePoint(c);
    }
    backwardNumSkipped(sinceMatch, errorCode);
    return ce32;
}

uint32_t
CollationIterator::nextCE32FromDiscontiguousContraction(
        const CollationData *d, UCharsTrie &suffixes, uint32_t ce32,
        int32_t lookAhead, UChar32 c,
        UErrorCode &errorCode) {
    if(U_FAILURE(errorCode)) { return 0; }

    // UCA section 3.3.2 Contractions:
    // Contractions that end with non-starter characters
    // are known as discontiguous contractions.
    // ... discontiguous contractions must be detected in input text
    // whenever the final sequence of non-starter characters could be rearranged
    // so as to make a contiguous matching sequence that is canonically equivalent.

    // UCA: http://www.unicode.org/reports/tr10/#S2.1
    // S2.1 Find the longest initial substring S at each point that has a match in the table.
    // S2.1.1 If there are any non-starters following S, process each non-starter C.
    // S2.1.2 If C is not blocked from S, find if S + C has a match in the table.
    //     Note: A non-starter in a string is called blocked
    //     if there is another non-starter of the same canonical combining class or zero
    //     between it and the last character of canonical combining class 0.
    // S2.1.3 If there is a match, replace S by S + C, and remove C.

    // First: Is a discontiguous contraction even possible?
    uint16_t fcd16 = d->getFCD16(c);
    U_ASSERT(fcd16 > 0xff);  // The caller checked this already, as a shortcut.
    UChar32 nextCp = nextSkippedCodePoint(errorCode);
    if(nextCp < 0) {
        // No further text.
        backwardNumSkipped(1, errorCode);
        return ce32;
    }
    ++lookAhead;
    uint8_t prevCC = (uint8_t)fcd16;
    fcd16 = d->getFCD16(nextCp);
    if(fcd16 <= 0xff) {
        // The next code point after c is a starter (S2.1.1 "process each non-starter").
        backwardNumSkipped(2, errorCode);
        return ce32;
    }

    // We have read and matched (lookAhead-2) code points,
    // read non-matching c and peeked ahead at nextCp.
    // Return to the state before the mismatch and continue matching with nextCp.
    if(skipped == NULL || skipped->isEmpty()) {
        if(skipped == NULL) {
            skipped = new SkippedState();
            if(skipped == NULL) {
                errorCode = U_MEMORY_ALLOCATION_ERROR;
                return 0;
            }
        }
        suffixes.reset();
        if(lookAhead > 2) {
            // Replay the partial match so far.
            backwardNumCodePoints(lookAhead, errorCode);
            suffixes.firstForCodePoint(nextCodePoint(errorCode));
            for(int32_t i = 3; i < lookAhead; ++i) {
                suffixes.nextForCodePoint(nextCodePoint(errorCode));
            }
            // Skip c (which did not match) and nextCp (which we will try now).
            forwardNumCodePoints(2, errorCode);
        }
        skipped->saveTrieState(suffixes);
    } else {
        // Reset to the trie state before the failed match of c.
        skipped->resetToTrieState(suffixes);
    }

    skipped->setFirstSkipped(c);
    // Number of code points read since the last match (at this point: c and nextCp).
    int32_t sinceMatch = 2;
    c = nextCp;
    for(;;) {
        UStringTrieResult match;
        // "If C is not blocked from S, find if S + C has a match in the table." (S2.1.2)
        if(prevCC < (fcd16 >> 8) && USTRINGTRIE_HAS_VALUE(match = suffixes.nextForCodePoint(c))) {
            // "If there is a match, replace S by S + C, and remove C." (S2.1.3)
            // Keep prevCC unchanged.
            ce32 = (uint32_t)suffixes.getValue();
            sinceMatch = 0;
            skipped->recordMatch();
            if(!USTRINGTRIE_HAS_NEXT(match)) { break; }
            skipped->saveTrieState(suffixes);
        } else {
            // No match for "S + C", skip C.
            skipped->skip(c);
            skipped->resetToTrieState(suffixes);
            prevCC = (uint8_t)fcd16;
        }
        if((c = nextSkippedCodePoint(errorCode)) < 0) { break; }
        ++sinceMatch;
        fcd16 = d->getFCD16(c);
        if(fcd16 <= 0xff) {
            // The next code point after c is a starter (S2.1.1 "process each non-starter").
            break;
        }
    }
    backwardNumSkipped(sinceMatch, errorCode);
    UBool isTopDiscontiguous = skipped->isEmpty();
    skipped->replaceMatch();
    if(isTopDiscontiguous && !skipped->isEmpty()) {
        // We did get a match after skipping one or more combining marks,
        // and we are not in a recursive discontiguous contraction.
        // Append CEs from the contraction ce32
        // and then from the combining marks that we skipped before the match.
        c = U_SENTINEL;
        for(;;) {
            appendCEsFromCE32(d, c, ce32, TRUE, errorCode);
            // Fetch CE32s for skipped combining marks from the normal data, with fallback,
            // rather than from the CollationData where we found the contraction.
            if(!skipped->hasNext()) { break; }
            c = skipped->next();
            ce32 = getDataCE32(c);
            if(ce32 == Collation::FALLBACK_CE32) {
                d = data->base;
                ce32 = d->getCE32(c);
            } else {
                d = data;
            }
            // Note: A nested discontiguous-contraction match
            // replaces consumed combining marks with newly skipped ones
            // and resets the reading position to the beginning.
        }
        skipped->clear();
        ce32 = Collation::NO_CE32;  // Signal to the caller that the result is in the ceBuffer.
    }
    return ce32;
}

void
CollationIterator::appendNumericCEs(uint32_t ce32, UBool forward, UErrorCode &errorCode) {
    // Collect digits.
    CharString digits;
    if(forward) {
        for(;;) {
            char digit = Collation::digitFromCE32(ce32);
            digits.append(digit, errorCode);
            if(numCpFwd == 0) { break; }
            UChar32 c = nextCodePoint(errorCode);
            if(c < 0) { break; }
            ce32 = data->getCE32(c);
            if(ce32 == Collation::FALLBACK_CE32) {
                ce32 = data->base->getCE32(c);
            }
            if(!Collation::hasCE32Tag(ce32, Collation::DIGIT_TAG)) {
                backwardNumCodePoints(1, errorCode);
                break;
            }
            if(numCpFwd > 0) { --numCpFwd; }
        }
    } else {
        for(;;) {
            char digit = Collation::digitFromCE32(ce32);
            digits.append(digit, errorCode);
            UChar32 c = previousCodePoint(errorCode);
            if(c < 0) { break; }
            ce32 = data->getCE32(c);
            if(ce32 == Collation::FALLBACK_CE32) {
                ce32 = data->base->getCE32(c);
            }
            if(!Collation::hasCE32Tag(ce32, Collation::DIGIT_TAG)) {
                forwardNumCodePoints(1, errorCode);
                break;
            }
        }
        // Reverse the digit string.
        char *p = digits.data();
        char *q = p + digits.length() - 1;
        while(p < q) {
            char digit = *p;
            *p++ = *q;
            *q-- = digit;
        }
    }
    if(U_FAILURE(errorCode)) { return; }
    int32_t pos = 0;
    do {
        // Skip leading zeros.
        while(pos < (digits.length() - 1) && digits[pos] == 0) { ++pos; }
        // Write a sequence of CEs for at most 254 digits at a time.
        int32_t segmentLength = digits.length() - pos;
        if(segmentLength > 254) { segmentLength = 254; }
        appendNumericSegmentCEs(digits.data() + pos, segmentLength, errorCode);
        pos += segmentLength;
    } while(U_SUCCESS(errorCode) && pos < digits.length());
}

void
CollationIterator::appendNumericSegmentCEs(const char *digits, int32_t length, UErrorCode &errorCode) {
    U_ASSERT(1 <= length && length <= 254);
    U_ASSERT(length == 1 || digits[0] != 0);
    uint32_t numericPrimary = data->numericPrimary;
    // Note: We use primary byte values 2..255: digits are not compressible.
    if(length <= 7) {
        // Very dense encoding for small numbers.
        int32_t value = digits[0];
        for(int32_t i = 1; i < length; ++i) {
            value = value * 10 + digits[i];
        }
        // Primary weight second byte values:
        //     74 byte values   2.. 75 for small numbers in two-byte primary weights.
        //     40 byte values  76..115 for medium numbers in three-byte primary weights.
        //     16 byte values 116..131 for large numbers in four-byte primary weights.
        //    124 byte values 132..255 for very large numbers with 4..127 digit pairs.
        int32_t firstByte = 2;
        int32_t numBytes = 74;
        if(value < numBytes) {
            // Two-byte primary for 0..73, good for day & month numbers etc.
            uint32_t primary = numericPrimary | ((firstByte + value) << 16);
            ceBuffer.append(Collation::makeCE(primary), errorCode);
            return;
        }
        value -= numBytes;
        firstByte += numBytes;
        numBytes = 40;
        if(value < numBytes * 254) {
            // Three-byte primary for 74..10233=74+40*254-1, good for year numbers and more.
            uint32_t primary = numericPrimary |
                ((firstByte + value / 254) << 16) | ((2 + value % 254) << 8);
            ceBuffer.append(Collation::makeCE(primary), errorCode);
            return;
        }
        value -= numBytes * 254;
        firstByte += numBytes;
        numBytes = 16;
        if(value < numBytes * 254 * 254) {
            // Four-byte primary for 10234..1042489=10234+16*254*254-1.
            uint32_t primary = numericPrimary | (2 + value % 254);
            value /= 254;
            primary |= (2 + value % 254) << 8;
            value /= 254;
            primary |= (firstByte + value % 254) << 16;
            ceBuffer.append(Collation::makeCE(primary), errorCode);
            return;
        }
        // original value > 1042489
    }
    U_ASSERT(length >= 7);

    // The second primary byte value 132..255 indicates the number of digit pairs (4..127),
    // then we generate primary bytes with those pairs.
    // Omit trailing 00 pairs.
    // Decrement the value for the last pair.

    // Set the exponent. 4 pairs->132, 5 pairs->133, ..., 127 pairs->255.
    int32_t numPairs = (length + 1) / 2;
    uint32_t primary = numericPrimary | ((132 - 4 + numPairs) << 16);
    // Find the length without trailing 00 pairs.
    while(digits[length - 1] == 0 && digits[length - 2] == 0) {
        length -= 2;
    }
    // Read the first pair.
    uint32_t pair;
    int32_t pos;
    if(length & 1) {
        // Only "half a pair" if we have an odd number of digits.
        pair = digits[0];
        pos = 1;
    } else {
        pair = digits[0] * 10 + digits[1];
        pos = 2;
    }
    pair = 11 + 2 * pair;
    // Add the pairs of digits between pos and length.
    int32_t shift = 8;
    while(pos < length) {
        if(shift == 0) {
            // Every three pairs/bytes we need to store a 4-byte-primary CE
            // and start with a new CE with the '0' primary lead byte.
            primary |= pair;
            ceBuffer.append(Collation::makeCE(primary), errorCode);
            primary = numericPrimary;
            shift = 16;
        } else {
            primary |= pair << shift;
            shift -= 8;
        }
        pair = 11 + 2 * (digits[pos] * 10 + digits[pos + 1]);
        pos += 2;
    }
    primary |= (pair - 1) << shift;
    ceBuffer.append(Collation::makeCE(primary), errorCode);
}

int64_t
CollationIterator::previousCE(UVector32 &offsets, UErrorCode &errorCode) {
    if(ceBuffer.length > 0) {
        // Return the previous buffered CE.
        return ceBuffer.get(--ceBuffer.length);
    }
    offsets.removeAllElements();
    int32_t limitOffset = getOffset();
    UChar32 c = previousCodePoint(errorCode);
    if(c < 0) { return Collation::NO_CE; }
    if(data->isUnsafeBackward(c, isNumeric)) {
        return previousCEUnsafe(c, offsets, errorCode);
    }
    // Simple, safe-backwards iteration:
    // Get a CE going backwards, handle prefixes but no contractions.
    uint32_t ce32 = data->getCE32(c);
    const CollationData *d;
    if(ce32 == Collation::FALLBACK_CE32) {
        d = data->base;
        ce32 = d->getCE32(c);
    } else {
        d = data;
    }
    if(Collation::isSimpleOrLongCE32(ce32)) {
        return Collation::ceFromCE32(ce32);
    }
    appendCEsFromCE32(d, c, ce32, FALSE, errorCode);
    if(U_SUCCESS(errorCode)) {
        if(ceBuffer.length > 1) {
            offsets.addElement(getOffset(), errorCode);
            // For an expansion, the offset of each non-initial CE is the limit offset,
            // consistent with forward iteration.
            while(offsets.size() <= ceBuffer.length) {
                offsets.addElement(limitOffset, errorCode);
            };
        }
        return ceBuffer.get(--ceBuffer.length);
    } else {
        return Collation::NO_CE_PRIMARY;
    }
}

int64_t
CollationIterator::previousCEUnsafe(UChar32 c, UVector32 &offsets, UErrorCode &errorCode) {
    // We just move through the input counting safe and unsafe code points
    // without collecting the unsafe-backward substring into a buffer and
    // switching to it.
    // This is to keep the logic simple. Otherwise we would have to handle
    // prefix matching going before the backward buffer, switching
    // to iteration and back, etc.
    // In the most important case of iterating over a normal string,
    // reading from the string itself is already maximally fast.
    // The only drawback there is that after getting the CEs we always
    // skip backward to the safe character rather than switching out
    // of a backwardBuffer.
    // But this should not be the common case for previousCE(),
    // and correctness and maintainability are more important than
    // complex optimizations.
    // Find the first safe character before c.
    int32_t numBackward = 1;
    while((c = previousCodePoint(errorCode)) >= 0) {
        ++numBackward;
        if(!data->isUnsafeBackward(c, isNumeric)) {
            break;
        }
    }
    // Set the forward iteration limit.
    // Note: This counts code points.
    // We cannot enforce a limit in the middle of a surrogate pair or similar.
    numCpFwd = numBackward;
    // Reset the forward iterator.
    cesIndex = 0;
    U_ASSERT(ceBuffer.length == 0);
    // Go forward and collect the CEs.
    int32_t offset = getOffset();
    while(numCpFwd > 0) {
        // nextCE() normally reads one code point.
        // Contraction matching and digit specials read more and check numCpFwd.
        --numCpFwd;
        // Append one or more CEs to the ceBuffer.
        (void)nextCE(errorCode);
        U_ASSERT(U_FAILURE(errorCode) || ceBuffer.get(ceBuffer.length - 1) != Collation::NO_CE);
        // No need to loop for getting each expansion CE from nextCE().
        cesIndex = ceBuffer.length;
        // However, we need to write an offset for each CE.
        // This is for CollationElementIterator::getOffset() to return
        // intermediate offsets from the unsafe-backwards segment.
        U_ASSERT(offsets.size() < ceBuffer.length);
        offsets.addElement(offset, errorCode);
        // For an expansion, the offset of each non-initial CE is the limit offset,
        // consistent with forward iteration.
        offset = getOffset();
        while(offsets.size() < ceBuffer.length) {
            offsets.addElement(offset, errorCode);
        };
    }
    U_ASSERT(offsets.size() == ceBuffer.length);
    // End offset corresponding to just after the unsafe-backwards segment.
    offsets.addElement(offset, errorCode);
    // Reset the forward iteration limit
    // and move backward to before the segment for which we fetched CEs.
    numCpFwd = -1;
    backwardNumCodePoints(numBackward, errorCode);
    // Use the collected CEs and return the last one.
    cesIndex = 0;  // Avoid cesIndex > ceBuffer.length when that gets decremented.
    if(U_SUCCESS(errorCode)) {
        return ceBuffer.get(--ceBuffer.length);
    } else {
        return Collation::NO_CE_PRIMARY;
    }
}

U_NAMESPACE_END

#endif  // !UCONFIG_NO_COLLATION
