| OLD | NEW |
| 1 /* | 1 /* |
| 2 ****************************************************************************** | 2 ****************************************************************************** |
| 3 * Copyright (C) 2014, International Business Machines | 3 * Copyright (C) 2014, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
| 5 ****************************************************************************** | 5 ****************************************************************************** |
| 6 * simplepatternformatter.h | 6 * simplepatternformatter.h |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #ifndef __SIMPLEPATTERNFORMATTER_H__ | 9 #ifndef __SIMPLEPATTERNFORMATTER_H__ |
| 10 #define __SIMPLEPATTERNFORMATTER_H__ | 10 #define __SIMPLEPATTERNFORMATTER_H__ |
| 11 | 11 |
| 12 #define EXPECTED_PLACEHOLDER_COUNT 3 | 12 #define EXPECTED_PLACEHOLDER_COUNT 3 |
| 13 | 13 |
| 14 #include "cmemory.h" | 14 #include "cmemory.h" |
| 15 #include "unicode/utypes.h" | 15 #include "unicode/utypes.h" |
| 16 #include "unicode/unistr.h" | 16 #include "unicode/unistr.h" |
| 17 | 17 |
| 18 U_NAMESPACE_BEGIN | 18 U_NAMESPACE_BEGIN |
| 19 | 19 |
| 20 class SimplePatternFormatterPlaceholderValues; |
| 21 |
| 20 struct PlaceholderInfo { | 22 struct PlaceholderInfo { |
| 21 int32_t id; | 23 int32_t id; |
| 22 int32_t offset; | 24 int32_t offset; |
| 23 }; | 25 }; |
| 24 | 26 |
| 25 /** | 27 /** |
| 26 * Compiled version of a pattern string such as "{1} was born in {0}". | 28 * Compiled version of a pattern string such as "{1} was born in {0}". |
| 27 * <p> | 29 * <p> |
| 28 * Using SimplePatternFormatter is both faster and safer than adhoc replacement. | 30 * Using SimplePatternFormatter is both faster and safer than adhoc replacement. |
| 29 * They are faster because they are precompiled; they are safer because they | 31 * They are faster because they are precompiled; they are safer because they |
| 30 * account for curly braces escaped by apostrophe ('). | 32 * account for curly braces escaped by apostrophe ('). |
| 31 * | 33 * |
| 32 * Placeholders are of the form \{[0-9]+\}. If a curly brace is preceded | 34 * Placeholders are of the form \{[0-9]+\}. If a curly brace is preceded |
| 33 * by a single quote, it becomes a curly brace instead of the start of a | 35 * by a single quote, it becomes a curly brace instead of the start of a |
| 34 * placeholder. Two single quotes resolve to one single quote. | 36 * placeholder. Two single quotes resolve to one single quote. |
| 35 * <p> | 37 * <p> |
| 36 * Example: | 38 * Example: |
| 37 * <pre> | 39 * <pre> |
| 38 * SimplePatternFormatter fmt("{1} '{born} in {0}"); | 40 * SimplePatternFormatter fmt("{1} '{born} in {0}"); |
| 39 * UnicodeString result; | 41 * UnicodeString result; |
| 40 * UErrorCode status = U_ZERO_ERROR; | 42 * UErrorCode status = U_ZERO_ERROR; |
| 41 * // Evaluates to: "paul {born} in england" | 43 * // Evaluates to: "paul {born} in england" |
| 42 * fmt.format("englad", "paul", result, status); | 44 * fmt.format("england", "paul", result, status); |
| 43 * </pre> | 45 * </pre> |
| 44 */ | 46 */ |
| 45 class U_COMMON_API SimplePatternFormatter : public UMemory { | 47 class U_COMMON_API SimplePatternFormatter : public UMemory { |
| 46 public: | 48 public: |
| 47 /** | 49 /** |
| 48 * Default constructor | 50 * Default constructor |
| 49 */ | 51 */ |
| 50 SimplePatternFormatter(); | 52 SimplePatternFormatter(); |
| 51 | 53 |
| 52 /** | 54 /** |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 * <code>SimplePatternFormatter("{0} {2}").getPlaceholderCount() | 86 * <code>SimplePatternFormatter("{0} {2}").getPlaceholderCount() |
| 85 * evaluates to 3. | 87 * evaluates to 3. |
| 86 * Callers use this function to find out how many values this object | 88 * Callers use this function to find out how many values this object |
| 87 * expects when formatting. | 89 * expects when formatting. |
| 88 */ | 90 */ |
| 89 int32_t getPlaceholderCount() const { | 91 int32_t getPlaceholderCount() const { |
| 90 return placeholderCount; | 92 return placeholderCount; |
| 91 } | 93 } |
| 92 | 94 |
| 93 /** | 95 /** |
| 94 * Returns true if the pattern this object represents starts with | |
| 95 * placeholder id; otherwise, returns false. | |
| 96 */ | |
| 97 UBool startsWithPlaceholder(int32_t id) const; | |
| 98 | |
| 99 /** | |
| 100 * Returns this pattern with none of the placeholders. | 96 * Returns this pattern with none of the placeholders. |
| 101 */ | 97 */ |
| 102 const UnicodeString &getPatternWithNoPlaceholders() const { | 98 const UnicodeString &getPatternWithNoPlaceholders() const { |
| 103 return noPlaceholders; | 99 return noPlaceholders; |
| 104 } | 100 } |
| 105 | 101 |
| 106 /** | 102 /** |
| 107 * Formats given value. | 103 * Formats given value. arg0 cannot be appendTo. |
| 108 */ | 104 */ |
| 109 UnicodeString &format( | 105 UnicodeString &format( |
| 110 const UnicodeString &args0, | 106 const UnicodeString &args0, |
| 111 UnicodeString &appendTo, | 107 UnicodeString &appendTo, |
| 112 UErrorCode &status) const; | 108 UErrorCode &status) const; |
| 113 | 109 |
| 114 /** | 110 /** |
| 115 * Formats given values. | 111 * Formats given values. Neither arg0 nor arg1 can be appendTo. |
| 116 */ | 112 */ |
| 117 UnicodeString &format( | 113 UnicodeString &format( |
| 118 const UnicodeString &args0, | 114 const UnicodeString &args0, |
| 119 const UnicodeString &args1, | 115 const UnicodeString &args1, |
| 120 UnicodeString &appendTo, | 116 UnicodeString &appendTo, |
| 121 UErrorCode &status) const; | 117 UErrorCode &status) const; |
| 122 | 118 |
| 123 /** | 119 /** |
| 124 * Formats given values. | 120 * Formats given values. Neither arg0, arg1, nor arg2 can be appendTo. |
| 125 */ | 121 */ |
| 126 UnicodeString &format( | 122 UnicodeString &format( |
| 127 const UnicodeString &args0, | 123 const UnicodeString &args0, |
| 128 const UnicodeString &args1, | 124 const UnicodeString &args1, |
| 129 const UnicodeString &args2, | 125 const UnicodeString &args2, |
| 130 UnicodeString &appendTo, | 126 UnicodeString &appendTo, |
| 131 UErrorCode &status) const; | 127 UErrorCode &status) const; |
| 132 | 128 |
| 133 /** | 129 /** |
| 134 * Formats given values. | 130 * Formats given values. |
| 135 * | 131 * |
| 136 * The caller retains ownership of all pointers. | 132 * The caller retains ownership of all pointers. |
| 137 * @param placeholderValues 1st one corresponds to {0}; 2nd to {1}; | 133 * @param placeholderValues 1st one corresponds to {0}; 2nd to {1}; |
| 138 * 3rd to {2} etc. | 134 * 3rd to {2} etc. If any of these point to appendTo, this method |
| 135 * sets status to U_ILLEGAL_ARGUMENT_ERROR. |
| 139 * @param placeholderValueCount the number of placeholder values | 136 * @param placeholderValueCount the number of placeholder values |
| 140 * must be at least large enough to provide values for all placeholders | 137 * must be at least large enough to provide values for all placeholders |
| 141 * in this object. Otherwise status set to U_ILLEGAL_ARGUMENT_ERROR. | 138 * in this object. Otherwise status set to U_ILLEGAL_ARGUMENT_ERROR. |
| 142 * @param appendTo resulting string appended here. Optimization: If | 139 * @param appendTo resulting string appended here. |
| 143 * the pattern this object represents starts with a placeholder AND | |
| 144 * appendTo references the value of that same placeholder, then that | |
| 145 * placeholder value is not copied to appendTo (Its already there). | |
| 146 * If the value of the starting placeholder is a very large string, | |
| 147 * this optimization can offer huge savings. | |
| 148 * @param offsetArray The offset of each placeholder value in appendTo | 140 * @param offsetArray The offset of each placeholder value in appendTo |
| 149 * stored here. The first value gets the offset of the value for {0}; | 141 * stored here. The first value gets the offset of the value for {0}; |
| 150 * the 2nd for {1}; the 3rd for {2} etc. -1 means that the corresponding | 142 * the 2nd for {1}; the 3rd for {2} etc. -1 means that the corresponding |
| 151 * placeholder does not exist in this object. If caller is not | 143 * placeholder does not exist in this object. If caller is not |
| 152 * interested in offsets, it may pass NULL and 0 for the length. | 144 * interested in offsets, it may pass NULL and 0 for the length. |
| 153 * @param offsetArrayLength the size of offsetArray may be less than | 145 * @param offsetArrayLength the size of offsetArray. If less than |
| 154 * placeholderValueCount. | 146 * placeholderValueCount only the first offsets get recorded. If |
| 147 * greater than placeholderValueCount, then extra values in offset |
| 148 * array are set to -1. |
| 155 * @param status any error stored here. | 149 * @param status any error stored here. |
| 156 */ | 150 */ |
| 157 UnicodeString &format( | 151 UnicodeString &formatAndAppend( |
| 158 const UnicodeString * const *placeholderValues, | 152 const UnicodeString * const *placeholderValues, |
| 159 int32_t placeholderValueCount, | 153 int32_t placeholderValueCount, |
| 160 UnicodeString &appendTo, | 154 UnicodeString &appendTo, |
| 161 int32_t *offsetArray, | 155 int32_t *offsetArray, |
| 162 int32_t offsetArrayLength, | 156 int32_t offsetArrayLength, |
| 163 UErrorCode &status) const; | 157 UErrorCode &status) const; |
| 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; |
| 164 private: | 190 private: |
| 165 UnicodeString noPlaceholders; | 191 UnicodeString noPlaceholders; |
| 166 MaybeStackArray<PlaceholderInfo, 3> placeholders; | 192 MaybeStackArray<PlaceholderInfo, 3> placeholders; |
| 167 int32_t placeholderSize; | 193 int32_t placeholderSize; |
| 168 int32_t placeholderCount; | 194 int32_t placeholderCount; |
| 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; |
| 169 | 210 |
| 170 // ensureCapacity ensures that the capacity of the placeholders array | 211 // ensureCapacity ensures that the capacity of the placeholders array |
| 171 // is desiredCapacity. If ensureCapacity must resize the placeholders | 212 // is desiredCapacity. If ensureCapacity must resize the placeholders |
| 172 // array, the first placeholderSize elements stay in the array. Note | 213 // array, the first placeholderSize elements stay in the array. Note |
| 173 // that ensureCapcity NEVER changes the value of placeholderSize only | 214 // that ensureCapcity NEVER changes the value of placeholderSize only |
| 174 // the capacity of the placeholders array. | 215 // the capacity of the placeholders array. |
| 175 // If there is no memory allocation error when resizing, this | 216 // If there is no memory allocation error when resizing, this |
| 176 // function returns desiredCapacity. If there is a memory allocation | 217 // function returns desiredCapacity. If there is a memory allocation |
| 177 // error, this function leaves the placeholders array unchanged and | 218 // error, this function leaves the placeholders array unchanged and |
| 178 // returns the smaller, old capacity. ensureCapacity resizes only if | 219 // returns the smaller, old capacity. ensureCapacity resizes only if |
| 179 // the current capacity of placeholders array is less than desiredCapacity. | 220 // the current capacity of placeholders array is less than desiredCapacity. |
| 180 // Otherwise, it leaves the placeholders array unchanged. If caller | 221 // Otherwise, it leaves the placeholders array unchanged. If caller |
| 181 // specifies an allocation size, then it must be at least as large as | 222 // specifies an allocation size, then it must be at least as large as |
| 182 // desiredCapacity. In that case, if ensureCapacity resizes, it will | 223 // desiredCapacity. In that case, if ensureCapacity resizes, it will |
| 183 // allocate allocationSize spots instead of desiredCapacity spots in | 224 // allocate allocationSize spots instead of desiredCapacity spots in |
| 184 // the array. If caller is calling ensureCapacity in a loop while adding | 225 // the array. If caller is calling ensureCapacity in a loop while adding |
| 185 // elements, it is recommended that it use an allocationSize of | 226 // elements, it is recommended that it use an allocationSize of |
| 186 // approximately twice desiredCapacity to avoid memory allocation with | 227 // approximately twice desiredCapacity to avoid memory allocation with |
| 187 // every call to ensureCapacity. | 228 // every call to ensureCapacity. |
| 188 int32_t ensureCapacity(int32_t desiredCapacity, int32_t allocationSize=0); | 229 int32_t ensureCapacity(int32_t desiredCapacity, int32_t allocationSize=0); |
| 189 | 230 |
| 190 // Records the offset of an individual placeholder in the noPlaceholders | 231 // Records the offset of an individual placeholder in the noPlaceholders |
| 191 // string. | 232 // string. |
| 192 UBool addPlaceholder(int32_t id, int32_t offset); | 233 UBool addPlaceholder(int32_t id, int32_t offset); |
| 193 }; | 234 }; |
| 194 | 235 |
| 195 U_NAMESPACE_END | 236 U_NAMESPACE_END |
| 196 | 237 |
| 197 #endif | 238 #endif |
| OLD | NEW |