+
+ // 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& 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);
+}
+
+UnicodeString& SimplePatternFormatter::formatAndAppend(
+ const SimplePatternFormatterPlaceholderValues &values,
+ UnicodeString &appendTo,
+ int32_t *offsetArray,
+ int32_t offsetArrayLength) const {