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); }
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); }
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); }