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