UnicodeString& SimplePatternFormatter::formatAndAppend(
        const UnicodeString * const *placeholderValues,
        int32_t placeholderValueCount,
        UnicodeString &appendTo,
        int32_t *offsetArray,
        int32_t offsetArrayLength,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return appendTo;
    }
    if (isInvalidArray(placeholderValues, placeholderValueCount)
            || isInvalidArray(offsetArray, offsetArrayLength)) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    if (placeholderValueCount < placeholderCount) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    
    // Since we are disallowing parameter values that are the same as
    // appendTo, we have to check all placeholderValues as opposed to
    // the first placeholderCount placeholder values.
    SimplePatternFormatterPlaceholderValues values(
            placeholderValues, placeholderValueCount);
    if (values.isAppendToInAnyIndexExcept(appendTo, -1)) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    return formatAndAppend(
            values,
            appendTo,
            offsetArray,
            offsetArrayLength);
}
Beispiel #2
0
UnicodeString &SimpleFormatter::formatAndReplace(
        const UnicodeString *const *values, int32_t valuesLength,
        UnicodeString &result,
        int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const {
    if (U_FAILURE(errorCode)) {
        return result;
    }
    if (isInvalidArray(values, valuesLength) || isInvalidArray(offsets, offsetsLength)) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }
    const UChar *cp = compiledPattern.getBuffer();
    int32_t cpLength = compiledPattern.length();
    if (valuesLength < getArgumentLimit(cp, cpLength)) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }

    // If the pattern starts with an argument whose value is the same object
    // as the result, then we keep the result contents and append to it.
    // Otherwise we replace its contents.
    int32_t firstArg = -1;
    // If any non-initial argument value is the same object as the result,
    // then we first copy its contents and use that instead while formatting.
    UnicodeString resultCopy;
    if (getArgumentLimit(cp, cpLength) > 0) {
        for (int32_t i = 1; i < cpLength;) {
            int32_t n = cp[i++];
            if (n < ARG_NUM_LIMIT) {
                if (values[n] == &result) {
                    if (i == 2) {
                        firstArg = n;
                    } else if (resultCopy.isEmpty() && !result.isEmpty()) {
                        resultCopy = result;
                    }
                }
            } else {
                i += n - ARG_NUM_LIMIT;
            }
        }
    }
    if (firstArg < 0) {
        result.remove();
    }
    return format(cp, cpLength, values,
                  result, &resultCopy, FALSE,
                  offsets, offsetsLength, errorCode);
}
Beispiel #3
0
UnicodeString& SimpleFormatter::formatAndAppend(
        const UnicodeString *const *values, int32_t valuesLength,
        UnicodeString &appendTo,
        int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const {
    if (U_FAILURE(errorCode)) {
        return appendTo;
    }
    if (isInvalidArray(values, valuesLength) || isInvalidArray(offsets, offsetsLength) ||
            valuesLength < getArgumentLimit()) {
        errorCode = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }
    return format(compiledPattern.getBuffer(), compiledPattern.length(), values,
                  appendTo, NULL, TRUE,
                  offsets, offsetsLength, errorCode);
}
UnicodeString& SimplePatternFormatter::formatAndReplace(
        const UnicodeString * const *placeholderValues,
        int32_t placeholderValueCount,
        UnicodeString &result,
        int32_t *offsetArray,
        int32_t offsetArrayLength,
        UErrorCode &status) const {
    if (U_FAILURE(status)) {
        return result;
    }
    if (isInvalidArray(placeholderValues, placeholderValueCount)
            || isInvalidArray(offsetArray, offsetArrayLength)) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }
    if (placeholderValueCount < placeholderCount) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return result;
    }
    SimplePatternFormatterPlaceholderValues values(
            placeholderValues, placeholderCount);
    int32_t placeholderAtStart = getUniquePlaceholderAtStart();

    // If pattern starts with a unique placeholder and that placeholder
    // value is result, we may be able to optimize by just appending to result.
    if (placeholderAtStart >= 0
            && placeholderValues[placeholderAtStart] == &result) {

        // If result is the value for other placeholders, call off optimization.
        if (values.isAppendToInAnyIndexExcept(result, placeholderAtStart)) {
            values.snapshotAppendTo(result);
            result.remove();
            return formatAndAppend(
                    values,
                    result,
                    offsetArray,
                    offsetArrayLength);
        }

        // Otherwise we can optimize
        formatAndAppend(
                values,
                result,
                offsetArray,
                offsetArrayLength);
        
        // We have to make the offset for the placeholderAtStart
        // placeholder be 0. Otherwise it would be the length of the
        // previous value of result.
        if (offsetArrayLength > placeholderAtStart) {
            offsetArray[placeholderAtStart] = 0;
        }
        return result;
    }
    if (values.isAppendToInAnyIndexExcept(result, -1)) {
        values.snapshotAppendTo(result);
    }
    result.remove();
    return formatAndAppend(
            values,
            result,
            offsetArray,
            offsetArrayLength);
}