2 ******************************************************************************
3 * Copyright (C) 2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 ******************************************************************************
6 * simplepatternformatter.h
9 #ifndef __SIMPLEPATTERNFORMATTER_H__
10 #define __SIMPLEPATTERNFORMATTER_H__
12 #define EXPECTED_PLACEHOLDER_COUNT 3
15 #include "unicode/utypes.h"
16 #include "unicode/unistr.h"
20 class SimplePatternFormatterPlaceholderValues
;
22 struct PlaceholderInfo
{
28 * Compiled version of a pattern string such as "{1} was born in {0}".
30 * Using SimplePatternFormatter is both faster and safer than adhoc replacement.
31 * They are faster because they are precompiled; they are safer because they
32 * account for curly braces escaped by apostrophe (').
34 * Placeholders are of the form \{[0-9]+\}. If a curly brace is preceded
35 * by a single quote, it becomes a curly brace instead of the start of a
36 * placeholder. Two single quotes resolve to one single quote.
40 * SimplePatternFormatter fmt("{1} '{born} in {0}");
41 * UnicodeString result;
42 * UErrorCode status = U_ZERO_ERROR;
43 * // Evaluates to: "paul {born} in england"
44 * fmt.format("england", "paul", result, status);
47 class U_COMMON_API SimplePatternFormatter
: public UMemory
{
52 SimplePatternFormatter();
55 * Construct from a pattern. Will never fail if pattern has three or
56 * fewer placeholders in it.
58 explicit SimplePatternFormatter(const UnicodeString
& pattern
);
63 SimplePatternFormatter(const SimplePatternFormatter
& other
);
68 SimplePatternFormatter
&operator=(const SimplePatternFormatter
& other
);
73 ~SimplePatternFormatter();
76 * Compiles pattern and makes this object represent pattern.
78 * Returns TRUE on success; FALSE on failure. Will not fail if
79 * there are three or fewer placeholders in pattern. May fail with
80 * U_MEMORY_ALLOCATION_ERROR if there are more than three placeholders.
82 UBool
compile(const UnicodeString
&pattern
, UErrorCode
&status
);
85 * Returns (maxPlaceholderId + 1). For example
86 * <code>SimplePatternFormatter("{0} {2}").getPlaceholderCount()
88 * Callers use this function to find out how many values this object
89 * expects when formatting.
91 int32_t getPlaceholderCount() const {
92 return placeholderCount
;
96 * Returns this pattern with none of the placeholders.
98 const UnicodeString
&getPatternWithNoPlaceholders() const {
99 return noPlaceholders
;
103 * Formats given value. arg0 cannot be appendTo.
105 UnicodeString
&format(
106 const UnicodeString
&args0
,
107 UnicodeString
&appendTo
,
108 UErrorCode
&status
) const;
111 * Formats given values. Neither arg0 nor arg1 can be appendTo.
113 UnicodeString
&format(
114 const UnicodeString
&args0
,
115 const UnicodeString
&args1
,
116 UnicodeString
&appendTo
,
117 UErrorCode
&status
) const;
120 * Formats given values. Neither arg0, arg1, nor arg2 can be appendTo.
122 UnicodeString
&format(
123 const UnicodeString
&args0
,
124 const UnicodeString
&args1
,
125 const UnicodeString
&args2
,
126 UnicodeString
&appendTo
,
127 UErrorCode
&status
) const;
130 * Formats given values.
132 * The caller retains ownership of all pointers.
133 * @param placeholderValues 1st one corresponds to {0}; 2nd to {1};
134 * 3rd to {2} etc. If any of these point to appendTo, this method
135 * sets status to U_ILLEGAL_ARGUMENT_ERROR.
136 * @param placeholderValueCount the number of placeholder values
137 * must be at least large enough to provide values for all placeholders
138 * in this object. Otherwise status set to U_ILLEGAL_ARGUMENT_ERROR.
139 * @param appendTo resulting string appended here.
140 * @param offsetArray The offset of each placeholder value in appendTo
141 * stored here. The first value gets the offset of the value for {0};
142 * the 2nd for {1}; the 3rd for {2} etc. -1 means that the corresponding
143 * placeholder does not exist in this object. If caller is not
144 * interested in offsets, it may pass NULL and 0 for the length.
145 * @param offsetArrayLength the size of offsetArray. If less than
146 * placeholderValueCount only the first offsets get recorded. If
147 * greater than placeholderValueCount, then extra values in offset
148 * array are set to -1.
149 * @param status any error stored here.
151 UnicodeString
&formatAndAppend(
152 const UnicodeString
* const *placeholderValues
,
153 int32_t placeholderValueCount
,
154 UnicodeString
&appendTo
,
155 int32_t *offsetArray
,
156 int32_t offsetArrayLength
,
157 UErrorCode
&status
) const;
160 * Formats given values.
162 * The caller retains ownership of all pointers.
163 * @param placeholderValues 1st one corresponds to {0}; 2nd to {1};
164 * 3rd to {2} etc. May include pointer to result in which case
165 * the previous value of result is used for the corresponding
167 * @param placeholderValueCount the number of placeholder values
168 * must be at least large enough to provide values for all placeholders
169 * in this object. Otherwise status set to U_ILLEGAL_ARGUMENT_ERROR.
170 * @param result resulting string stored here overwriting any previous
172 * @param offsetArray The offset of each placeholder value in result
173 * stored here. The first value gets the offset of the value for {0};
174 * the 2nd for {1}; the 3rd for {2} etc. -1 means that the corresponding
175 * placeholder does not exist in this object. If caller is not
176 * interested in offsets, it may pass NULL and 0 for the length.
177 * @param offsetArrayLength the size of offsetArray. If less than
178 * placeholderValueCount only the first offsets get recorded. If
179 * greater than placeholderValueCount, then extra values in offset
180 * array are set to -1.
181 * @param status any error stored here.
183 UnicodeString
&formatAndReplace(
184 const UnicodeString
* const *placeholderValues
,
185 int32_t placeholderValueCount
,
186 UnicodeString
&result
,
187 int32_t *offsetArray
,
188 int32_t offsetArrayLength
,
189 UErrorCode
&status
) const;
191 UnicodeString noPlaceholders
;
192 MaybeStackArray
<PlaceholderInfo
, 3> placeholders
;
193 int32_t placeholderSize
;
194 int32_t placeholderCount
;
195 UBool firstPlaceholderReused
;
197 // A Placeholder value that is the same as appendTo is treated as the
199 UnicodeString
&formatAndAppend(
200 const SimplePatternFormatterPlaceholderValues
&placeholderValues
,
201 UnicodeString
&appendTo
,
202 int32_t *offsetArray
,
203 int32_t offsetArrayLength
) const;
205 // Returns the placeholder at the beginning of this pattern
206 // (e.g 3 for placeholder {3}). Returns -1 if the beginning of pattern
207 // is text or if the placeholder at the beginning of this pattern
208 // is used again in the middle of the pattern.
209 int32_t getUniquePlaceholderAtStart() const;
211 // ensureCapacity ensures that the capacity of the placeholders array
212 // is desiredCapacity. If ensureCapacity must resize the placeholders
213 // array, the first placeholderSize elements stay in the array. Note
214 // that ensureCapcity NEVER changes the value of placeholderSize only
215 // the capacity of the placeholders array.
216 // If there is no memory allocation error when resizing, this
217 // function returns desiredCapacity. If there is a memory allocation
218 // error, this function leaves the placeholders array unchanged and
219 // returns the smaller, old capacity. ensureCapacity resizes only if
220 // the current capacity of placeholders array is less than desiredCapacity.
221 // Otherwise, it leaves the placeholders array unchanged. If caller
222 // specifies an allocation size, then it must be at least as large as
223 // desiredCapacity. In that case, if ensureCapacity resizes, it will
224 // allocate allocationSize spots instead of desiredCapacity spots in
225 // the array. If caller is calling ensureCapacity in a loop while adding
226 // elements, it is recommended that it use an allocationSize of
227 // approximately twice desiredCapacity to avoid memory allocation with
228 // every call to ensureCapacity.
229 int32_t ensureCapacity(int32_t desiredCapacity
, int32_t allocationSize
=0);
231 // Records the offset of an individual placeholder in the noPlaceholders
233 UBool
addPlaceholder(int32_t id
, int32_t offset
);