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