Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-14 09:25:40

0001 // © 2016 and later: Unicode, Inc. and others.
0002 // License & terms of use: http://www.unicode.org/copyright.html
0003 /*
0004 ******************************************************************************
0005 * Copyright (C) 2014-2016, International Business Machines
0006 * Corporation and others.  All Rights Reserved.
0007 ******************************************************************************
0008 * simpleformatter.h
0009 */
0010 
0011 #ifndef __SIMPLEFORMATTER_H__
0012 #define __SIMPLEFORMATTER_H__
0013 
0014 /**
0015  * \file
0016  * \brief C++ API: Simple formatter, minimal subset of MessageFormat.
0017  */
0018 
0019 #include "unicode/utypes.h"
0020 
0021 #if U_SHOW_CPLUSPLUS_API
0022 
0023 #include "unicode/unistr.h"
0024 
0025 U_NAMESPACE_BEGIN
0026 
0027 // Forward declaration:
0028 namespace number::impl {
0029 class SimpleModifier;
0030 }
0031 
0032 /**
0033  * Formats simple patterns like "{1} was born in {0}".
0034  * Minimal subset of MessageFormat; fast, simple, minimal dependencies.
0035  * Supports only numbered arguments with no type nor style parameters,
0036  * and formats only string values.
0037  * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
0038  *
0039  * Factory methods set error codes for syntax errors
0040  * and for too few or too many arguments/placeholders.
0041  *
0042  * SimpleFormatter objects are thread-safe except for assignment and applying new patterns.
0043  *
0044  * Example:
0045  * <pre>
0046  * UErrorCode errorCode = U_ZERO_ERROR;
0047  * SimpleFormatter fmt("{1} '{born}' in {0}", errorCode);
0048  * UnicodeString result;
0049  *
0050  * // Output: "paul {born} in england"
0051  * fmt.format("england", "paul", result, errorCode);
0052  * </pre>
0053  *
0054  * This class is not intended for public subclassing.
0055  *
0056  * @see MessageFormat
0057  * @see UMessagePatternApostropheMode
0058  * @stable ICU 57
0059  */
0060 class U_COMMON_API SimpleFormatter final : public UMemory {
0061 public:
0062     /**
0063      * Default constructor.
0064      * @stable ICU 57
0065      */
0066     SimpleFormatter() : compiledPattern(static_cast<char16_t>(0)) {}
0067 
0068     /**
0069      * Constructs a formatter from the pattern string.
0070      *
0071      * @param pattern The pattern string.
0072      * @param errorCode ICU error code in/out parameter.
0073      *                  Must fulfill U_SUCCESS before the function call.
0074      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
0075      * @stable ICU 57
0076      */
0077     SimpleFormatter(const UnicodeString& pattern, UErrorCode &errorCode) {
0078         applyPattern(pattern, errorCode);
0079     }
0080 
0081     /**
0082      * Constructs a formatter from the pattern string.
0083      * The number of arguments checked against the given limits is the
0084      * highest argument number plus one, not the number of occurrences of arguments.
0085      *
0086      * @param pattern The pattern string.
0087      * @param min The pattern must have at least this many arguments.
0088      * @param max The pattern must have at most this many arguments.
0089      * @param errorCode ICU error code in/out parameter.
0090      *                  Must fulfill U_SUCCESS before the function call.
0091      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
0092      *                  too few or too many arguments.
0093      * @stable ICU 57
0094      */
0095     SimpleFormatter(const UnicodeString& pattern, int32_t min, int32_t max,
0096                     UErrorCode &errorCode) {
0097         applyPatternMinMaxArguments(pattern, min, max, errorCode);
0098     }
0099 
0100     /**
0101      * Copy constructor.
0102      * @stable ICU 57
0103      */
0104     SimpleFormatter(const SimpleFormatter& other)
0105             : compiledPattern(other.compiledPattern) {}
0106 
0107     /**
0108      * Assignment operator.
0109      * @stable ICU 57
0110      */
0111     SimpleFormatter &operator=(const SimpleFormatter& other);
0112 
0113     /**
0114      * Destructor.
0115      * @stable ICU 57
0116      */
0117     ~SimpleFormatter();
0118 
0119     /**
0120      * Changes this object according to the new pattern.
0121      *
0122      * @param pattern The pattern string.
0123      * @param errorCode ICU error code in/out parameter.
0124      *                  Must fulfill U_SUCCESS before the function call.
0125      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
0126      * @return true if U_SUCCESS(errorCode).
0127      * @stable ICU 57
0128      */
0129     UBool applyPattern(const UnicodeString &pattern, UErrorCode &errorCode) {
0130         return applyPatternMinMaxArguments(pattern, 0, INT32_MAX, errorCode);
0131     }
0132 
0133     /**
0134      * Changes this object according to the new pattern.
0135      * The number of arguments checked against the given limits is the
0136      * highest argument number plus one, not the number of occurrences of arguments.
0137      *
0138      * @param pattern The pattern string.
0139      * @param min The pattern must have at least this many arguments.
0140      * @param max The pattern must have at most this many arguments.
0141      * @param errorCode ICU error code in/out parameter.
0142      *                  Must fulfill U_SUCCESS before the function call.
0143      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
0144      *                  too few or too many arguments.
0145      * @return true if U_SUCCESS(errorCode).
0146      * @stable ICU 57
0147      */
0148     UBool applyPatternMinMaxArguments(const UnicodeString &pattern,
0149                                       int32_t min, int32_t max, UErrorCode &errorCode);
0150 
0151     /**
0152      * @return The max argument number + 1.
0153      * @stable ICU 57
0154      */
0155     int32_t getArgumentLimit() const {
0156         return getArgumentLimit(compiledPattern.getBuffer(), compiledPattern.length());
0157     }
0158 
0159     /**
0160      * Formats the given value, appending to the appendTo builder.
0161      * The argument value must not be the same object as appendTo.
0162      * getArgumentLimit() must be at most 1.
0163      *
0164      * @param value0 Value for argument {0}.
0165      * @param appendTo Gets the formatted pattern and value appended.
0166      * @param errorCode ICU error code in/out parameter.
0167      *                  Must fulfill U_SUCCESS before the function call.
0168      * @return appendTo
0169      * @stable ICU 57
0170      */
0171     UnicodeString &format(
0172             const UnicodeString &value0,
0173             UnicodeString &appendTo, UErrorCode &errorCode) const;
0174 
0175     /**
0176      * Formats the given values, appending to the appendTo builder.
0177      * An argument value must not be the same object as appendTo.
0178      * getArgumentLimit() must be at most 2.
0179      *
0180      * @param value0 Value for argument {0}.
0181      * @param value1 Value for argument {1}.
0182      * @param appendTo Gets the formatted pattern and values appended.
0183      * @param errorCode ICU error code in/out parameter.
0184      *                  Must fulfill U_SUCCESS before the function call.
0185      * @return appendTo
0186      * @stable ICU 57
0187      */
0188     UnicodeString &format(
0189             const UnicodeString &value0,
0190             const UnicodeString &value1,
0191             UnicodeString &appendTo, UErrorCode &errorCode) const;
0192 
0193     /**
0194      * Formats the given values, appending to the appendTo builder.
0195      * An argument value must not be the same object as appendTo.
0196      * getArgumentLimit() must be at most 3.
0197      *
0198      * @param value0 Value for argument {0}.
0199      * @param value1 Value for argument {1}.
0200      * @param value2 Value for argument {2}.
0201      * @param appendTo Gets the formatted pattern and values appended.
0202      * @param errorCode ICU error code in/out parameter.
0203      *                  Must fulfill U_SUCCESS before the function call.
0204      * @return appendTo
0205      * @stable ICU 57
0206      */
0207     UnicodeString &format(
0208             const UnicodeString &value0,
0209             const UnicodeString &value1,
0210             const UnicodeString &value2,
0211             UnicodeString &appendTo, UErrorCode &errorCode) const;
0212 
0213     /**
0214      * Formats the given values, appending to the appendTo string.
0215      *
0216      * @param values The argument values.
0217      *               An argument value must not be the same object as appendTo.
0218      *               Can be nullptr if valuesLength==getArgumentLimit()==0.
0219      * @param valuesLength The length of the values array.
0220      *                     Must be at least getArgumentLimit().
0221      * @param appendTo Gets the formatted pattern and values appended.
0222      * @param offsets offsets[i] receives the offset of where
0223      *                values[i] replaced pattern argument {i}.
0224      *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
0225      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
0226      * @param offsetsLength The length of the offsets array.
0227      * @param errorCode ICU error code in/out parameter.
0228      *                  Must fulfill U_SUCCESS before the function call.
0229      * @return appendTo
0230      * @stable ICU 57
0231      */
0232     UnicodeString &formatAndAppend(
0233             const UnicodeString *const *values, int32_t valuesLength,
0234             UnicodeString &appendTo,
0235             int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
0236 
0237     /**
0238      * Formats the given values, replacing the contents of the result string.
0239      * May optimize by actually appending to the result if it is the same object
0240      * as the value corresponding to the initial argument in the pattern.
0241      *
0242      * @param values The argument values.
0243      *               An argument value may be the same object as result.
0244      *               Can be nullptr if valuesLength==getArgumentLimit()==0.
0245      * @param valuesLength The length of the values array.
0246      *                     Must be at least getArgumentLimit().
0247      * @param result Gets its contents replaced by the formatted pattern and values.
0248      * @param offsets offsets[i] receives the offset of where
0249      *                values[i] replaced pattern argument {i}.
0250      *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
0251      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
0252      * @param offsetsLength The length of the offsets array.
0253      * @param errorCode ICU error code in/out parameter.
0254      *                  Must fulfill U_SUCCESS before the function call.
0255      * @return result
0256      * @stable ICU 57
0257      */
0258     UnicodeString &formatAndReplace(
0259             const UnicodeString *const *values, int32_t valuesLength,
0260             UnicodeString &result,
0261             int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
0262 
0263     /**
0264      * Returns the pattern text with none of the arguments.
0265      * Like formatting with all-empty string values.
0266      * @stable ICU 57
0267      */
0268     UnicodeString getTextWithNoArguments() const {
0269         return getTextWithNoArguments(
0270             compiledPattern.getBuffer(),
0271             compiledPattern.length(),
0272             nullptr,
0273             0);
0274     }
0275 
0276 #ifndef U_HIDE_INTERNAL_API
0277     /**
0278      * Returns the pattern text with none of the arguments.
0279      * Like formatting with all-empty string values.
0280      *
0281      * TODO(ICU-20406): Replace this with an Iterator interface.
0282      *
0283      * @param offsets offsets[i] receives the offset of where {i} was located
0284      *                before it was replaced by an empty string.
0285      *                For example, "a{0}b{1}" produces offset 1 for i=0 and 2 for i=1.
0286      *                Can be nullptr if offsetsLength==0.
0287      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
0288      * @param offsetsLength The length of the offsets array.
0289      *
0290      * @internal
0291      */
0292     UnicodeString getTextWithNoArguments(int32_t *offsets, int32_t offsetsLength) const {
0293         return getTextWithNoArguments(
0294             compiledPattern.getBuffer(),
0295             compiledPattern.length(),
0296             offsets,
0297             offsetsLength);
0298     }
0299 #endif // U_HIDE_INTERNAL_API
0300 
0301 private:
0302     /**
0303      * Binary representation of the compiled pattern.
0304      * Index 0: One more than the highest argument number.
0305      * Followed by zero or more arguments or literal-text segments.
0306      *
0307      * An argument is stored as its number, less than ARG_NUM_LIMIT.
0308      * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
0309      * followed by that many chars.
0310      */
0311     UnicodeString compiledPattern;
0312 
0313     static inline int32_t getArgumentLimit(const char16_t *compiledPattern,
0314                                               int32_t compiledPatternLength) {
0315         return compiledPatternLength == 0 ? 0 : compiledPattern[0];
0316     }
0317 
0318     static UnicodeString getTextWithNoArguments(
0319         const char16_t *compiledPattern,
0320         int32_t compiledPatternLength,
0321         int32_t *offsets,
0322         int32_t offsetsLength);
0323 
0324     static UnicodeString &format(
0325             const char16_t *compiledPattern, int32_t compiledPatternLength,
0326             const UnicodeString *const *values,
0327             UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
0328             int32_t *offsets, int32_t offsetsLength,
0329             UErrorCode &errorCode);
0330 
0331     // Give access to internals to SimpleModifier for number formatting
0332     friend class number::impl::SimpleModifier;
0333 };
0334 
0335 U_NAMESPACE_END
0336 
0337 #endif /* U_SHOW_CPLUSPLUS_API */
0338 
0339 #endif  // __SIMPLEFORMATTER_H__