Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(561)

Side by Side Diff: source/i18n/region.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/i18n/regeximp.cpp ('k') | source/i18n/reldatefmt.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ******************************************************************************* 2 *******************************************************************************
3 * Copyright (C) 2013, International Business Machines Corporation and 3 * Copyright (C) 2014, International Business Machines Corporation and
4 * others. All Rights Reserved. 4 * others. All Rights Reserved.
5 ******************************************************************************* 5 *******************************************************************************
6 * 6 *
7 * 7 *
8 * File REGION.CPP 8 * File REGION.CPP
9 * 9 *
10 * Modification History:* 10 * Modification History:*
11 * Date Name Description 11 * Date Name Description
12 * 01/15/13 Emmons Original Port from ICU4J 12 * 01/15/13 Emmons Original Port from ICU4J
13 ******************************************************************************** 13 ********************************************************************************
14 */ 14 */
15 15
16 /** 16 /**
17 * \file 17 * \file
18 * \brief C++ API: Region classes (territory containment) 18 * \brief C++ API: Region classes (territory containment)
19 */ 19 */
20 20
21 #include "unicode/region.h" 21 #include "unicode/region.h"
22 #include "unicode/utypes.h" 22 #include "unicode/utypes.h"
23 #include "unicode/uobject.h" 23 #include "unicode/uobject.h"
24 #include "unicode/unistr.h" 24 #include "unicode/unistr.h"
25 #include "unicode/ures.h" 25 #include "unicode/ures.h"
26 #include "unicode/decimfmt.h" 26 #include "unicode/decimfmt.h"
27 #include "ucln_in.h" 27 #include "ucln_in.h"
28 #include "cstring.h" 28 #include "cstring.h"
29 #include "mutex.h"
29 #include "uhash.h" 30 #include "uhash.h"
30 #include "umutex.h" 31 #include "umutex.h"
31 #include "uresimp.h" 32 #include "uresimp.h"
32 #include "region_impl.h" 33 #include "region_impl.h"
33 34
34 #if !UCONFIG_NO_FORMATTING 35 #if !UCONFIG_NO_FORMATTING
35 36
36 37
37 U_CDECL_BEGIN 38 U_CDECL_BEGIN
38 39
39 static void U_CALLCONV 40 static void U_CALLCONV
40 deleteRegion(void *obj) { 41 deleteRegion(void *obj) {
41 delete (icu::Region *)obj; 42 delete (icu::Region *)obj;
42 } 43 }
43 44
44 /** 45 /**
45 * Cleanup callback func 46 * Cleanup callback func
46 */ 47 */
47 static UBool U_CALLCONV region_cleanup(void) 48 static UBool U_CALLCONV region_cleanup(void)
48 { 49 {
49 icu::Region::cleanupRegionData(); 50 icu::Region::cleanupRegionData();
50 51
51 return TRUE; 52 return TRUE;
52 } 53 }
53 54
54 U_CDECL_END 55 U_CDECL_END
55 56
56 U_NAMESPACE_BEGIN 57 U_NAMESPACE_BEGIN
57 58
58 static UMutex gRegionDataLock = U_MUTEX_INITIALIZER; 59 static UInitOnce gRegionDataInitOnce = U_INITONCE_INITIALIZER;
59 static UBool regionDataIsLoaded = false;
60 static UVector* availableRegions[URGN_LIMIT]; 60 static UVector* availableRegions[URGN_LIMIT];
61 61
62 static UHashtable *regionAliases; 62 static UHashtable *regionAliases;
63 static UHashtable *regionIDMap; 63 static UHashtable *regionIDMap;
64 static UHashtable *numericCodeMap; 64 static UHashtable *numericCodeMap;
65 65
66 static const UChar UNKNOWN_REGION_ID [] = { 0x5A, 0x5A, 0 }; /* "ZZ" */ 66 static const UChar UNKNOWN_REGION_ID [] = { 0x5A, 0x5A, 0 }; /* "ZZ" */
67 static const UChar OUTLYING_OCEANIA_REGION_ID [] = { 0x51, 0x4F, 0 }; /* "QO" * / 67 static const UChar OUTLYING_OCEANIA_REGION_ID [] = { 0x51, 0x4F, 0 }; /* "QO" * /
68 static const UChar WORLD_ID [] = { 0x30, 0x30, 0x31, 0 }; /* "001" */ 68 static const UChar WORLD_ID [] = { 0x30, 0x30, 0x31, 0 }; /* "001" */
69 69
70 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration) 70 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration)
71 71
72 /* 72 /*
73 * Initializes the region data from the ICU resource bundles. The region data 73 * Initializes the region data from the ICU resource bundles. The region data
74 * contains the basic relationships such as which regions are known, what the nu meric 74 * contains the basic relationships such as which regions are known, what the nu meric
75 * codes are, any known aliases, and the territory containment data. 75 * codes are, any known aliases, and the territory containment data.
76 * 76 *
77 * If the region data has already loaded, then this method simply returns withou t doing 77 * If the region data has already loaded, then this method simply returns withou t doing
78 * anything meaningful. 78 * anything meaningful.
79 */ 79 */
80 void Region::loadRegionData() { 80 void Region::loadRegionData(UErrorCode &status) {
81 81 LocalPointer<DecimalFormat> df(new DecimalFormat(status));
82 if (regionDataIsLoaded) { 82 if (U_FAILURE(status)) {
83 return; 83 return;
84 } 84 }
85 85 if (df == NULL) {
86 umtx_lock(&gRegionDataLock); 86 status = U_MEMORY_ALLOCATION_ERROR;
87
88 if (regionDataIsLoaded) { // In case another thread gets to it before we do. ..
89 umtx_unlock(&gRegionDataLock);
90 return;
91 }
92
93
94 UErrorCode status = U_ZERO_ERROR;
95
96 UResourceBundle* regionCodes = NULL;
97 UResourceBundle* territoryAlias = NULL;
98 UResourceBundle* codeMappings = NULL;
99 UResourceBundle* worldContainment = NULL;
100 UResourceBundle* territoryContainment = NULL;
101 UResourceBundle* groupingContainment = NULL;
102
103 DecimalFormat *df = new DecimalFormat(status);
104 if (U_FAILURE(status)) {
105 umtx_unlock(&gRegionDataLock);
106 return; 87 return;
107 } 88 }
108 df->setParseIntegerOnly(TRUE); 89 df->setParseIntegerOnly(TRUE);
109 90
110 regionIDMap = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeString, NULL,&status); 91 regionIDMap = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString , NULL, &status);
92 if (U_FAILURE(status)) {
93 return;
94 }
95 if (regionIDMap == NULL) {
96 status = U_MEMORY_ALLOCATION_ERROR;
97 return;
98 }
111 uhash_setValueDeleter(regionIDMap, deleteRegion); 99 uhash_setValueDeleter(regionIDMap, deleteRegion);
112 100
113 numericCodeMap = uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status); 101 numericCodeMap = uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status);
114 102
115 regionAliases = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeStrin g,NULL,&status); 103 regionAliases = uhash_open(uhash_hashUnicodeString,uhash_compareUnicodeStrin g,NULL,&status);
104 if (U_FAILURE(status)) {
105 return;
106 }
107 if (regionAliases == NULL) {
108 status = U_MEMORY_ALLOCATION_ERROR;
109 return;
110 }
116 uhash_setKeyDeleter(regionAliases,uprv_deleteUObject); 111 uhash_setKeyDeleter(regionAliases,uprv_deleteUObject);
117 112
118 UResourceBundle *rb = ures_openDirect(NULL,"metadata",&status); 113 LocalUResourceBundlePointer rb(ures_openDirect(NULL,"metadata",&status));
119 regionCodes = ures_getByKey(rb,"regionCodes",NULL,&status); 114 LocalUResourceBundlePointer regionCodes(ures_getByKey(rb.getAlias(),"regionC odes",NULL,&status));
120 territoryAlias = ures_getByKey(rb,"territoryAlias",NULL,&status); 115 LocalUResourceBundlePointer territoryAlias(ures_getByKey(rb.getAlias(),"terr itoryAlias",NULL,&status));
121 116
122 UResourceBundle *rb2 = ures_openDirect(NULL,"supplementalData",&status); 117 LocalUResourceBundlePointer rb2(ures_openDirect(NULL,"supplementalData",&sta tus));
123 codeMappings = ures_getByKey(rb2,"codeMappings",NULL,&status); 118 LocalUResourceBundlePointer codeMappings(ures_getByKey(rb2.getAlias(),"codeM appings",NULL,&status));
124 119
125 territoryContainment = ures_getByKey(rb2,"territoryContainment",NULL,&status ); 120 LocalUResourceBundlePointer territoryContainment(ures_getByKey(rb2.getAlias( ),"territoryContainment",NULL,&status));
126 worldContainment = ures_getByKey(territoryContainment,"001",NULL,&status); 121 LocalUResourceBundlePointer worldContainment(ures_getByKey(territoryContainm ent.getAlias(),"001",NULL,&status));
127 groupingContainment = ures_getByKey(territoryContainment,"grouping",NULL,&st atus); 122 LocalUResourceBundlePointer groupingContainment(ures_getByKey(territoryConta inment.getAlias(),"grouping",NULL,&status));
128 123
129 UVector *continents = new UVector(uprv_deleteUObject, uhash_compareUnicodeSt ring, status); 124 UVector *continents = new UVector(uprv_deleteUObject, uhash_compareUnicodeSt ring, status);
130 125
131 while ( ures_hasNext(worldContainment) ) { 126 while ( ures_hasNext(worldContainment.getAlias()) ) {
132 UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeStri ng(worldContainment,NULL,&status)); 127 UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeStri ng(worldContainment.getAlias(),NULL,&status));
133 continents->addElement(continentName,status); 128 continents->addElement(continentName,status);
134 } 129 }
135 130
136 UVector *groupings = new UVector(uprv_deleteUObject, uhash_compareUnicodeStr ing, status); 131 UVector *groupings = new UVector(uprv_deleteUObject, uhash_compareUnicodeStr ing, status);
137 while ( ures_hasNext(groupingContainment) ) { 132 while ( ures_hasNext(groupingContainment.getAlias()) ) {
138 UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeStrin g(groupingContainment,NULL,&status)); 133 UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeStrin g(groupingContainment.getAlias(),NULL,&status));
139 groupings->addElement(groupingName,status); 134 groupings->addElement(groupingName,status);
140 } 135 }
141 136
142 while ( ures_hasNext(regionCodes) ) { 137 while ( ures_hasNext(regionCodes.getAlias()) ) {
143 UnicodeString regionID = ures_getNextUnicodeString(regionCodes,NULL,&sta tus); 138 UnicodeString regionID = ures_getNextUnicodeString(regionCodes.getAlias( ), NULL, &status);
144 Region *r = new Region(); 139 Region *r = new Region();
145 r->idStr = regionID; 140 r->idStr = regionID;
146 r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV); 141 r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV);
147 r->type = URGN_TERRITORY; // Only temporary - figure out the real type l ater once the aliases are known. 142 r->type = URGN_TERRITORY; // Only temporary - figure out the real type l ater once the aliases are known.
148 143
149 uhash_put(regionIDMap,(void *)&(r->idStr),(void *)r,&status); 144 uhash_put(regionIDMap,(void *)&(r->idStr),(void *)r,&status);
150 Formattable result; 145 Formattable result;
151 UErrorCode ps = U_ZERO_ERROR; 146 UErrorCode ps = U_ZERO_ERROR;
152 df->parse(r->idStr,result,ps); 147 df->parse(r->idStr,result,ps);
153 if ( U_SUCCESS(ps) ) { 148 if ( U_SUCCESS(ps) ) {
154 r->code = result.getLong(); // Convert string to number 149 r->code = result.getLong(); // Convert string to number
155 uhash_iput(numericCodeMap,r->code,(void *)r,&status); 150 uhash_iput(numericCodeMap,r->code,(void *)r,&status);
156 r->type = URGN_SUBCONTINENT; 151 r->type = URGN_SUBCONTINENT;
157 } else { 152 } else {
158 r->code = -1; 153 r->code = -1;
159 } 154 }
160 } 155 }
161 156
162 157
163 // Process the territory aliases 158 // Process the territory aliases
164 while ( ures_hasNext(territoryAlias) ) { 159 while ( ures_hasNext(territoryAlias.getAlias()) ) {
165 UResourceBundle *res = ures_getNextResource(territoryAlias,NULL,&status) ; 160 UResourceBundle *res = ures_getNextResource(territoryAlias.getAlias(),NU LL,&status);
166 const char *aliasFrom = ures_getKey(res); 161 const char *aliasFrom = ures_getKey(res);
167 UnicodeString* aliasFromStr = new UnicodeString(aliasFrom, -1, US_INV); 162 UnicodeString* aliasFromStr = new UnicodeString(aliasFrom, -1, US_INV);
168 UnicodeString aliasTo = ures_getUnicodeString(res,&status); 163 UnicodeString aliasTo = ures_getUnicodeString(res,&status);
169 ures_close(res); 164 ures_close(res);
170 165
171 Region *aliasToRegion = (Region *) uhash_get(regionIDMap,&aliasTo); 166 Region *aliasToRegion = (Region *) uhash_get(regionIDMap,&aliasTo);
172 Region *aliasFromRegion = (Region *)uhash_get(regionIDMap,aliasFromStr); 167 Region *aliasFromRegion = (Region *)uhash_get(regionIDMap,aliasFromStr);
173 168
174 if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is jus t an alias from some string to a region 169 if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is jus t an alias from some string to a region
175 uhash_put(regionAliases,(void *)aliasFromStr, (void *)aliasToRegion, &status); 170 uhash_put(regionAliases,(void *)aliasFromStr, (void *)aliasToRegion, &status);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 UnicodeString *preferredValue = new UnicodeString(target ->idStr); 202 UnicodeString *preferredValue = new UnicodeString(target ->idStr);
208 aliasFromRegion->preferredValues->addElement((void *)pre ferredValue,status); 203 aliasFromRegion->preferredValues->addElement((void *)pre ferredValue,status);
209 } 204 }
210 currentRegion.remove(); 205 currentRegion.remove();
211 } 206 }
212 } 207 }
213 } 208 }
214 } 209 }
215 210
216 // Process the code mappings - This will allow us to assign numeric codes to most of the territories. 211 // Process the code mappings - This will allow us to assign numeric codes to most of the territories.
217 while ( ures_hasNext(codeMappings) ) { 212 while ( ures_hasNext(codeMappings.getAlias()) ) {
218 UResourceBundle *mapping = ures_getNextResource(codeMappings,NULL,&statu s); 213 UResourceBundle *mapping = ures_getNextResource(codeMappings.getAlias(), NULL,&status);
219 if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) { 214 if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3) {
220 UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0 ,&status); 215 UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0 ,&status);
221 UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mappi ng,1,&status); 216 UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mappi ng,1,&status);
222 UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapp ing,2,&status); 217 UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapp ing,2,&status);
223 218
224 Region *r = (Region *)uhash_get(regionIDMap,(void *)&codeMappingID); 219 Region *r = (Region *)uhash_get(regionIDMap,(void *)&codeMappingID);
225 if ( r ) { 220 if ( r ) {
226 Formattable result; 221 Formattable result;
227 UErrorCode ps = U_ZERO_ERROR; 222 UErrorCode ps = U_ZERO_ERROR;
228 df->parse(codeMappingNumber,result,ps); 223 df->parse(codeMappingNumber,result,ps);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 // Special case: The region code "QO" (Outlying Oceania) is a subcontinent c ode added by CLDR 265 // Special case: The region code "QO" (Outlying Oceania) is a subcontinent c ode added by CLDR
271 // even though it looks like a territory code. Need to handle it here. 266 // even though it looks like a territory code. Need to handle it here.
272 267
273 UnicodeString OUTLYING_OCEANIA_REGION_ID_STRING(OUTLYING_OCEANIA_REGION_ ID); 268 UnicodeString OUTLYING_OCEANIA_REGION_ID_STRING(OUTLYING_OCEANIA_REGION_ ID);
274 r = (Region *) uhash_get(regionIDMap,(void *)&OUTLYING_OCEANIA_REGION_ID_STR ING); 269 r = (Region *) uhash_get(regionIDMap,(void *)&OUTLYING_OCEANIA_REGION_ID_STR ING);
275 if ( r ) { 270 if ( r ) {
276 r->type = URGN_SUBCONTINENT; 271 r->type = URGN_SUBCONTINENT;
277 } 272 }
278 273
279 // Load territory containment info from the supplemental data. 274 // Load territory containment info from the supplemental data.
280 while ( ures_hasNext(territoryContainment) ) { 275 while ( ures_hasNext(territoryContainment.getAlias()) ) {
281 UResourceBundle *mapping = ures_getNextResource(territoryContainment,NUL L,&status); 276 UResourceBundle *mapping = ures_getNextResource(territoryContainment.get Alias(),NULL,&status);
282 const char *parent = ures_getKey(mapping); 277 const char *parent = ures_getKey(mapping);
278 if (uprv_strcmp(parent, "containedGroupings") == 0 || uprv_strcmp(parent , "deprecated") == 0) {
279 ures_close(mapping);
280 continue; // handle new pseudo-parent types added in ICU data per cl drbug 7808; for now just skip.
281 // #11232 is to do something useful with these.
282 }
283 UnicodeString parentStr = UnicodeString(parent, -1 , US_INV); 283 UnicodeString parentStr = UnicodeString(parent, -1 , US_INV);
284 Region *parentRegion = (Region *) uhash_get(regionIDMap,(void *)&parentS tr); 284 Region *parentRegion = (Region *) uhash_get(regionIDMap,(void *)&parentS tr);
285 285
286 for ( int j = 0 ; j < ures_getSize(mapping); j++ ) { 286 for ( int j = 0 ; j < ures_getSize(mapping); j++ ) {
287 UnicodeString child = ures_getUnicodeStringByIndex(mapping,j,&status ); 287 UnicodeString child = ures_getUnicodeStringByIndex(mapping,j,&status );
288 Region *childRegion = (Region *) uhash_get(regionIDMap,(void *)&chil d); 288 Region *childRegion = (Region *) uhash_get(regionIDMap,(void *)&chil d);
289 if ( parentRegion != NULL && childRegion != NULL ) { 289 if ( parentRegion != NULL && childRegion != NULL ) {
290 290
291 // Add the child region to the set of regions contained by the p arent 291 // Add the child region to the set of regions contained by the p arent
292 if (parentRegion->containedRegions == NULL) { 292 if (parentRegion->containedRegions == NULL) {
(...skipping 19 matching lines...) Expand all
312 int32_t pos = -1; 312 int32_t pos = -1;
313 while ( const UHashElement* element = uhash_nextElement(regionIDMap,&pos)) { 313 while ( const UHashElement* element = uhash_nextElement(regionIDMap,&pos)) {
314 Region *ar = (Region *)element->value.pointer; 314 Region *ar = (Region *)element->value.pointer;
315 if ( availableRegions[ar->type] == NULL ) { 315 if ( availableRegions[ar->type] == NULL ) {
316 availableRegions[ar->type] = new UVector(uprv_deleteUObject, uhash_c ompareUnicodeString, status); 316 availableRegions[ar->type] = new UVector(uprv_deleteUObject, uhash_c ompareUnicodeString, status);
317 } 317 }
318 UnicodeString *arString = new UnicodeString(ar->idStr); 318 UnicodeString *arString = new UnicodeString(ar->idStr);
319 availableRegions[ar->type]->addElement((void *)arString,status); 319 availableRegions[ar->type]->addElement((void *)arString,status);
320 } 320 }
321 321
322 ures_close(territoryContainment);
323 ures_close(worldContainment);
324 ures_close(groupingContainment);
325
326 ures_close(codeMappings);
327 ures_close(rb2);
328 ures_close(territoryAlias);
329 ures_close(regionCodes);
330 ures_close(rb);
331
332 delete df;
333
334 ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup); 322 ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup);
335
336 regionDataIsLoaded = true;
337 umtx_unlock(&gRegionDataLock);
338
339 } 323 }
340 324
341 void Region::cleanupRegionData() { 325 void Region::cleanupRegionData() {
342
343 for (int32_t i = 0 ; i < URGN_LIMIT ; i++ ) { 326 for (int32_t i = 0 ; i < URGN_LIMIT ; i++ ) {
344 if ( availableRegions[i] ) { 327 if ( availableRegions[i] ) {
345 delete availableRegions[i]; 328 delete availableRegions[i];
346 } 329 }
347 } 330 }
348 331
349 if (regionAliases) { 332 if (regionAliases) {
350 uhash_close(regionAliases); 333 uhash_close(regionAliases);
351 } 334 }
352 335
353 if (numericCodeMap) { 336 if (numericCodeMap) {
354 uhash_close(numericCodeMap); 337 uhash_close(numericCodeMap);
355 } 338 }
356 339
357 if (regionIDMap) { 340 if (regionIDMap) {
358 uhash_close(regionIDMap); 341 uhash_close(regionIDMap);
359 } 342 }
343 gRegionDataInitOnce.reset();
360 } 344 }
361 345
362 Region::Region () 346 Region::Region ()
363 : code(-1), 347 : code(-1),
364 type(URGN_UNKNOWN), 348 type(URGN_UNKNOWN),
365 containingRegion(NULL), 349 containingRegion(NULL),
366 containedRegions(NULL), 350 containedRegions(NULL),
367 preferredValues(NULL) { 351 preferredValues(NULL) {
368 id[0] = 0; 352 id[0] = 0;
369 } 353 }
(...skipping 25 matching lines...) Expand all
395 379
396 /** 380 /**
397 * Returns a pointer to a Region using the given region code. The region code c an be either 2-letter ISO code, 381 * Returns a pointer to a Region using the given region code. The region code c an be either 2-letter ISO code,
398 * 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code a s defined by the LDML specification. 382 * 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code a s defined by the LDML specification.
399 * The identifier will be canonicalized internally using the supplemental metada ta as defined in the CLDR. 383 * The identifier will be canonicalized internally using the supplemental metada ta as defined in the CLDR.
400 * If the region code is NULL or not recognized, the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ) 384 * If the region code is NULL or not recognized, the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR )
401 */ 385 */
402 const Region* U_EXPORT2 386 const Region* U_EXPORT2
403 Region::getInstance(const char *region_code, UErrorCode &status) { 387 Region::getInstance(const char *region_code, UErrorCode &status) {
404 388
389 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
390 if (U_FAILURE(status)) {
391 return NULL;
392 }
393
405 if ( !region_code ) { 394 if ( !region_code ) {
406 status = U_ILLEGAL_ARGUMENT_ERROR; 395 status = U_ILLEGAL_ARGUMENT_ERROR;
407 return NULL; 396 return NULL;
408 } 397 }
409
410 loadRegionData();
411
412 if (regionIDMap == NULL) {
413 status = U_ILLEGAL_ARGUMENT_ERROR;
414 return NULL;
415 }
416 398
417 UnicodeString regionCodeString = UnicodeString(region_code, -1, US_INV); 399 UnicodeString regionCodeString = UnicodeString(region_code, -1, US_INV);
418 Region *r = (Region *)uhash_get(regionIDMap,(void *)&regionCodeString); 400 Region *r = (Region *)uhash_get(regionIDMap,(void *)&regionCodeString);
419 401
420 if ( !r ) { 402 if ( !r ) {
421 r = (Region *)uhash_get(regionAliases,(void *)&regionCodeString); 403 r = (Region *)uhash_get(regionAliases,(void *)&regionCodeString);
422 } 404 }
423 405
424 if ( !r ) { // Unknown region code 406 if ( !r ) { // Unknown region code
425 status = U_ILLEGAL_ARGUMENT_ERROR; 407 status = U_ILLEGAL_ARGUMENT_ERROR;
(...skipping 12 matching lines...) Expand all
438 420
439 } 421 }
440 422
441 /** 423 /**
442 * Returns a pointer to a Region using the given numeric region code. If the num eric region code is not recognized, 424 * Returns a pointer to a Region using the given numeric region code. If the num eric region code is not recognized,
443 * the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ). 425 * the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ).
444 */ 426 */
445 const Region* U_EXPORT2 427 const Region* U_EXPORT2
446 Region::getInstance (int32_t code, UErrorCode &status) { 428 Region::getInstance (int32_t code, UErrorCode &status) {
447 429
448 loadRegionData(); 430 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
449 431 if (U_FAILURE(status)) {
450 if (numericCodeMap == NULL) {
451 status = U_ILLEGAL_ARGUMENT_ERROR;
452 return NULL; 432 return NULL;
453 } 433 }
454 434
455 Region *r = (Region *)uhash_iget(numericCodeMap,code); 435 Region *r = (Region *)uhash_iget(numericCodeMap,code);
456 436
457 if ( !r ) { // Just in case there's an alias that's numeric, try to find it. 437 if ( !r ) { // Just in case there's an alias that's numeric, try to find it.
458 UErrorCode fs = U_ZERO_ERROR; 438 UErrorCode fs = U_ZERO_ERROR;
459 UnicodeString pat = UNICODE_STRING_SIMPLE("00#"); 439 UnicodeString pat = UNICODE_STRING_SIMPLE("00#");
460 DecimalFormat *df = new DecimalFormat(pat,fs); 440 DecimalFormat *df = new DecimalFormat(pat,fs);
461 441
(...skipping 19 matching lines...) Expand all
481 461
482 return r; 462 return r;
483 } 463 }
484 464
485 465
486 /** 466 /**
487 * Returns an enumeration over the IDs of all known regions that match the given type. 467 * Returns an enumeration over the IDs of all known regions that match the given type.
488 */ 468 */
489 StringEnumeration* U_EXPORT2 469 StringEnumeration* U_EXPORT2
490 Region::getAvailable(URegionType type) { 470 Region::getAvailable(URegionType type) {
491
492 loadRegionData();
493 UErrorCode status = U_ZERO_ERROR; 471 UErrorCode status = U_ZERO_ERROR;
472 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
473 if (U_FAILURE(status)) {
474 return NULL;
475 }
494 return new RegionNameEnumeration(availableRegions[type],status); 476 return new RegionNameEnumeration(availableRegions[type],status);
495
496 return NULL;
497 } 477 }
498 478
499 /** 479 /**
500 * Returns a pointer to the region that contains this region. Returns NULL if t his region is code "001" (World) 480 * Returns a pointer to the region that contains this region. Returns NULL if t his region is code "001" (World)
501 * or "ZZ" (Unknown region). For example, calling this method with region "IT" ( Italy) returns the 481 * or "ZZ" (Unknown region). For example, calling this method with region "IT" ( Italy) returns the
502 * region "039" (Southern Europe). 482 * region "039" (Southern Europe).
503 */ 483 */
504 const Region* 484 const Region*
505 Region::getContainingRegion() const { 485 Region::getContainingRegion() const {
506 loadRegionData(); 486 UErrorCode status = U_ZERO_ERROR;
487 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
507 return containingRegion; 488 return containingRegion;
508 } 489 }
509 490
510 /** 491 /**
511 * Return a pointer to the region that geographically contains this region and m atches the given type, 492 * Return a pointer to the region that geographically contains this region and m atches the given type,
512 * moving multiple steps up the containment chain if necessary. Returns NULL if no containing region can be found 493 * moving multiple steps up the containment chain if necessary. Returns NULL if no containing region can be found
513 * that matches the given type. Note: The URegionTypes = "URGN_GROUPING", "URGN_ DEPRECATED", or "URGN_UNKNOWN" 494 * that matches the given type. Note: The URegionTypes = "URGN_GROUPING", "URGN_ DEPRECATED", or "URGN_UNKNOWN"
514 * are not appropriate for use in this API. NULL will be returned in this case. For example, calling this method 495 * are not appropriate for use in this API. NULL will be returned in this case. For example, calling this method
515 * with region "IT" (Italy) for type "URGN_CONTINENT" returns the region "150" ( Europe ). 496 * with region "IT" (Italy) for type "URGN_CONTINENT" returns the region "150" ( Europe ).
516 */ 497 */
517 const Region* 498 const Region*
518 Region::getContainingRegion(URegionType type) const { 499 Region::getContainingRegion(URegionType type) const {
519 loadRegionData(); 500 UErrorCode status = U_ZERO_ERROR;
501 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
520 if ( containingRegion == NULL ) { 502 if ( containingRegion == NULL ) {
521 return NULL; 503 return NULL;
522 } 504 }
523 505
524 if ( containingRegion->type == type ) { 506 if ( containingRegion->type == type ) {
525 return containingRegion; 507 return containingRegion;
526 } else { 508 } else {
527 return containingRegion->getContainingRegion(type); 509 return containingRegion->getContainingRegion(type);
528 } 510 }
529 } 511 }
530 512
531 /** 513 /**
532 * Return an enumeration over the IDs of all the regions that are immediate chil dren of this region in the 514 * Return an enumeration over the IDs of all the regions that are immediate chil dren of this region in the
533 * region hierarchy. These returned regions could be either macro regions, terri tories, or a mixture of the two, 515 * region hierarchy. These returned regions could be either macro regions, terri tories, or a mixture of the two,
534 * depending on the containment data as defined in CLDR. This API may return NU LL if this region doesn't have 516 * depending on the containment data as defined in CLDR. This API may return NU LL if this region doesn't have
535 * any sub-regions. For example, calling this method with region "150" (Europe) returns an enumeration containing 517 * any sub-regions. For example, calling this method with region "150" (Europe) returns an enumeration containing
536 * the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern Europe) - "154" (Northern Europe) 518 * the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern Europe) - "154" (Northern Europe)
537 * and "155" (Western Europe). 519 * and "155" (Western Europe).
538 */ 520 */
539 StringEnumeration* 521 StringEnumeration*
540 Region::getContainedRegions() const { 522 Region::getContainedRegions() const {
541 loadRegionData();
542 UErrorCode status = U_ZERO_ERROR; 523 UErrorCode status = U_ZERO_ERROR;
524 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
543 return new RegionNameEnumeration(containedRegions,status); 525 return new RegionNameEnumeration(containedRegions,status);
544 } 526 }
545 527
546 /** 528 /**
547 * Returns an enumeration over the IDs of all the regions that are children of t his region anywhere in the region 529 * Returns an enumeration over the IDs of all the regions that are children of t his region anywhere in the region
548 * hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any 530 * hierarchy and match the given type. This API may return an empty enumeration if this region doesn't have any
549 * sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type 531 * sub-regions that match the given type. For example, calling this method with region "150" (Europe) and type
550 * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR " (France) - "IT" (Italy) - "DE" (Germany) etc. ) 532 * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR " (France) - "IT" (Italy) - "DE" (Germany) etc. )
551 */ 533 */
552 StringEnumeration* 534 StringEnumeration*
553 Region::getContainedRegions( URegionType type ) const { 535 Region::getContainedRegions( URegionType type ) const {
554 loadRegionData(); 536 UErrorCode status = U_ZERO_ERROR;
537 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
538 if (U_FAILURE(status)) {
539 return NULL;
540 }
555 541
556 UErrorCode status = U_ZERO_ERROR;
557 UVector *result = new UVector(NULL, uhash_compareChars, status); 542 UVector *result = new UVector(NULL, uhash_compareChars, status);
558 543
559 StringEnumeration *cr = getContainedRegions(); 544 StringEnumeration *cr = getContainedRegions();
560 545
561 for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) { 546 for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) {
562 const char *id = cr->next(NULL,status); 547 const char *id = cr->next(NULL,status);
563 const Region *r = Region::getInstance(id,status); 548 const Region *r = Region::getInstance(id,status);
564 if ( r->getType() == type ) { 549 if ( r->getType() == type ) {
565 result->addElement((void *)&r->idStr,status); 550 result->addElement((void *)&r->idStr,status);
566 } else { 551 } else {
(...skipping 10 matching lines...) Expand all
577 StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,stat us); 562 StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,stat us);
578 delete result; 563 delete result;
579 return resultEnumeration; 564 return resultEnumeration;
580 } 565 }
581 566
582 /** 567 /**
583 * Returns true if this region contains the supplied other region anywhere in th e region hierarchy. 568 * Returns true if this region contains the supplied other region anywhere in th e region hierarchy.
584 */ 569 */
585 UBool 570 UBool
586 Region::contains(const Region &other) const { 571 Region::contains(const Region &other) const {
587 loadRegionData(); 572 UErrorCode status = U_ZERO_ERROR;
573 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
588 574
589 if (!containedRegions) { 575 if (!containedRegions) {
590 return FALSE; 576 return FALSE;
591 } 577 }
592 if (containedRegions->contains((void *)&other.idStr)) { 578 if (containedRegions->contains((void *)&other.idStr)) {
593 return TRUE; 579 return TRUE;
594 } else { 580 } else {
595 for ( int32_t i = 0 ; i < containedRegions->size() ; i++ ) { 581 for ( int32_t i = 0 ; i < containedRegions->size() ; i++ ) {
596 UnicodeString *crStr = (UnicodeString *)containedRegions->elementAt( i); 582 UnicodeString *crStr = (UnicodeString *)containedRegions->elementAt( i);
597 Region *cr = (Region *) uhash_get(regionIDMap,(void *)crStr); 583 Region *cr = (Region *) uhash_get(regionIDMap,(void *)crStr);
598 if ( cr && cr->contains(other) ) { 584 if ( cr && cr->contains(other) ) {
599 return TRUE; 585 return TRUE;
600 } 586 }
601 } 587 }
602 } 588 }
603 589
604 return FALSE; 590 return FALSE;
605 } 591 }
606 592
607 /** 593 /**
608 * For deprecated regions, return an enumeration over the IDs of the regions tha t are the preferred replacement 594 * For deprecated regions, return an enumeration over the IDs of the regions tha t are the preferred replacement
609 * regions for this region. Returns NULL for a non-deprecated region. For exam ple, calling this method with region 595 * regions for this region. Returns NULL for a non-deprecated region. For exam ple, calling this method with region
610 * "SU" (Soviet Union) would return a list of the regions containing "RU" (Russi a), "AM" (Armenia), "AZ" (Azerbaijan), etc... 596 * "SU" (Soviet Union) would return a list of the regions containing "RU" (Russi a), "AM" (Armenia), "AZ" (Azerbaijan), etc...
611 */ 597 */
612 StringEnumeration* 598 StringEnumeration*
613 Region::getPreferredValues() const { 599 Region::getPreferredValues() const {
614 loadRegionData();
615 UErrorCode status = U_ZERO_ERROR; 600 UErrorCode status = U_ZERO_ERROR;
601 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status);
616 if ( type == URGN_DEPRECATED ) { 602 if ( type == URGN_DEPRECATED ) {
617 return new RegionNameEnumeration(preferredValues,status); 603 return new RegionNameEnumeration(preferredValues,status);
618 } else { 604 } else {
619 return NULL; 605 return NULL;
620 } 606 }
621 } 607 }
622 608
623 609
624 /** 610 /**
625 * Return this region's canonical region code. 611 * Return this region's canonical region code.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 667
682 RegionNameEnumeration::~RegionNameEnumeration() { 668 RegionNameEnumeration::~RegionNameEnumeration() {
683 delete fRegionNames; 669 delete fRegionNames;
684 } 670 }
685 671
686 U_NAMESPACE_END 672 U_NAMESPACE_END
687 673
688 #endif /* #if !UCONFIG_NO_FORMATTING */ 674 #endif /* #if !UCONFIG_NO_FORMATTING */
689 675
690 //eof 676 //eof
OLDNEW
« no previous file with comments | « source/i18n/regeximp.cpp ('k') | source/i18n/reldatefmt.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698