xref: /aosp_15_r20/external/icu/libicu/cts_headers/unicode/simpleformatter.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 ******************************************************************************
5 * Copyright (C) 2014-2016, International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 ******************************************************************************
8 * simpleformatter.h
9 */
10 
11 #ifndef __SIMPLEFORMATTER_H__
12 #define __SIMPLEFORMATTER_H__
13 
14 /**
15  * \file
16  * \brief C++ API: Simple formatter, minimal subset of MessageFormat.
17  */
18 
19 #include "unicode/utypes.h"
20 
21 #if U_SHOW_CPLUSPLUS_API
22 
23 #include "unicode/unistr.h"
24 
25 U_NAMESPACE_BEGIN
26 
27 // Forward declaration:
28 namespace number::impl {
29 class SimpleModifier;
30 }
31 
32 /**
33  * Formats simple patterns like "{1} was born in {0}".
34  * Minimal subset of MessageFormat; fast, simple, minimal dependencies.
35  * Supports only numbered arguments with no type nor style parameters,
36  * and formats only string values.
37  * Quoting via ASCII apostrophe compatible with ICU MessageFormat default behavior.
38  *
39  * Factory methods set error codes for syntax errors
40  * and for too few or too many arguments/placeholders.
41  *
42  * SimpleFormatter objects are thread-safe except for assignment and applying new patterns.
43  *
44  * Example:
45  * <pre>
46  * UErrorCode errorCode = U_ZERO_ERROR;
47  * SimpleFormatter fmt("{1} '{born}' in {0}", errorCode);
48  * UnicodeString result;
49  *
50  * // Output: "paul {born} in england"
51  * fmt.format("england", "paul", result, errorCode);
52  * </pre>
53  *
54  * This class is not intended for public subclassing.
55  *
56  * @see MessageFormat
57  * @see UMessagePatternApostropheMode
58  * @stable ICU 57
59  */
60 class U_COMMON_API SimpleFormatter final : public UMemory {
61 public:
62     /**
63      * Default constructor.
64      * @stable ICU 57
65      */
SimpleFormatter()66     SimpleFormatter() : compiledPattern((char16_t)0) {}
67 
68     /**
69      * Constructs a formatter from the pattern string.
70      *
71      * @param pattern The pattern string.
72      * @param errorCode ICU error code in/out parameter.
73      *                  Must fulfill U_SUCCESS before the function call.
74      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
75      * @stable ICU 57
76      */
SimpleFormatter(const UnicodeString & pattern,UErrorCode & errorCode)77     SimpleFormatter(const UnicodeString& pattern, UErrorCode &errorCode) {
78         applyPattern(pattern, errorCode);
79     }
80 
81     /**
82      * Constructs a formatter from the pattern string.
83      * The number of arguments checked against the given limits is the
84      * highest argument number plus one, not the number of occurrences of arguments.
85      *
86      * @param pattern The pattern string.
87      * @param min The pattern must have at least this many arguments.
88      * @param max The pattern must have at most this many arguments.
89      * @param errorCode ICU error code in/out parameter.
90      *                  Must fulfill U_SUCCESS before the function call.
91      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
92      *                  too few or too many arguments.
93      * @stable ICU 57
94      */
SimpleFormatter(const UnicodeString & pattern,int32_t min,int32_t max,UErrorCode & errorCode)95     SimpleFormatter(const UnicodeString& pattern, int32_t min, int32_t max,
96                     UErrorCode &errorCode) {
97         applyPatternMinMaxArguments(pattern, min, max, errorCode);
98     }
99 
100     /**
101      * Copy constructor.
102      * @stable ICU 57
103      */
SimpleFormatter(const SimpleFormatter & other)104     SimpleFormatter(const SimpleFormatter& other)
105             : compiledPattern(other.compiledPattern) {}
106 
107     /**
108      * Assignment operator.
109      * @stable ICU 57
110      */
111     SimpleFormatter &operator=(const SimpleFormatter& other);
112 
113     /**
114      * Destructor.
115      * @stable ICU 57
116      */
117     ~SimpleFormatter();
118 
119     /**
120      * Changes this object according to the new pattern.
121      *
122      * @param pattern The pattern string.
123      * @param errorCode ICU error code in/out parameter.
124      *                  Must fulfill U_SUCCESS before the function call.
125      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax.
126      * @return true if U_SUCCESS(errorCode).
127      * @stable ICU 57
128      */
applyPattern(const UnicodeString & pattern,UErrorCode & errorCode)129     UBool applyPattern(const UnicodeString &pattern, UErrorCode &errorCode) {
130         return applyPatternMinMaxArguments(pattern, 0, INT32_MAX, errorCode);
131     }
132 
133     /**
134      * Changes this object according to the new pattern.
135      * The number of arguments checked against the given limits is the
136      * highest argument number plus one, not the number of occurrences of arguments.
137      *
138      * @param pattern The pattern string.
139      * @param min The pattern must have at least this many arguments.
140      * @param max The pattern must have at most this many arguments.
141      * @param errorCode ICU error code in/out parameter.
142      *                  Must fulfill U_SUCCESS before the function call.
143      *                  Set to U_ILLEGAL_ARGUMENT_ERROR for bad argument syntax and
144      *                  too few or too many arguments.
145      * @return true if U_SUCCESS(errorCode).
146      * @stable ICU 57
147      */
148     UBool applyPatternMinMaxArguments(const UnicodeString &pattern,
149                                       int32_t min, int32_t max, UErrorCode &errorCode);
150 
151     /**
152      * @return The max argument number + 1.
153      * @stable ICU 57
154      */
getArgumentLimit()155     int32_t getArgumentLimit() const {
156         return getArgumentLimit(compiledPattern.getBuffer(), compiledPattern.length());
157     }
158 
159     /**
160      * Formats the given value, appending to the appendTo builder.
161      * The argument value must not be the same object as appendTo.
162      * getArgumentLimit() must be at most 1.
163      *
164      * @param value0 Value for argument {0}.
165      * @param appendTo Gets the formatted pattern and value appended.
166      * @param errorCode ICU error code in/out parameter.
167      *                  Must fulfill U_SUCCESS before the function call.
168      * @return appendTo
169      * @stable ICU 57
170      */
171     UnicodeString &format(
172             const UnicodeString &value0,
173             UnicodeString &appendTo, UErrorCode &errorCode) const;
174 
175     /**
176      * Formats the given values, appending to the appendTo builder.
177      * An argument value must not be the same object as appendTo.
178      * getArgumentLimit() must be at most 2.
179      *
180      * @param value0 Value for argument {0}.
181      * @param value1 Value for argument {1}.
182      * @param appendTo Gets the formatted pattern and values appended.
183      * @param errorCode ICU error code in/out parameter.
184      *                  Must fulfill U_SUCCESS before the function call.
185      * @return appendTo
186      * @stable ICU 57
187      */
188     UnicodeString &format(
189             const UnicodeString &value0,
190             const UnicodeString &value1,
191             UnicodeString &appendTo, UErrorCode &errorCode) const;
192 
193     /**
194      * Formats the given values, appending to the appendTo builder.
195      * An argument value must not be the same object as appendTo.
196      * getArgumentLimit() must be at most 3.
197      *
198      * @param value0 Value for argument {0}.
199      * @param value1 Value for argument {1}.
200      * @param value2 Value for argument {2}.
201      * @param appendTo Gets the formatted pattern and values appended.
202      * @param errorCode ICU error code in/out parameter.
203      *                  Must fulfill U_SUCCESS before the function call.
204      * @return appendTo
205      * @stable ICU 57
206      */
207     UnicodeString &format(
208             const UnicodeString &value0,
209             const UnicodeString &value1,
210             const UnicodeString &value2,
211             UnicodeString &appendTo, UErrorCode &errorCode) const;
212 
213     /**
214      * Formats the given values, appending to the appendTo string.
215      *
216      * @param values The argument values.
217      *               An argument value must not be the same object as appendTo.
218      *               Can be nullptr if valuesLength==getArgumentLimit()==0.
219      * @param valuesLength The length of the values array.
220      *                     Must be at least getArgumentLimit().
221      * @param appendTo Gets the formatted pattern and values appended.
222      * @param offsets offsets[i] receives the offset of where
223      *                values[i] replaced pattern argument {i}.
224      *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
225      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
226      * @param offsetsLength The length of the offsets array.
227      * @param errorCode ICU error code in/out parameter.
228      *                  Must fulfill U_SUCCESS before the function call.
229      * @return appendTo
230      * @stable ICU 57
231      */
232     UnicodeString &formatAndAppend(
233             const UnicodeString *const *values, int32_t valuesLength,
234             UnicodeString &appendTo,
235             int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
236 
237     /**
238      * Formats the given values, replacing the contents of the result string.
239      * May optimize by actually appending to the result if it is the same object
240      * as the value corresponding to the initial argument in the pattern.
241      *
242      * @param values The argument values.
243      *               An argument value may be the same object as result.
244      *               Can be nullptr if valuesLength==getArgumentLimit()==0.
245      * @param valuesLength The length of the values array.
246      *                     Must be at least getArgumentLimit().
247      * @param result Gets its contents replaced by the formatted pattern and values.
248      * @param offsets offsets[i] receives the offset of where
249      *                values[i] replaced pattern argument {i}.
250      *                Can be shorter or longer than values. Can be nullptr if offsetsLength==0.
251      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
252      * @param offsetsLength The length of the offsets array.
253      * @param errorCode ICU error code in/out parameter.
254      *                  Must fulfill U_SUCCESS before the function call.
255      * @return result
256      * @stable ICU 57
257      */
258     UnicodeString &formatAndReplace(
259             const UnicodeString *const *values, int32_t valuesLength,
260             UnicodeString &result,
261             int32_t *offsets, int32_t offsetsLength, UErrorCode &errorCode) const;
262 
263     /**
264      * Returns the pattern text with none of the arguments.
265      * Like formatting with all-empty string values.
266      * @stable ICU 57
267      */
getTextWithNoArguments()268     UnicodeString getTextWithNoArguments() const {
269         return getTextWithNoArguments(
270             compiledPattern.getBuffer(),
271             compiledPattern.length(),
272             nullptr,
273             0);
274     }
275 
276 #ifndef U_HIDE_INTERNAL_API
277     /**
278      * Returns the pattern text with none of the arguments.
279      * Like formatting with all-empty string values.
280      *
281      * TODO(ICU-20406): Replace this with an Iterator interface.
282      *
283      * @param offsets offsets[i] receives the offset of where {i} was located
284      *                before it was replaced by an empty string.
285      *                For example, "a{0}b{1}" produces offset 1 for i=0 and 2 for i=1.
286      *                Can be nullptr if offsetsLength==0.
287      *                If there is no {i} in the pattern, then offsets[i] is set to -1.
288      * @param offsetsLength The length of the offsets array.
289      *
290      * @internal
291      */
getTextWithNoArguments(int32_t * offsets,int32_t offsetsLength)292     UnicodeString getTextWithNoArguments(int32_t *offsets, int32_t offsetsLength) const {
293         return getTextWithNoArguments(
294             compiledPattern.getBuffer(),
295             compiledPattern.length(),
296             offsets,
297             offsetsLength);
298     }
299 #endif // U_HIDE_INTERNAL_API
300 
301 private:
302     /**
303      * Binary representation of the compiled pattern.
304      * Index 0: One more than the highest argument number.
305      * Followed by zero or more arguments or literal-text segments.
306      *
307      * An argument is stored as its number, less than ARG_NUM_LIMIT.
308      * A literal-text segment is stored as its length (at least 1) offset by ARG_NUM_LIMIT,
309      * followed by that many chars.
310      */
311     UnicodeString compiledPattern;
312 
getArgumentLimit(const char16_t * compiledPattern,int32_t compiledPatternLength)313     static inline int32_t getArgumentLimit(const char16_t *compiledPattern,
314                                               int32_t compiledPatternLength) {
315         return compiledPatternLength == 0 ? 0 : compiledPattern[0];
316     }
317 
318     static UnicodeString getTextWithNoArguments(
319         const char16_t *compiledPattern,
320         int32_t compiledPatternLength,
321         int32_t *offsets,
322         int32_t offsetsLength);
323 
324     static UnicodeString &format(
325             const char16_t *compiledPattern, int32_t compiledPatternLength,
326             const UnicodeString *const *values,
327             UnicodeString &result, const UnicodeString *resultCopy, UBool forbidResultAsValue,
328             int32_t *offsets, int32_t offsetsLength,
329             UErrorCode &errorCode);
330 
331     // Give access to internals to SimpleModifier for number formatting
332     friend class number::impl::SimpleModifier;
333 };
334 
335 U_NAMESPACE_END
336 
337 #endif /* U_SHOW_CPLUSPLUS_API */
338 
339 #endif  // __SIMPLEFORMATTER_H__
340