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