1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 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 IETF BCP 47 language tag. 94 * Discards the existing state. 95 * The empty string causes the builder to be reset, like {@link #clear}. 96 * Legacy language tags (marked as “Type: grandfathered” in BCP 47) 97 * are converted to their canonical form before being processed. 98 * Otherwise, the <code>language tag</code> must be well-formed, 99 * or else the build() method will later report an U_ILLEGAL_ARGUMENT_ERROR. 100 * 101 * <p>This method clears the internal UErrorCode. 102 * 103 * @param tag the language tag, defined as IETF BCP 47 language tag. 104 * @return This builder. 105 * @stable ICU 64 106 */ 107 LocaleBuilder& setLanguageTag(StringPiece tag); 108 109 /** 110 * Sets the language. If <code>language</code> is the empty string, the 111 * language in this <code>LocaleBuilder</code> is removed. Otherwise, the 112 * <code>language</code> must be well-formed, or else the build() method will 113 * later report an U_ILLEGAL_ARGUMENT_ERROR. 114 * 115 * <p>The syntax of language value is defined as 116 * [unicode_language_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_language_subtag). 117 * 118 * @param language the language 119 * @return This builder. 120 * @stable ICU 64 121 */ 122 LocaleBuilder& setLanguage(StringPiece language); 123 124 /** 125 * Sets the script. If <code>script</code> is the empty string, the script in 126 * this <code>LocaleBuilder</code> is removed. 127 * Otherwise, the <code>script</code> must be well-formed, or else the build() 128 * method will later report an U_ILLEGAL_ARGUMENT_ERROR. 129 * 130 * <p>The script value is a four-letter script code as 131 * [unicode_script_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_script_subtag) 132 * defined by ISO 15924 133 * 134 * @param script the script 135 * @return This builder. 136 * @stable ICU 64 137 */ 138 LocaleBuilder& setScript(StringPiece script); 139 140 /** 141 * Sets the region. If region is the empty string, the region in this 142 * <code>LocaleBuilder</code> is removed. Otherwise, the <code>region</code> 143 * must be well-formed, or else the build() method will later report an 144 * U_ILLEGAL_ARGUMENT_ERROR. 145 * 146 * <p>The region value is defined by 147 * [unicode_region_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_region_subtag) 148 * as a two-letter ISO 3166 code or a three-digit UN M.49 area code. 149 * 150 * <p>The region value in the <code>Locale</code> created by the 151 * <code>LocaleBuilder</code> is always normalized to upper case. 152 * 153 * @param region the region 154 * @return This builder. 155 * @stable ICU 64 156 */ 157 LocaleBuilder& setRegion(StringPiece region); 158 159 /** 160 * Sets the variant. If variant is the empty string, the variant in this 161 * <code>LocaleBuilder</code> is removed. Otherwise, the <code>variant</code> 162 * must be well-formed, or else the build() method will later report an 163 * U_ILLEGAL_ARGUMENT_ERROR. 164 * 165 * <p><b>Note:</b> This method checks if <code>variant</code> 166 * satisfies the 167 * [unicode_variant_subtag](http://www.unicode.org/reports/tr35/tr35.html#unicode_variant_subtag) 168 * syntax requirements, and normalizes the value to lowercase letters. However, 169 * the <code>Locale</code> class does not impose any syntactic 170 * restriction on variant. To set an ill-formed variant, use a Locale constructor. 171 * If there are multiple unicode_variant_subtag, the caller must concatenate 172 * them with '-' as separator (ex: "foobar-fibar"). 173 * 174 * @param variant the variant 175 * @return This builder. 176 * @stable ICU 64 177 */ 178 LocaleBuilder& setVariant(StringPiece variant); 179 180 /** 181 * Sets the extension for the given key. If the value is the empty string, 182 * the extension is removed. Otherwise, the <code>key</code> and 183 * <code>value</code> must be well-formed, or else the build() method will 184 * later report an U_ILLEGAL_ARGUMENT_ERROR. 185 * 186 * <p><b>Note:</b> The key ('u') is used for the Unicode locale extension. 187 * Setting a value for this key replaces any existing Unicode locale key/type 188 * pairs with those defined in the extension. 189 * 190 * <p><b>Note:</b> The key ('x') is used for the private use code. To be 191 * well-formed, the value for this key needs only to have subtags of one to 192 * eight alphanumeric characters, not two to eight as in the general case. 193 * 194 * @param key the extension key 195 * @param value the extension value 196 * @return This builder. 197 * @stable ICU 64 198 */ 199 LocaleBuilder& setExtension(char key, StringPiece value); 200 201 /** 202 * Sets the Unicode locale keyword type for the given key. If the type 203 * StringPiece is constructed with a nullptr, the keyword is removed. 204 * If the type is the empty string, the keyword is set without type subtags. 205 * Otherwise, the key and type must be well-formed, or else the build() 206 * method will later report an U_ILLEGAL_ARGUMENT_ERROR. 207 * 208 * <p>Keys and types are converted to lower case. 209 * 210 * <p><b>Note</b>:Setting the 'u' extension via {@link #setExtension} 211 * replaces all Unicode locale keywords with those defined in the 212 * extension. 213 * 214 * @param key the Unicode locale key 215 * @param type the Unicode locale type 216 * @return This builder. 217 * @stable ICU 64 218 */ 219 LocaleBuilder& setUnicodeLocaleKeyword( 220 StringPiece key, StringPiece type); 221 222 /** 223 * Adds a unicode locale attribute, if not already present, otherwise 224 * has no effect. The attribute must not be empty string and must be 225 * well-formed or U_ILLEGAL_ARGUMENT_ERROR will be set to status 226 * during the build() call. 227 * 228 * @param attribute the attribute 229 * @return This builder. 230 * @stable ICU 64 231 */ 232 LocaleBuilder& addUnicodeLocaleAttribute(StringPiece attribute); 233 234 /** 235 * Removes a unicode locale attribute, if present, otherwise has no 236 * effect. The attribute must not be empty string and must be well-formed 237 * or U_ILLEGAL_ARGUMENT_ERROR will be set to status during the build() call. 238 * 239 * <p>Attribute comparison for removal is case-insensitive. 240 * 241 * @param attribute the attribute 242 * @return This builder. 243 * @stable ICU 64 244 */ 245 LocaleBuilder& removeUnicodeLocaleAttribute(StringPiece attribute); 246 247 /** 248 * Resets the builder to its initial, empty state. 249 * <p>This method clears the internal UErrorCode. 250 * 251 * @return this builder 252 * @stable ICU 64 253 */ 254 LocaleBuilder& clear(); 255 256 /** 257 * Resets the extensions to their initial, empty state. 258 * Language, script, region and variant are unchanged. 259 * 260 * @return this builder 261 * @stable ICU 64 262 */ 263 LocaleBuilder& clearExtensions(); 264 265 /** 266 * Returns an instance of <code>Locale</code> created from the fields set 267 * on this builder. 268 * If any set methods or during the build() call require memory allocation 269 * but fail U_MEMORY_ALLOCATION_ERROR will be set to status. 270 * If any of the fields set by the setters are not well-formed, the status 271 * will be set to U_ILLEGAL_ARGUMENT_ERROR. The state of the builder will 272 * not change after the build() call and the caller is free to keep using 273 * the same builder to build more locales. 274 * 275 * @return a new Locale 276 * @stable ICU 64 277 */ 278 Locale build(UErrorCode& status); 279 280 /** 281 * Sets the UErrorCode if an error occurred while recording sets. 282 * Preserves older error codes in the outErrorCode. 283 * @param outErrorCode Set to an error code that occurred while setting subtags. 284 * Unchanged if there is no such error or if outErrorCode 285 * already contained an error. 286 * @return true if U_FAILURE(outErrorCode) 287 * @stable ICU 65 288 */ 289 UBool copyErrorTo(UErrorCode &outErrorCode) const; 290 291 private: 292 friend class LocaleMatcher::Result; 293 294 void copyExtensionsFrom(const Locale& src, UErrorCode& errorCode); 295 296 UErrorCode status_; 297 char language_[9]; 298 char script_[5]; 299 char region_[4]; 300 CharString *variant_; // Pointer not object so we need not #include internal charstr.h. 301 icu::Locale *extensions_; // Pointer not object. Storage for all other fields. 302 303 }; 304 305 U_NAMESPACE_END 306 307 #endif /* U_SHOW_CPLUSPLUS_API */ 308 309 #endif // __LOCALEBUILDER_H__ 310