]>
Commit | Line | Data |
---|---|---|
57a6839d A |
1 | /* |
2 | ****************************************************************************** | |
3 | * Copyright (C) 2014, International Business Machines | |
4 | * Corporation and others. All Rights Reserved. | |
5 | ****************************************************************************** | |
6 | * simplepatternformatter.h | |
7 | */ | |
8 | ||
9 | #ifndef __SIMPLEPATTERNFORMATTER_H__ | |
10 | #define __SIMPLEPATTERNFORMATTER_H__ | |
11 | ||
12 | #define EXPECTED_PLACEHOLDER_COUNT 3 | |
13 | ||
b331163b | 14 | #include "cmemory.h" |
57a6839d A |
15 | #include "unicode/utypes.h" |
16 | #include "unicode/unistr.h" | |
17 | ||
18 | U_NAMESPACE_BEGIN | |
19 | ||
b331163b A |
20 | class SimplePatternFormatterPlaceholderValues; |
21 | ||
22 | struct PlaceholderInfo { | |
23 | int32_t id; | |
24 | int32_t offset; | |
25 | }; | |
26 | ||
57a6839d A |
27 | /** |
28 | * Compiled version of a pattern string such as "{1} was born in {0}". | |
29 | * <p> | |
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 ('). | |
33 | * | |
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. | |
37 | * <p> | |
38 | * Example: | |
39 | * <pre> | |
40 | * SimplePatternFormatter fmt("{1} '{born} in {0}"); | |
41 | * UnicodeString result; | |
42 | * UErrorCode status = U_ZERO_ERROR; | |
43 | * // Evaluates to: "paul {born} in england" | |
b331163b | 44 | * fmt.format("england", "paul", result, status); |
57a6839d A |
45 | * </pre> |
46 | */ | |
47 | class U_COMMON_API SimplePatternFormatter : public UMemory { | |
48 | public: | |
49 | /** | |
50 | * Default constructor | |
51 | */ | |
52 | SimplePatternFormatter(); | |
53 | ||
54 | /** | |
55 | * Construct from a pattern. Will never fail if pattern has three or | |
56 | * fewer placeholders in it. | |
57 | */ | |
58 | explicit SimplePatternFormatter(const UnicodeString& pattern); | |
59 | ||
60 | /** | |
61 | * Copy constructor. | |
62 | */ | |
63 | SimplePatternFormatter(const SimplePatternFormatter& other); | |
64 | ||
65 | /** | |
66 | * Assignment operator | |
67 | */ | |
68 | SimplePatternFormatter &operator=(const SimplePatternFormatter& other); | |
69 | ||
70 | /** | |
71 | * Destructor. | |
72 | */ | |
73 | ~SimplePatternFormatter(); | |
74 | ||
75 | /** | |
76 | * Compiles pattern and makes this object represent pattern. | |
77 | * | |
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. | |
81 | */ | |
82 | UBool compile(const UnicodeString &pattern, UErrorCode &status); | |
83 | ||
84 | /** | |
85 | * Returns (maxPlaceholderId + 1). For example | |
86 | * <code>SimplePatternFormatter("{0} {2}").getPlaceholderCount() | |
87 | * evaluates to 3. | |
88 | * Callers use this function to find out how many values this object | |
89 | * expects when formatting. | |
90 | */ | |
91 | int32_t getPlaceholderCount() const { | |
92 | return placeholderCount; | |
93 | } | |
94 | ||
95 | /** | |
b331163b A |
96 | * Returns this pattern with none of the placeholders. |
97 | */ | |
98 | const UnicodeString &getPatternWithNoPlaceholders() const { | |
99 | return noPlaceholders; | |
100 | } | |
101 | ||
102 | /** | |
103 | * Formats given value. arg0 cannot be appendTo. | |
57a6839d A |
104 | */ |
105 | UnicodeString &format( | |
106 | const UnicodeString &args0, | |
107 | UnicodeString &appendTo, | |
108 | UErrorCode &status) const; | |
109 | ||
110 | /** | |
b331163b | 111 | * Formats given values. Neither arg0 nor arg1 can be appendTo. |
57a6839d A |
112 | */ |
113 | UnicodeString &format( | |
114 | const UnicodeString &args0, | |
115 | const UnicodeString &args1, | |
116 | UnicodeString &appendTo, | |
117 | UErrorCode &status) const; | |
118 | ||
119 | /** | |
b331163b | 120 | * Formats given values. Neither arg0, arg1, nor arg2 can be appendTo. |
57a6839d A |
121 | */ |
122 | UnicodeString &format( | |
123 | const UnicodeString &args0, | |
124 | const UnicodeString &args1, | |
125 | const UnicodeString &args2, | |
126 | UnicodeString &appendTo, | |
127 | UErrorCode &status) const; | |
128 | ||
129 | /** | |
130 | * Formats given values. | |
131 | * | |
132 | * The caller retains ownership of all pointers. | |
133 | * @param placeholderValues 1st one corresponds to {0}; 2nd to {1}; | |
b331163b A |
134 | * 3rd to {2} etc. If any of these point to appendTo, this method |
135 | * sets status to U_ILLEGAL_ARGUMENT_ERROR. | |
57a6839d A |
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. | |
b331163b A |
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. | |
57a6839d A |
149 | * @param status any error stored here. |
150 | */ | |
b331163b | 151 | UnicodeString &formatAndAppend( |
57a6839d A |
152 | const UnicodeString * const *placeholderValues, |
153 | int32_t placeholderValueCount, | |
154 | UnicodeString &appendTo, | |
155 | int32_t *offsetArray, | |
156 | int32_t offsetArrayLength, | |
157 | UErrorCode &status) const; | |
b331163b A |
158 | |
159 | /** | |
160 | * Formats given values. | |
161 | * | |
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 | |
166 | * placeholder. | |
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 | |
171 | * value. | |
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. | |
182 | */ | |
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; | |
57a6839d A |
190 | private: |
191 | UnicodeString noPlaceholders; | |
b331163b | 192 | MaybeStackArray<PlaceholderInfo, 3> placeholders; |
57a6839d | 193 | int32_t placeholderSize; |
57a6839d | 194 | int32_t placeholderCount; |
b331163b A |
195 | UBool firstPlaceholderReused; |
196 | ||
197 | // A Placeholder value that is the same as appendTo is treated as the | |
198 | // empty string. | |
199 | UnicodeString &formatAndAppend( | |
200 | const SimplePatternFormatterPlaceholderValues &placeholderValues, | |
201 | UnicodeString &appendTo, | |
202 | int32_t *offsetArray, | |
203 | int32_t offsetArrayLength) const; | |
204 | ||
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; | |
210 | ||
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); | |
230 | ||
231 | // Records the offset of an individual placeholder in the noPlaceholders | |
232 | // string. | |
57a6839d A |
233 | UBool addPlaceholder(int32_t id, int32_t offset); |
234 | }; | |
235 | ||
236 | U_NAMESPACE_END | |
237 | ||
238 | #endif |