Esempio n. 1
0
int32_t
ChoiceFormat::findSubMessage(const MessagePattern &pattern, int32_t partIndex, double number) {
    int32_t count = pattern.countParts();
    int32_t msgStart;
    // Iterate over (ARG_INT|DOUBLE, ARG_SELECTOR, message) tuples
    // until ARG_LIMIT or end of choice-only pattern.
    // Ignore the first number and selector and start the loop on the first message.
    partIndex += 2;
    for (;;) {
        // Skip but remember the current sub-message.
        msgStart = partIndex;
        partIndex = pattern.getLimitPartIndex(partIndex);
        if (++partIndex >= count) {
            // Reached the end of the choice-only pattern.
            // Return with the last sub-message.
            break;
        }
        const MessagePattern::Part &part = pattern.getPart(partIndex++);
        UMessagePatternPartType type = part.getType();
        if (type == UMSGPAT_PART_TYPE_ARG_LIMIT) {
            // Reached the end of the ChoiceFormat style.
            // Return with the last sub-message.
            break;
        }
        // part is an ARG_INT or ARG_DOUBLE
        U_ASSERT(MessagePattern::Part::hasNumericValue(type));
        double boundary = pattern.getNumericValue(part);
        // Fetch the ARG_SELECTOR character.
        int32_t selectorIndex = pattern.getPatternIndex(partIndex++);
        UChar boundaryChar = pattern.getPatternString().charAt(selectorIndex);
        if (boundaryChar == LESS_THAN ? !(number > boundary) : !(number >= boundary)) {
            // The number is in the interval between the previous boundary and the current one.
            // Return with the sub-message between them.
            // The !(a>b) and !(a>=b) comparisons are equivalent to
            // (a<=b) and (a<b) except they "catch" NaN.
            break;
        }
    }
    return msgStart;
}
Esempio n. 2
0
int32_t
ChoiceFormat::matchStringUntilLimitPart(
        const MessagePattern &pattern, int32_t partIndex, int32_t limitPartIndex,
        const UnicodeString &source, int32_t sourceOffset) {
    int32_t matchingSourceLength = 0;
    const UnicodeString &msgString = pattern.getPatternString();
    int32_t prevIndex = pattern.getPart(partIndex).getLimit();
    for (;;) {
        const MessagePattern::Part &part = pattern.getPart(++partIndex);
        if (partIndex == limitPartIndex || part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) {
            int32_t index = part.getIndex();
            int32_t length = index - prevIndex;
            if (length != 0 && 0 != source.compare(sourceOffset, length, msgString, prevIndex, length)) {
                return -1;  // mismatch
            }
            matchingSourceLength += length;
            if (partIndex == limitPartIndex) {
                return matchingSourceLength;
            }
            prevIndex = part.getLimit();  // SKIP_SYNTAX
        }
    }
}