| 1 | // © 2018 and later: Unicode, Inc. and others. | 
| 2 | // License & terms of use: http://www.unicode.org/copyright.html#License | 
| 3 | #ifndef __LOCALEBUILDER_H__ | 
| 4 | #define __LOCALEBUILDER_H__ | 
| 5 |  | 
| 6 | #include "unicode/utypes.h" | 
| 7 |  | 
| 8 | #if U_SHOW_CPLUSPLUS_API | 
| 9 |  | 
| 10 | #include "unicode/locid.h" | 
| 11 | #include "unicode/localematcher.h" | 
| 12 | #include "unicode/stringpiece.h" | 
| 13 | #include "unicode/uobject.h" | 
| 14 |  | 
| 15 | /** | 
| 16 |  * \file | 
| 17 |  * \brief C++ API: Builder API for Locale | 
| 18 |  */ | 
| 19 |  | 
| 20 | U_NAMESPACE_BEGIN | 
| 21 | class CharString; | 
| 22 |  | 
| 23 | /** | 
| 24 |  * <code>LocaleBuilder</code> is used to build instances of <code>Locale</code> | 
| 25 |  * from values configured by the setters.  Unlike the <code>Locale</code> | 
| 26 |  * constructors, the <code>LocaleBuilder</code> checks if a value configured by a | 
| 27 |  * setter satisfies the syntax requirements defined by the <code>Locale</code> | 
| 28 |  * class.  A <code>Locale</code> object created by a <code>LocaleBuilder</code> is | 
| 29 |  * well-formed and can be transformed to a well-formed IETF BCP 47 language tag | 
| 30 |  * without losing information. | 
| 31 |  * | 
| 32 |  * <p>The following example shows how to create a <code>Locale</code> object | 
| 33 |  * with the <code>LocaleBuilder</code>. | 
| 34 |  * <blockquote> | 
| 35 |  * <pre> | 
| 36 |  *     UErrorCode status = U_ZERO_ERROR; | 
| 37 |  *     Locale aLocale = LocaleBuilder() | 
| 38 |  *                          .setLanguage("sr") | 
| 39 |  *                          .setScript("Latn") | 
| 40 |  *                          .setRegion("RS") | 
| 41 |  *                          .build(status); | 
| 42 |  *     if (U_SUCCESS(status)) { | 
| 43 |  *       // ... | 
| 44 |  *     } | 
| 45 |  * </pre> | 
| 46 |  * </blockquote> | 
| 47 |  * | 
| 48 |  * <p>LocaleBuilders can be reused; <code>clear()</code> resets all | 
| 49 |  * fields to their default values. | 
| 50 |  * | 
| 51 |  * <p>LocaleBuilder tracks errors in an internal UErrorCode. For all setters, | 
| 52 |  * except setLanguageTag and setLocale, LocaleBuilder will return immediately | 
| 53 |  * if the internal UErrorCode is in error state. | 
| 54 |  * To reset internal state and error code, call clear method. | 
| 55 |  * The setLanguageTag and setLocale method will first clear the internal | 
| 56 |  * UErrorCode, then track the error of the validation of the input parameter | 
| 57 |  * into the internal UErrorCode. | 
| 58 |  * | 
| 59 |  * @stable ICU 64 | 
| 60 |  */ | 
| 61 | class U_COMMON_API LocaleBuilder : public UObject { | 
| 62 | public: | 
| 63 |     /** | 
| 64 |      * Constructs an empty LocaleBuilder. The default value of all | 
| 65 |      * fields, extensions, and private use information is the | 
| 66 |      * empty string. | 
| 67 |      * | 
| 68 |      * @stable ICU 64 | 
| 69 |      */ | 
| 70 |     LocaleBuilder(); | 
| 71 |  | 
| 72 |     /** | 
| 73 |      * Destructor | 
| 74 |      * @stable ICU 64 | 
| 75 |      */ | 
| 76 |     virtual ~LocaleBuilder(); | 
| 77 |  | 
| 78 |     /** | 
| 79 |      * Resets the <code>LocaleBuilder</code> to match the provided | 
| 80 |      * <code>locale</code>.  Existing state is discarded. | 
| 81 |      * | 
| 82 |      * <p>All fields of the locale must be well-formed. | 
| 83 |      * <p>This method clears the internal UErrorCode. | 
| 84 |      * | 
| 85 |      * @param locale the locale | 
| 86 |      * @return This builder. | 
| 87 |      * | 
| 88 |      * @stable ICU 64 | 
| 89 |      */ | 
| 90 |     LocaleBuilder& setLocale(const Locale& locale); | 
| 91 |  | 
| 92 |     /** | 
| 93 |      * Resets the LocaleBuilder to match the provided | 
| 94 |      * [Unicode Locale Identifier](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id) . | 
| 95 |      * Discards the existing state. the empty string cause the builder to be | 
| 96 |      * reset, like {@link #clear}.  Grandfathered tags are converted to their | 
| 97 |      * canonical form before being processed.  Otherwise, the <code>language | 
| 98 |      * tag</code> must be well-formed, or else the build() method will later | 
| 99 |      * report an U_ILLEGAL_ARGUMENT_ERROR. | 
| 100 |      * | 
| 101 |      * <p>This method clears the internal UErrorCode. | 
| 102 |      * | 
| 103 |      * @param tag the language tag, defined as | 
| 104 |      *   [unicode_locale_id](http://www.unicode.org/reports/tr35/tr35.html#unicode_locale_id). | 
| 105 |      * @return This builder. | 
| 106 |      * @stable ICU 64 | 
| 107 |      */ | 
| 108 |     LocaleBuilder& setLanguageTag(StringPiece tag); | 
| 109 |  | 
| 110 |     /** | 
| 111 |      * Sets the language.  If <code>language</code> is the empty string, the | 
| 112 |      * language in this <code>LocaleBuilder</code> is removed. Otherwise, the | 
| 113 |      * <code>language</code> must be well-formed, or else the build() method will | 
| 114 |      * later report an U_ILLEGAL_ARGUMENT_ERROR. | 
| 115 |      * | 
| 116 |      * <p>The syntax of language value is defined as | 
| 117 |      * [unicode_language_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_language_subtag). | 
| 118 |      * | 
| 119 |      * @param language the language | 
| 120 |      * @return This builder. | 
| 121 |      * @stable ICU 64 | 
| 122 |      */ | 
| 123 |     LocaleBuilder& setLanguage(StringPiece language); | 
| 124 |  | 
| 125 |     /** | 
| 126 |      * Sets the script. If <code>script</code> is the empty string, the script in | 
| 127 |      * this <code>LocaleBuilder</code> is removed. | 
| 128 |      * Otherwise, the <code>script</code> must be well-formed, or else the build() | 
| 129 |      * method will later report an U_ILLEGAL_ARGUMENT_ERROR. | 
| 130 |      * | 
| 131 |      * <p>The script value is a four-letter script code as | 
| 132 |      * [unicode_script_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_script_subtag) | 
| 133 |      * defined by ISO 15924 | 
| 134 |      * | 
| 135 |      * @param script the script | 
| 136 |      * @return This builder. | 
| 137 |      * @stable ICU 64 | 
| 138 |      */ | 
| 139 |     LocaleBuilder& setScript(StringPiece script); | 
| 140 |  | 
| 141 |     /** | 
| 142 |      * Sets the region.  If region is the empty string, the region in this | 
| 143 |      * <code>LocaleBuilder</code> is removed. Otherwise, the <code>region</code> | 
| 144 |      * must be well-formed, or else the build() method will later report an | 
| 145 |      * U_ILLEGAL_ARGUMENT_ERROR. | 
| 146 |      * | 
| 147 |      * <p>The region value is defined by | 
| 148 |      *  [unicode_region_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_region_subtag) | 
| 149 |      * as a two-letter ISO 3166 code or a three-digit UN M.49 area code. | 
| 150 |      * | 
| 151 |      * <p>The region value in the <code>Locale</code> created by the | 
| 152 |      * <code>LocaleBuilder</code> is always normalized to upper case. | 
| 153 |      * | 
| 154 |      * @param region the region | 
| 155 |      * @return This builder. | 
| 156 |      * @stable ICU 64 | 
| 157 |      */ | 
| 158 |     LocaleBuilder& setRegion(StringPiece region); | 
| 159 |  | 
| 160 |     /** | 
| 161 |      * Sets the variant.  If variant is the empty string, the variant in this | 
| 162 |      * <code>LocaleBuilder</code> is removed.  Otherwise, the <code>variant</code> | 
| 163 |      * must be well-formed, or else the build() method will later report an | 
| 164 |      * U_ILLEGAL_ARGUMENT_ERROR. | 
| 165 |      * | 
| 166 |      * <p><b>Note:</b> This method checks if <code>variant</code> | 
| 167 |      * satisfies the | 
| 168 |      * [unicode_variant_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_variant_subtag) | 
| 169 |      * syntax requirements, and normalizes the value to lowercase letters. However, | 
| 170 |      * the <code>Locale</code> class does not impose any syntactic | 
| 171 |      * restriction on variant. To set an ill-formed variant, use a Locale constructor. | 
| 172 |      * If there are multiple unicode_variant_subtag, the caller must concatenate | 
| 173 |      * them with '-' as separator (ex: "foobar-fibar"). | 
| 174 |      * | 
| 175 |      * @param variant the variant | 
| 176 |      * @return This builder. | 
| 177 |      * @stable ICU 64 | 
| 178 |      */ | 
| 179 |     LocaleBuilder& setVariant(StringPiece variant); | 
| 180 |  | 
| 181 |     /** | 
| 182 |      * Sets the extension for the given key. If the value is the empty string, | 
| 183 |      * the extension is removed.  Otherwise, the <code>key</code> and | 
| 184 |      * <code>value</code> must be well-formed, or else the build() method will | 
| 185 |      * later report an U_ILLEGAL_ARGUMENT_ERROR. | 
| 186 |      * | 
| 187 |      * <p><b>Note:</b> The key ('u') is used for the Unicode locale extension. | 
| 188 |      * Setting a value for this key replaces any existing Unicode locale key/type | 
| 189 |      * pairs with those defined in the extension. | 
| 190 |      * | 
| 191 |      * <p><b>Note:</b> The key ('x') is used for the private use code. To be | 
| 192 |      * well-formed, the value for this key needs only to have subtags of one to | 
| 193 |      * eight alphanumeric characters, not two to eight as in the general case. | 
| 194 |      * | 
| 195 |      * @param key the extension key | 
| 196 |      * @param value the extension value | 
| 197 |      * @return This builder. | 
| 198 |      * @stable ICU 64 | 
| 199 |      */ | 
| 200 |     LocaleBuilder& setExtension(char key, StringPiece value); | 
| 201 |  | 
| 202 |     /** | 
| 203 |      * Sets the Unicode locale keyword type for the given key. If the type | 
| 204 |      * StringPiece is constructed with a nullptr, the keyword is removed. | 
| 205 |      * If the type is the empty string, the keyword is set without type subtags. | 
| 206 |      * Otherwise, the key and type must be well-formed, or else the build() | 
| 207 |      * method will later report an U_ILLEGAL_ARGUMENT_ERROR. | 
| 208 |      * | 
| 209 |      * <p>Keys and types are converted to lower case. | 
| 210 |      * | 
| 211 |      * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension} | 
| 212 |      * replaces all Unicode locale keywords with those defined in the | 
| 213 |      * extension. | 
| 214 |      * | 
| 215 |      * @param key the Unicode locale key | 
| 216 |      * @param type the Unicode locale type | 
| 217 |      * @return This builder. | 
| 218 |      * @stable ICU 64 | 
| 219 |      */ | 
| 220 |     LocaleBuilder& setUnicodeLocaleKeyword( | 
| 221 |         StringPiece key, StringPiece type); | 
| 222 |  | 
| 223 |     /** | 
| 224 |      * Adds a unicode locale attribute, if not already present, otherwise | 
| 225 |      * has no effect.  The attribute must not be empty string and must be | 
| 226 |      * well-formed or U_ILLEGAL_ARGUMENT_ERROR will be set to status | 
| 227 |      * during the build() call. | 
| 228 |      * | 
| 229 |      * @param attribute the attribute | 
| 230 |      * @return This builder. | 
| 231 |      * @stable ICU 64 | 
| 232 |      */ | 
| 233 |     LocaleBuilder& addUnicodeLocaleAttribute(StringPiece attribute); | 
| 234 |  | 
| 235 |     /** | 
| 236 |      * Removes a unicode locale attribute, if present, otherwise has no | 
| 237 |      * effect.  The attribute must not be empty string and must be well-formed | 
| 238 |      * or U_ILLEGAL_ARGUMENT_ERROR will be set to status during the build() call. | 
| 239 |      * | 
| 240 |      * <p>Attribute comparison for removal is case-insensitive. | 
| 241 |      * | 
| 242 |      * @param attribute the attribute | 
| 243 |      * @return This builder. | 
| 244 |      * @stable ICU 64 | 
| 245 |      */ | 
| 246 |     LocaleBuilder& removeUnicodeLocaleAttribute(StringPiece attribute); | 
| 247 |  | 
| 248 |     /** | 
| 249 |      * Resets the builder to its initial, empty state. | 
| 250 |      * <p>This method clears the internal UErrorCode. | 
| 251 |      * | 
| 252 |      * @return this builder | 
| 253 |      * @stable ICU 64 | 
| 254 |      */ | 
| 255 |     LocaleBuilder& clear(); | 
| 256 |  | 
| 257 |     /** | 
| 258 |      * Resets the extensions to their initial, empty state. | 
| 259 |      * Language, script, region and variant are unchanged. | 
| 260 |      * | 
| 261 |      * @return this builder | 
| 262 |      * @stable ICU 64 | 
| 263 |      */ | 
| 264 |     LocaleBuilder& clearExtensions(); | 
| 265 |  | 
| 266 |     /** | 
| 267 |      * Returns an instance of <code>Locale</code> created from the fields set | 
| 268 |      * on this builder. | 
| 269 |      * If any set methods or during the build() call require memory allocation | 
| 270 |      * but fail U_MEMORY_ALLOCATION_ERROR will be set to status. | 
| 271 |      * If any of the fields set by the setters are not well-formed, the status | 
| 272 |      * will be set to U_ILLEGAL_ARGUMENT_ERROR. The state of the builder will | 
| 273 |      * not change after the build() call and the caller is free to keep using | 
| 274 |      * the same builder to build more locales. | 
| 275 |      * | 
| 276 |      * @return a new Locale | 
| 277 |      * @stable ICU 64 | 
| 278 |      */ | 
| 279 |     Locale build(UErrorCode& status); | 
| 280 |  | 
| 281 | #ifndef U_HIDE_DRAFT_API | 
| 282 |     /** | 
| 283 |      * Sets the UErrorCode if an error occurred while recording sets. | 
| 284 |      * Preserves older error codes in the outErrorCode. | 
| 285 |      * @param outErrorCode Set to an error code that occurred while setting subtags. | 
| 286 |      *                  Unchanged if there is no such error or if outErrorCode | 
| 287 |      *                  already contained an error. | 
| 288 |      * @return TRUE if U_FAILURE(outErrorCode) | 
| 289 |      * @draft ICU 65 | 
| 290 |      */ | 
| 291 |     UBool copyErrorTo(UErrorCode &outErrorCode) const; | 
| 292 | #endif  /* U_HIDE_DRAFT_API */ | 
| 293 |  | 
| 294 | private: | 
| 295 |     friend class LocaleMatcher::Result; | 
| 296 |  | 
| 297 |     void copyExtensionsFrom(const Locale& src, UErrorCode& errorCode); | 
| 298 |  | 
| 299 |     UErrorCode status_; | 
| 300 |     char language_[9]; | 
| 301 |     char script_[5]; | 
| 302 |     char region_[4]; | 
| 303 |     CharString *variant_;  // Pointer not object so we need not #include internal charstr.h. | 
| 304 |     icu::Locale *extensions_;  // Pointer not object. Storage for all other fields. | 
| 305 |  | 
| 306 | }; | 
| 307 |  | 
| 308 | U_NAMESPACE_END | 
| 309 |  | 
| 310 | #endif /* U_SHOW_CPLUSPLUS_API */ | 
| 311 |  | 
| 312 | #endif  // __LOCALEBUILDER_H__ | 
| 313 |  |