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