OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 2014, International Business Machines Corporation and | 3 * Copyright (C) 2014-2015, 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 ******************************************************************************** |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 return TRUE; | 52 return TRUE; |
53 } | 53 } |
54 | 54 |
55 U_CDECL_END | 55 U_CDECL_END |
56 | 56 |
57 U_NAMESPACE_BEGIN | 57 U_NAMESPACE_BEGIN |
58 | 58 |
59 static UInitOnce gRegionDataInitOnce = U_INITONCE_INITIALIZER; | 59 static UInitOnce gRegionDataInitOnce = U_INITONCE_INITIALIZER; |
60 static UVector* availableRegions[URGN_LIMIT]; | 60 static UVector* availableRegions[URGN_LIMIT]; |
61 | 61 |
62 static UHashtable *regionAliases; | 62 static UHashtable *regionAliases = NULL; |
63 static UHashtable *regionIDMap; | 63 static UHashtable *regionIDMap = NULL; |
64 static UHashtable *numericCodeMap; | 64 static UHashtable *numericCodeMap = NULL; |
| 65 static UVector *allRegions = NULL; |
65 | 66 |
66 static const UChar UNKNOWN_REGION_ID [] = { 0x5A, 0x5A, 0 }; /* "ZZ" */ | 67 static const UChar UNKNOWN_REGION_ID [] = { 0x5A, 0x5A, 0 }; /* "ZZ" */ |
67 static const UChar OUTLYING_OCEANIA_REGION_ID [] = { 0x51, 0x4F, 0 }; /* "QO" *
/ | 68 static const UChar OUTLYING_OCEANIA_REGION_ID [] = { 0x51, 0x4F, 0 }; /* "QO" *
/ |
68 static const UChar WORLD_ID [] = { 0x30, 0x30, 0x31, 0 }; /* "001" */ | 69 static const UChar WORLD_ID [] = { 0x30, 0x30, 0x31, 0 }; /* "001" */ |
| 70 static const UChar RANGE_MARKER [] = { 0x7e, 0 }; /* "~" */ |
| 71 static const UnicodeString RANGE_MARKER_STRING(RANGE_MARKER); |
69 | 72 |
70 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration) | 73 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(RegionNameEnumeration) |
71 | 74 |
72 /* | 75 /* |
73 * Initializes the region data from the ICU resource bundles. The region data | 76 * 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 | 77 * 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. | 78 * codes are, any known aliases, and the territory containment data. |
76 * | 79 * |
77 * If the region data has already loaded, then this method simply returns withou
t doing | 80 * If the region data has already loaded, then this method simply returns withou
t doing |
78 * anything meaningful. | 81 * anything meaningful. |
79 */ | 82 */ |
80 void Region::loadRegionData(UErrorCode &status) { | 83 void Region::loadRegionData(UErrorCode &status) { |
81 LocalPointer<DecimalFormat> df(new DecimalFormat(status)); | 84 |
| 85 // Construct service objs first |
| 86 LocalUHashtablePointer newRegionIDMap(uhash_open(uhash_hashUnicodeString, uh
ash_compareUnicodeString, NULL, &status)); |
| 87 LocalUHashtablePointer newNumericCodeMap(uhash_open(uhash_hashLong,uhash_com
pareLong,NULL,&status)); |
| 88 LocalUHashtablePointer newRegionAliases(uhash_open(uhash_hashUnicodeString,u
hash_compareUnicodeString,NULL,&status)); |
| 89 LocalPointer<DecimalFormat> df(new DecimalFormat(status), status); |
| 90 |
| 91 LocalPointer<UVector> continents(new UVector(uprv_deleteUObject, uhash_compa
reUnicodeString, status), status); |
| 92 LocalPointer<UVector> groupings(new UVector(uprv_deleteUObject, uhash_compar
eUnicodeString, status), status); |
| 93 allRegions = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, sta
tus); |
| 94 |
| 95 LocalUResourceBundlePointer metadata(ures_openDirect(NULL,"metadata",&status
)); |
| 96 LocalUResourceBundlePointer metadataAlias(ures_getByKey(metadata.getAlias(),
"alias",NULL,&status)); |
| 97 LocalUResourceBundlePointer territoryAlias(ures_getByKey(metadataAlias.getAl
ias(),"territory",NULL,&status)); |
| 98 |
| 99 LocalUResourceBundlePointer supplementalData(ures_openDirect(NULL,"supplemen
talData",&status)); |
| 100 LocalUResourceBundlePointer codeMappings(ures_getByKey(supplementalData.getA
lias(),"codeMappings",NULL,&status)); |
| 101 |
| 102 LocalUResourceBundlePointer idValidity(ures_getByKey(supplementalData.getAli
as(),"idValidity",NULL,&status)); |
| 103 LocalUResourceBundlePointer regionList(ures_getByKey(idValidity.getAlias(),"
region",NULL,&status)); |
| 104 LocalUResourceBundlePointer regionRegular(ures_getByKey(regionList.getAlias(
),"regular",NULL,&status)); |
| 105 LocalUResourceBundlePointer regionMacro(ures_getByKey(regionList.getAlias(),
"macroregion",NULL,&status)); |
| 106 LocalUResourceBundlePointer regionUnknown(ures_getByKey(regionList.getAlias(
),"unknown",NULL,&status)); |
| 107 |
| 108 LocalUResourceBundlePointer territoryContainment(ures_getByKey(supplementalD
ata.getAlias(),"territoryContainment",NULL,&status)); |
| 109 LocalUResourceBundlePointer worldContainment(ures_getByKey(territoryContainm
ent.getAlias(),"001",NULL,&status)); |
| 110 LocalUResourceBundlePointer groupingContainment(ures_getByKey(territoryConta
inment.getAlias(),"grouping",NULL,&status)); |
| 111 |
82 if (U_FAILURE(status)) { | 112 if (U_FAILURE(status)) { |
83 return; | 113 return; |
84 } | 114 } |
85 if (df == NULL) { | 115 |
86 status = U_MEMORY_ALLOCATION_ERROR; | 116 // now, initialize |
87 return; | 117 df->setParseIntegerOnly(TRUE); |
| 118 uhash_setValueDeleter(newRegionIDMap.getAlias(), deleteRegion); // regionID
Map owns objs |
| 119 uhash_setKeyDeleter(newRegionAliases.getAlias(), uprv_deleteUObject); // reg
ionAliases owns the string keys |
| 120 |
| 121 |
| 122 while ( ures_hasNext(regionRegular.getAlias()) ) { |
| 123 UnicodeString regionName = ures_getNextUnicodeString(regionRegular.getAl
ias(),NULL,&status); |
| 124 int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER_STRING); |
| 125 UChar buf[6]; |
| 126 regionName.extract(buf,6,status); |
| 127 if ( rangeMarkerLocation > 0 ) { |
| 128 UChar endRange = regionName.charAt(rangeMarkerLocation+1); |
| 129 buf[rangeMarkerLocation] = 0; |
| 130 while ( buf[rangeMarkerLocation-1] <= endRange ) { |
| 131 LocalPointer<UnicodeString> newRegion(new UnicodeString(buf), st
atus); |
| 132 allRegions->addElement(newRegion.orphan(),status); |
| 133 buf[rangeMarkerLocation-1]++; |
| 134 } |
| 135 } else { |
| 136 LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName),
status); |
| 137 allRegions->addElement(newRegion.orphan(),status); |
| 138 } |
88 } | 139 } |
89 df->setParseIntegerOnly(TRUE); | |
90 | 140 |
91 regionIDMap = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString
, NULL, &status); | 141 while ( ures_hasNext(regionMacro.getAlias()) ) { |
92 if (U_FAILURE(status)) { | 142 UnicodeString regionName = ures_getNextUnicodeString(regionMacro.getAlia
s(),NULL,&status); |
93 return; | 143 int32_t rangeMarkerLocation = regionName.indexOf(RANGE_MARKER_STRING); |
| 144 UChar buf[6]; |
| 145 regionName.extract(buf,6,status); |
| 146 if ( rangeMarkerLocation > 0 ) { |
| 147 UChar endRange = regionName.charAt(rangeMarkerLocation+1); |
| 148 buf[rangeMarkerLocation] = 0; |
| 149 while ( buf[rangeMarkerLocation-1] <= endRange ) { |
| 150 LocalPointer<UnicodeString> newRegion(new UnicodeString(buf), st
atus); |
| 151 allRegions->addElement(newRegion.orphan(),status); |
| 152 buf[rangeMarkerLocation-1]++; |
| 153 } |
| 154 } else { |
| 155 LocalPointer<UnicodeString> newRegion(new UnicodeString(regionName),
status); |
| 156 allRegions->addElement(newRegion.orphan(),status); |
| 157 } |
94 } | 158 } |
95 if (regionIDMap == NULL) { | 159 |
96 status = U_MEMORY_ALLOCATION_ERROR; | 160 while ( ures_hasNext(regionUnknown.getAlias()) ) { |
97 return; | 161 LocalPointer<UnicodeString> regionName (new UnicodeString(ures_getNextUn
icodeString(regionUnknown.getAlias(),NULL,&status),status)); |
| 162 allRegions->addElement(regionName.orphan(),status); |
98 } | 163 } |
99 uhash_setValueDeleter(regionIDMap, deleteRegion); | |
100 | |
101 numericCodeMap = uhash_open(uhash_hashLong,uhash_compareLong,NULL,&status); | |
102 | |
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 } | |
111 uhash_setKeyDeleter(regionAliases,uprv_deleteUObject); | |
112 | |
113 LocalUResourceBundlePointer rb(ures_openDirect(NULL,"metadata",&status)); | |
114 LocalUResourceBundlePointer regionCodes(ures_getByKey(rb.getAlias(),"regionC
odes",NULL,&status)); | |
115 LocalUResourceBundlePointer territoryAlias(ures_getByKey(rb.getAlias(),"terr
itoryAlias",NULL,&status)); | |
116 | |
117 LocalUResourceBundlePointer rb2(ures_openDirect(NULL,"supplementalData",&sta
tus)); | |
118 LocalUResourceBundlePointer codeMappings(ures_getByKey(rb2.getAlias(),"codeM
appings",NULL,&status)); | |
119 | |
120 LocalUResourceBundlePointer territoryContainment(ures_getByKey(rb2.getAlias(
),"territoryContainment",NULL,&status)); | |
121 LocalUResourceBundlePointer worldContainment(ures_getByKey(territoryContainm
ent.getAlias(),"001",NULL,&status)); | |
122 LocalUResourceBundlePointer groupingContainment(ures_getByKey(territoryConta
inment.getAlias(),"grouping",NULL,&status)); | |
123 | |
124 UVector *continents = new UVector(uprv_deleteUObject, uhash_compareUnicodeSt
ring, status); | |
125 | 164 |
126 while ( ures_hasNext(worldContainment.getAlias()) ) { | 165 while ( ures_hasNext(worldContainment.getAlias()) ) { |
127 UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeStri
ng(worldContainment.getAlias(),NULL,&status)); | 166 UnicodeString *continentName = new UnicodeString(ures_getNextUnicodeStri
ng(worldContainment.getAlias(),NULL,&status)); |
128 continents->addElement(continentName,status); | 167 continents->addElement(continentName,status); |
129 } | 168 } |
130 | 169 |
131 UVector *groupings = new UVector(uprv_deleteUObject, uhash_compareUnicodeStr
ing, status); | |
132 while ( ures_hasNext(groupingContainment.getAlias()) ) { | 170 while ( ures_hasNext(groupingContainment.getAlias()) ) { |
133 UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeStrin
g(groupingContainment.getAlias(),NULL,&status)); | 171 UnicodeString *groupingName = new UnicodeString(ures_getNextUnicodeStrin
g(groupingContainment.getAlias(),NULL,&status)); |
134 groupings->addElement(groupingName,status); | 172 groupings->addElement(groupingName,status); |
135 } | 173 } |
136 | 174 |
137 while ( ures_hasNext(regionCodes.getAlias()) ) { | 175 for ( int32_t i = 0 ; i < allRegions->size() ; i++ ) { |
138 UnicodeString regionID = ures_getNextUnicodeString(regionCodes.getAlias(
), NULL, &status); | 176 LocalPointer<Region> r(new Region(), status); |
139 Region *r = new Region(); | 177 if ( U_FAILURE(status) ) { |
140 r->idStr = regionID; | 178 return; |
| 179 } |
| 180 UnicodeString *regionName = (UnicodeString *)allRegions->elementAt(i); |
| 181 r->idStr = *regionName; |
| 182 |
141 r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV); | 183 r->idStr.extract(0,r->idStr.length(),r->id,sizeof(r->id),US_INV); |
142 r->type = URGN_TERRITORY; // Only temporary - figure out the real type l
ater once the aliases are known. | 184 r->type = URGN_TERRITORY; // Only temporary - figure out the real type l
ater once the aliases are known. |
143 | 185 |
144 uhash_put(regionIDMap,(void *)&(r->idStr),(void *)r,&status); | |
145 Formattable result; | 186 Formattable result; |
146 UErrorCode ps = U_ZERO_ERROR; | 187 UErrorCode ps = U_ZERO_ERROR; |
147 df->parse(r->idStr,result,ps); | 188 df->parse(r->idStr,result,ps); |
148 if ( U_SUCCESS(ps) ) { | 189 if ( U_SUCCESS(ps) ) { |
149 r->code = result.getLong(); // Convert string to number | 190 r->code = result.getLong(); // Convert string to number |
150 uhash_iput(numericCodeMap,r->code,(void *)r,&status); | 191 uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)(r.getAlias(
)),&status); |
151 r->type = URGN_SUBCONTINENT; | 192 r->type = URGN_SUBCONTINENT; |
152 } else { | 193 } else { |
153 r->code = -1; | 194 r->code = -1; |
154 } | 195 } |
| 196 void* idStrAlias = (void*)&(r->idStr); // about to orphan 'r'. Save this
off. |
| 197 uhash_put(newRegionIDMap.getAlias(),idStrAlias,(void *)(r.orphan()),&sta
tus); // regionIDMap takes ownership |
155 } | 198 } |
156 | 199 |
157 | |
158 // Process the territory aliases | 200 // Process the territory aliases |
159 while ( ures_hasNext(territoryAlias.getAlias()) ) { | 201 while ( ures_hasNext(territoryAlias.getAlias()) ) { |
160 UResourceBundle *res = ures_getNextResource(territoryAlias.getAlias(),NU
LL,&status); | 202 LocalUResourceBundlePointer res(ures_getNextResource(territoryAlias.getA
lias(),NULL,&status)); |
161 const char *aliasFrom = ures_getKey(res); | 203 const char *aliasFrom = ures_getKey(res.getAlias()); |
162 UnicodeString* aliasFromStr = new UnicodeString(aliasFrom, -1, US_INV); | 204 LocalPointer<UnicodeString> aliasFromStr(new UnicodeString(aliasFrom, -1
, US_INV), status); |
163 UnicodeString aliasTo = ures_getUnicodeString(res,&status); | 205 UnicodeString aliasTo = ures_getUnicodeStringByKey(res.getAlias(),"repla
cement",&status); |
164 ures_close(res); | 206 res.adoptInstead(NULL); |
165 | 207 |
166 Region *aliasToRegion = (Region *) uhash_get(regionIDMap,&aliasTo); | 208 const Region *aliasToRegion = (Region *) uhash_get(newRegionIDMap.getAli
as(),&aliasTo); |
167 Region *aliasFromRegion = (Region *)uhash_get(regionIDMap,aliasFromStr); | 209 Region *aliasFromRegion = (Region *)uhash_get(newRegionIDMap.getAlias(),
aliasFromStr.getAlias()); |
168 | 210 |
169 if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is jus
t an alias from some string to a region | 211 if ( aliasToRegion != NULL && aliasFromRegion == NULL ) { // This is jus
t an alias from some string to a region |
170 uhash_put(regionAliases,(void *)aliasFromStr, (void *)aliasToRegion,
&status); | 212 uhash_put(newRegionAliases.getAlias(),(void *)aliasFromStr.orphan(),
(void *)aliasToRegion,&status); |
171 } else { | 213 } else { |
172 if ( aliasFromRegion == NULL ) { // Deprecated region code not in th
e master codes list - so need to create a deprecated region for it. | 214 if ( aliasFromRegion == NULL ) { // Deprecated region code not in th
e master codes list - so need to create a deprecated region for it. |
173 aliasFromRegion = new Region(); | 215 LocalPointer<Region> newRgn(new Region, status); |
| 216 if ( U_SUCCESS(status) ) { |
| 217 aliasFromRegion = newRgn.orphan(); |
| 218 } else { |
| 219 return; // error out |
| 220 } |
174 aliasFromRegion->idStr.setTo(*aliasFromStr); | 221 aliasFromRegion->idStr.setTo(*aliasFromStr); |
175 aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length()
,aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV); | 222 aliasFromRegion->idStr.extract(0,aliasFromRegion->idStr.length()
,aliasFromRegion->id,sizeof(aliasFromRegion->id),US_INV); |
176 uhash_put(regionIDMap,(void *)&(aliasFromRegion->idStr),(void *)
aliasFromRegion,&status); | 223 uhash_put(newRegionIDMap.getAlias(),(void *)&(aliasFromRegion->i
dStr),(void *)aliasFromRegion,&status); |
177 Formattable result; | 224 Formattable result; |
178 UErrorCode ps = U_ZERO_ERROR; | 225 UErrorCode ps = U_ZERO_ERROR; |
179 df->parse(aliasFromRegion->idStr,result,ps); | 226 df->parse(aliasFromRegion->idStr,result,ps); |
180 if ( U_SUCCESS(ps) ) { | 227 if ( U_SUCCESS(ps) ) { |
181 aliasFromRegion->code = result.getLong(); // Convert string
to number | 228 aliasFromRegion->code = result.getLong(); // Convert string
to number |
182 uhash_iput(numericCodeMap,aliasFromRegion->code,(void *)alia
sFromRegion,&status); | 229 uhash_iput(newNumericCodeMap.getAlias(),aliasFromRegion->cod
e,(void *)aliasFromRegion,&status); |
183 } else { | 230 } else { |
184 aliasFromRegion->code = -1; | 231 aliasFromRegion->code = -1; |
185 } | 232 } |
186 aliasFromRegion->type = URGN_DEPRECATED; | 233 aliasFromRegion->type = URGN_DEPRECATED; |
187 } else { | 234 } else { |
188 aliasFromRegion->type = URGN_DEPRECATED; | 235 aliasFromRegion->type = URGN_DEPRECATED; |
189 } | 236 } |
190 delete aliasFromStr; | |
191 | 237 |
192 aliasFromRegion->preferredValues = new UVector(uprv_deleteUObject, u
hash_compareUnicodeString, status); | 238 { |
| 239 LocalPointer<UVector> newPreferredValues(new UVector(uprv_delete
UObject, uhash_compareUnicodeString, status), status); |
| 240 aliasFromRegion->preferredValues = newPreferredValues.orphan(); |
| 241 } |
| 242 if( U_FAILURE(status)) { |
| 243 return; |
| 244 } |
193 UnicodeString currentRegion; | 245 UnicodeString currentRegion; |
194 currentRegion.remove(); | 246 //currentRegion.remove(); TODO: was already 0 length? |
195 for (int32_t i = 0 ; i < aliasTo.length() ; i++ ) { | 247 for (int32_t i = 0 ; i < aliasTo.length() ; i++ ) { |
196 if ( aliasTo.charAt(i) != 0x0020 ) { | 248 if ( aliasTo.charAt(i) != 0x0020 ) { |
197 currentRegion.append(aliasTo.charAt(i)); | 249 currentRegion.append(aliasTo.charAt(i)); |
198 } | 250 } |
199 if ( aliasTo.charAt(i) == 0x0020 || i+1 == aliasTo.length() ) { | 251 if ( aliasTo.charAt(i) == 0x0020 || i+1 == aliasTo.length() ) { |
200 Region *target = (Region *)uhash_get(regionIDMap,(void *)&cu
rrentRegion); | 252 Region *target = (Region *)uhash_get(newRegionIDMap.getAlias
(),(void *)¤tRegion); |
201 if (target) { | 253 if (target) { |
202 UnicodeString *preferredValue = new UnicodeString(target
->idStr); | 254 LocalPointer<UnicodeString> preferredValue(new UnicodeSt
ring(target->idStr), status); |
203 aliasFromRegion->preferredValues->addElement((void *)pre
ferredValue,status); | 255 aliasFromRegion->preferredValues->addElement((void *)pre
ferredValue.orphan(),status); // may add null if err |
204 } | 256 } |
205 currentRegion.remove(); | 257 currentRegion.remove(); |
206 } | 258 } |
207 } | 259 } |
208 } | 260 } |
209 } | 261 } |
210 | 262 |
211 // Process the code mappings - This will allow us to assign numeric codes to
most of the territories. | 263 // Process the code mappings - This will allow us to assign numeric codes to
most of the territories. |
212 while ( ures_hasNext(codeMappings.getAlias()) ) { | 264 while ( ures_hasNext(codeMappings.getAlias()) ) { |
213 UResourceBundle *mapping = ures_getNextResource(codeMappings.getAlias(),
NULL,&status); | 265 UResourceBundle *mapping = ures_getNextResource(codeMappings.getAlias(),
NULL,&status); |
214 if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3)
{ | 266 if ( ures_getType(mapping) == URES_ARRAY && ures_getSize(mapping) == 3)
{ |
215 UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0
,&status); | 267 UnicodeString codeMappingID = ures_getUnicodeStringByIndex(mapping,0
,&status); |
216 UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mappi
ng,1,&status); | 268 UnicodeString codeMappingNumber = ures_getUnicodeStringByIndex(mappi
ng,1,&status); |
217 UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapp
ing,2,&status); | 269 UnicodeString codeMapping3Letter = ures_getUnicodeStringByIndex(mapp
ing,2,&status); |
218 | 270 |
219 Region *r = (Region *)uhash_get(regionIDMap,(void *)&codeMappingID); | 271 Region *r = (Region *)uhash_get(newRegionIDMap.getAlias(),(void *)&c
odeMappingID); |
220 if ( r ) { | 272 if ( r ) { |
221 Formattable result; | 273 Formattable result; |
222 UErrorCode ps = U_ZERO_ERROR; | 274 UErrorCode ps = U_ZERO_ERROR; |
223 df->parse(codeMappingNumber,result,ps); | 275 df->parse(codeMappingNumber,result,ps); |
224 if ( U_SUCCESS(ps) ) { | 276 if ( U_SUCCESS(ps) ) { |
225 r->code = result.getLong(); // Convert string to number | 277 r->code = result.getLong(); // Convert string to number |
226 uhash_iput(numericCodeMap,r->code,(void *)r,&status); | 278 uhash_iput(newNumericCodeMap.getAlias(),r->code,(void *)r,&s
tatus); |
227 } | 279 } |
228 UnicodeString *code3 = new UnicodeString(codeMapping3Letter); | 280 LocalPointer<UnicodeString> code3(new UnicodeString(codeMapping3
Letter), status); |
229 uhash_put(regionAliases,(void *)code3, (void *)r,&status); | 281 uhash_put(newRegionAliases.getAlias(),(void *)code3.orphan(), (v
oid *)r,&status); |
230 } | 282 } |
231 } | 283 } |
232 ures_close(mapping); | 284 ures_close(mapping); |
233 } | 285 } |
234 | 286 |
235 // Now fill in the special cases for WORLD, UNKNOWN, CONTINENTS, and GROUPIN
GS | 287 // Now fill in the special cases for WORLD, UNKNOWN, CONTINENTS, and GROUPIN
GS |
236 Region *r; | 288 Region *r; |
237 » UnicodeString WORLD_ID_STRING(WORLD_ID); | 289 UnicodeString WORLD_ID_STRING(WORLD_ID); |
238 r = (Region *) uhash_get(regionIDMap,(void *)&WORLD_ID_STRING); | 290 r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&WORLD_ID_STRING)
; |
239 if ( r ) { | 291 if ( r ) { |
240 r->type = URGN_WORLD; | 292 r->type = URGN_WORLD; |
241 } | 293 } |
242 | 294 |
243 » UnicodeString UNKNOWN_REGION_ID_STRING(UNKNOWN_REGION_ID); | 295 UnicodeString UNKNOWN_REGION_ID_STRING(UNKNOWN_REGION_ID); |
244 r = (Region *) uhash_get(regionIDMap,(void *)&UNKNOWN_REGION_ID_STRING); | 296 r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&UNKNOWN_REGION_I
D_STRING); |
245 if ( r ) { | 297 if ( r ) { |
246 r->type = URGN_UNKNOWN; | 298 r->type = URGN_UNKNOWN; |
247 } | 299 } |
248 | 300 |
249 for ( int32_t i = 0 ; i < continents->size() ; i++ ) { | 301 for ( int32_t i = 0 ; i < continents->size() ; i++ ) { |
250 r = (Region *) uhash_get(regionIDMap,(void *)continents->elementAt(i)); | 302 r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)continents->e
lementAt(i)); |
251 if ( r ) { | 303 if ( r ) { |
252 r->type = URGN_CONTINENT; | 304 r->type = URGN_CONTINENT; |
253 } | 305 } |
254 } | 306 } |
255 delete continents; | |
256 | 307 |
257 for ( int32_t i = 0 ; i < groupings->size() ; i++ ) { | 308 for ( int32_t i = 0 ; i < groupings->size() ; i++ ) { |
258 r = (Region *) uhash_get(regionIDMap,(void *)groupings->elementAt(i)); | 309 r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)groupings->el
ementAt(i)); |
259 if ( r ) { | 310 if ( r ) { |
260 r->type = URGN_GROUPING; | 311 r->type = URGN_GROUPING; |
261 } | 312 } |
262 } | 313 } |
263 delete groupings; | |
264 | 314 |
265 // Special case: The region code "QO" (Outlying Oceania) is a subcontinent c
ode added by CLDR | 315 // Special case: The region code "QO" (Outlying Oceania) is a subcontinent c
ode added by CLDR |
266 // even though it looks like a territory code. Need to handle it here. | 316 // even though it looks like a territory code. Need to handle it here. |
267 | 317 |
268 » UnicodeString OUTLYING_OCEANIA_REGION_ID_STRING(OUTLYING_OCEANIA_REGION_
ID); | 318 UnicodeString OUTLYING_OCEANIA_REGION_ID_STRING(OUTLYING_OCEANIA_REGION_ID); |
269 r = (Region *) uhash_get(regionIDMap,(void *)&OUTLYING_OCEANIA_REGION_ID_STR
ING); | 319 r = (Region *) uhash_get(newRegionIDMap.getAlias(),(void *)&OUTLYING_OCEANIA
_REGION_ID_STRING); |
270 if ( r ) { | 320 if ( r ) { |
271 r->type = URGN_SUBCONTINENT; | 321 r->type = URGN_SUBCONTINENT; |
272 } | 322 } |
273 | 323 |
274 // Load territory containment info from the supplemental data. | 324 // Load territory containment info from the supplemental data. |
275 while ( ures_hasNext(territoryContainment.getAlias()) ) { | 325 while ( ures_hasNext(territoryContainment.getAlias()) ) { |
276 UResourceBundle *mapping = ures_getNextResource(territoryContainment.get
Alias(),NULL,&status); | 326 LocalUResourceBundlePointer mapping(ures_getNextResource(territoryContai
nment.getAlias(),NULL,&status)); |
277 const char *parent = ures_getKey(mapping); | 327 if( U_FAILURE(status) ) { |
| 328 return; // error out |
| 329 } |
| 330 const char *parent = ures_getKey(mapping.getAlias()); |
278 if (uprv_strcmp(parent, "containedGroupings") == 0 || uprv_strcmp(parent
, "deprecated") == 0) { | 331 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. | 332 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. | 333 // #11232 is to do something useful with these. |
282 } | 334 } |
283 UnicodeString parentStr = UnicodeString(parent, -1 , US_INV); | 335 UnicodeString parentStr = UnicodeString(parent, -1 , US_INV); |
284 Region *parentRegion = (Region *) uhash_get(regionIDMap,(void *)&parentS
tr); | 336 Region *parentRegion = (Region *) uhash_get(newRegionIDMap.getAlias(),(v
oid *)&parentStr); |
285 | 337 |
286 for ( int j = 0 ; j < ures_getSize(mapping); j++ ) { | 338 for ( int j = 0 ; j < ures_getSize(mapping.getAlias()); j++ ) { |
287 UnicodeString child = ures_getUnicodeStringByIndex(mapping,j,&status
); | 339 UnicodeString child = ures_getUnicodeStringByIndex(mapping.getAlias(
),j,&status); |
288 Region *childRegion = (Region *) uhash_get(regionIDMap,(void *)&chil
d); | 340 Region *childRegion = (Region *) uhash_get(newRegionIDMap.getAlias()
,(void *)&child); |
289 if ( parentRegion != NULL && childRegion != NULL ) { | 341 if ( parentRegion != NULL && childRegion != NULL ) { |
290 | 342 |
291 // Add the child region to the set of regions contained by the p
arent | 343 // Add the child region to the set of regions contained by the p
arent |
292 if (parentRegion->containedRegions == NULL) { | 344 if (parentRegion->containedRegions == NULL) { |
293 parentRegion->containedRegions = new UVector(uprv_deleteUObj
ect, uhash_compareUnicodeString, status); | 345 parentRegion->containedRegions = new UVector(uprv_deleteUObj
ect, uhash_compareUnicodeString, status); |
294 } | 346 } |
295 | 347 |
296 UnicodeString *childStr = new UnicodeString(); | 348 LocalPointer<UnicodeString> childStr(new UnicodeString(), status
); |
| 349 if( U_FAILURE(status) ) { |
| 350 return; // error out |
| 351 } |
297 childStr->fastCopyFrom(childRegion->idStr); | 352 childStr->fastCopyFrom(childRegion->idStr); |
298 parentRegion->containedRegions->addElement((void *)childStr,stat
us); | 353 parentRegion->containedRegions->addElement((void *)childStr.orph
an(),status); |
299 | 354 |
300 // Set the parent region to be the containing region of the chil
d. | 355 // Set the parent region to be the containing region of the chil
d. |
301 // Regions of type GROUPING can't be set as the parent, since an
other region | 356 // Regions of type GROUPING can't be set as the parent, since an
other region |
302 // such as a SUBCONTINENT, CONTINENT, or WORLD must always be th
e parent. | 357 // such as a SUBCONTINENT, CONTINENT, or WORLD must always be th
e parent. |
303 if ( parentRegion->type != URGN_GROUPING) { | 358 if ( parentRegion->type != URGN_GROUPING) { |
304 childRegion->containingRegion = parentRegion; | 359 childRegion->containingRegion = parentRegion; |
305 } | 360 } |
306 } | 361 } |
307 } | 362 } |
308 ures_close(mapping); | |
309 } | 363 } |
310 | 364 |
311 // Create the availableRegions lists | 365 // Create the availableRegions lists |
312 int32_t pos = -1; | 366 int32_t pos = UHASH_FIRST; |
313 while ( const UHashElement* element = uhash_nextElement(regionIDMap,&pos)) { | 367 while ( const UHashElement* element = uhash_nextElement(newRegionIDMap.getAl
ias(),&pos)) { |
314 Region *ar = (Region *)element->value.pointer; | 368 Region *ar = (Region *)element->value.pointer; |
315 if ( availableRegions[ar->type] == NULL ) { | 369 if ( availableRegions[ar->type] == NULL ) { |
316 availableRegions[ar->type] = new UVector(uprv_deleteUObject, uhash_c
ompareUnicodeString, status); | 370 LocalPointer<UVector> newAr(new UVector(uprv_deleteUObject, uhash_co
mpareUnicodeString, status), status); |
| 371 availableRegions[ar->type] = newAr.orphan(); |
317 } | 372 } |
318 UnicodeString *arString = new UnicodeString(ar->idStr); | 373 LocalPointer<UnicodeString> arString(new UnicodeString(ar->idStr), statu
s); |
319 availableRegions[ar->type]->addElement((void *)arString,status); | 374 if( U_FAILURE(status) ) { |
| 375 return; // error out |
| 376 } |
| 377 availableRegions[ar->type]->addElement((void *)arString.orphan(),status)
; |
320 } | 378 } |
321 | 379 |
322 ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup); | 380 ucln_i18n_registerCleanup(UCLN_I18N_REGION, region_cleanup); |
| 381 // copy hashtables |
| 382 numericCodeMap = newNumericCodeMap.orphan(); |
| 383 regionIDMap = newRegionIDMap.orphan(); |
| 384 regionAliases = newRegionAliases.orphan(); |
323 } | 385 } |
324 | 386 |
325 void Region::cleanupRegionData() { | 387 void Region::cleanupRegionData() { |
326 for (int32_t i = 0 ; i < URGN_LIMIT ; i++ ) { | 388 for (int32_t i = 0 ; i < URGN_LIMIT ; i++ ) { |
327 if ( availableRegions[i] ) { | 389 if ( availableRegions[i] ) { |
328 delete availableRegions[i]; | 390 delete availableRegions[i]; |
329 } | 391 } |
330 } | 392 } |
331 | 393 |
332 if (regionAliases) { | 394 if (regionAliases) { |
333 uhash_close(regionAliases); | 395 uhash_close(regionAliases); |
334 } | 396 } |
335 | 397 |
336 if (numericCodeMap) { | 398 if (numericCodeMap) { |
337 uhash_close(numericCodeMap); | 399 uhash_close(numericCodeMap); |
338 } | 400 } |
339 | 401 |
340 if (regionIDMap) { | 402 if (regionIDMap) { |
341 uhash_close(regionIDMap); | 403 uhash_close(regionIDMap); |
342 } | 404 } |
| 405 if (allRegions) { |
| 406 allRegions->removeAllElements(); // Don't need the temporary list anymor
e. |
| 407 delete allRegions; |
| 408 allRegions = NULL; |
| 409 } |
| 410 |
| 411 regionAliases = numericCodeMap = regionIDMap = NULL; |
| 412 |
343 gRegionDataInitOnce.reset(); | 413 gRegionDataInitOnce.reset(); |
344 } | 414 } |
345 | 415 |
346 Region::Region () | 416 Region::Region () |
347 : code(-1), | 417 : code(-1), |
348 type(URGN_UNKNOWN), | 418 type(URGN_UNKNOWN), |
349 containingRegion(NULL), | 419 containingRegion(NULL), |
350 containedRegions(NULL), | 420 containedRegions(NULL), |
351 preferredValues(NULL) { | 421 preferredValues(NULL) { |
352 id[0] = 0; | 422 id[0] = 0; |
353 } | 423 } |
354 | 424 |
355 Region::~Region () { | 425 Region::~Region () { |
356 if (containedRegions) { | 426 if (containedRegions) { |
357 delete containedRegions; | 427 delete containedRegions; |
358 } | 428 } |
359 if (preferredValues) { | 429 if (preferredValues) { |
360 delete preferredValues; | 430 delete preferredValues; |
361 } | 431 } |
362 } | 432 } |
363 | 433 |
364 /** | 434 /** |
365 * Returns true if the two regions are equal. | 435 * Returns true if the two regions are equal. |
| 436 * Per PMC, just use pointer compare, since we have at most one instance of each
Region. |
366 */ | 437 */ |
367 UBool | 438 UBool |
368 Region::operator==(const Region &that) const { | 439 Region::operator==(const Region &that) const { |
369 return (idStr == that.idStr); | 440 return (idStr == that.idStr); |
370 } | 441 } |
371 | 442 |
372 /** | 443 /** |
373 * Returns true if the two regions are NOT equal; that is, if operator ==() retu
rns false. | 444 * Returns true if the two regions are NOT equal; that is, if operator ==() retu
rns false. |
| 445 * Per PMC, just use pointer compare, since we have at most one instance of each
Region. |
374 */ | 446 */ |
375 UBool | 447 UBool |
376 Region::operator!=(const Region &that) const { | 448 Region::operator!=(const Region &that) const { |
377 return (idStr != that.idStr); | 449 return (idStr != that.idStr); |
378 } | 450 } |
379 | 451 |
380 /** | 452 /** |
381 * Returns a pointer to a Region using the given region code. The region code c
an be either 2-letter ISO code, | 453 * Returns a pointer to a Region using the given region code. The region code c
an be either 2-letter ISO code, |
382 * 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code a
s defined by the LDML specification. | 454 * 3-letter ISO code, UNM.49 numeric code, or other valid Unicode Region Code a
s defined by the LDML specification. |
383 * The identifier will be canonicalized internally using the supplemental metada
ta as defined in the CLDR. | 455 * The identifier will be canonicalized internally using the supplemental metada
ta as defined in the CLDR. |
(...skipping 18 matching lines...) Expand all Loading... |
402 if ( !r ) { | 474 if ( !r ) { |
403 r = (Region *)uhash_get(regionAliases,(void *)®ionCodeString); | 475 r = (Region *)uhash_get(regionAliases,(void *)®ionCodeString); |
404 } | 476 } |
405 | 477 |
406 if ( !r ) { // Unknown region code | 478 if ( !r ) { // Unknown region code |
407 status = U_ILLEGAL_ARGUMENT_ERROR; | 479 status = U_ILLEGAL_ARGUMENT_ERROR; |
408 return NULL; | 480 return NULL; |
409 } | 481 } |
410 | 482 |
411 if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) { | 483 if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) { |
412 StringEnumeration *pv = r->getPreferredValues(); | 484 StringEnumeration *pv = r->getPreferredValues(status); |
413 pv->reset(status); | 485 pv->reset(status); |
414 const UnicodeString *ustr = pv->snext(status); | 486 const UnicodeString *ustr = pv->snext(status); |
415 r = (Region *)uhash_get(regionIDMap,(void *)ustr); | 487 r = (Region *)uhash_get(regionIDMap,(void *)ustr); |
416 delete pv; | 488 delete pv; |
417 } | 489 } |
418 | 490 |
419 return r; | 491 return r; |
420 | 492 |
421 } | 493 } |
422 | 494 |
423 /** | 495 /** |
424 * Returns a pointer to a Region using the given numeric region code. If the num
eric region code is not recognized, | 496 * Returns a pointer to a Region using the given numeric region code. If the num
eric region code is not recognized, |
425 * the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ). | 497 * the appropriate error code will be set ( U_ILLEGAL_ARGUMENT_ERROR ). |
426 */ | 498 */ |
427 const Region* U_EXPORT2 | 499 const Region* U_EXPORT2 |
428 Region::getInstance (int32_t code, UErrorCode &status) { | 500 Region::getInstance (int32_t code, UErrorCode &status) { |
429 | 501 |
430 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); | 502 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); |
431 if (U_FAILURE(status)) { | 503 if (U_FAILURE(status)) { |
432 return NULL; | 504 return NULL; |
433 } | 505 } |
434 | 506 |
435 Region *r = (Region *)uhash_iget(numericCodeMap,code); | 507 Region *r = (Region *)uhash_iget(numericCodeMap,code); |
436 | 508 |
437 if ( !r ) { // Just in case there's an alias that's numeric, try to find it. | 509 if ( !r ) { // Just in case there's an alias that's numeric, try to find it. |
438 UErrorCode fs = U_ZERO_ERROR; | 510 UnicodeString pat = UNICODE_STRING_SIMPLE("0"); |
439 UnicodeString pat = UNICODE_STRING_SIMPLE("00#"); | 511 LocalPointer<DecimalFormat> df(new DecimalFormat(pat,status), status); |
440 DecimalFormat *df = new DecimalFormat(pat,fs); | 512 if( U_FAILURE(status) ) { |
441 | 513 return NULL; |
| 514 } |
442 UnicodeString id; | 515 UnicodeString id; |
443 id.remove(); | 516 id.remove(); |
444 df->format(code,id); | 517 FieldPosition posIter; |
445 delete df; | 518 df->format(code,id, posIter, status); |
446 r = (Region *)uhash_get(regionAliases,&id); | 519 r = (Region *)uhash_get(regionAliases,&id); |
447 } | 520 } |
448 | 521 |
| 522 if( U_FAILURE(status) ) { |
| 523 return NULL; |
| 524 } |
| 525 |
449 if ( !r ) { | 526 if ( !r ) { |
450 status = U_ILLEGAL_ARGUMENT_ERROR; | 527 status = U_ILLEGAL_ARGUMENT_ERROR; |
451 return NULL; | 528 return NULL; |
452 } | 529 } |
453 | 530 |
454 if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) { | 531 if ( r->type == URGN_DEPRECATED && r->preferredValues->size() == 1) { |
455 StringEnumeration *pv = r->getPreferredValues(); | 532 StringEnumeration *pv = r->getPreferredValues(status); |
456 pv->reset(status); | 533 pv->reset(status); |
457 const UnicodeString *ustr = pv->snext(status); | 534 const UnicodeString *ustr = pv->snext(status); |
458 r = (Region *)uhash_get(regionIDMap,(void *)ustr); | 535 r = (Region *)uhash_get(regionIDMap,(void *)ustr); |
459 delete pv; | 536 delete pv; |
460 } | 537 } |
461 | 538 |
462 return r; | 539 return r; |
463 } | 540 } |
464 | 541 |
465 | 542 |
466 /** | 543 /** |
467 * Returns an enumeration over the IDs of all known regions that match the given
type. | 544 * Returns an enumeration over the IDs of all known regions that match the given
type. |
468 */ | 545 */ |
469 StringEnumeration* U_EXPORT2 | 546 StringEnumeration* U_EXPORT2 |
470 Region::getAvailable(URegionType type) { | 547 Region::getAvailable(URegionType type, UErrorCode &status) { |
471 UErrorCode status = U_ZERO_ERROR; | 548 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); // returns imme
diately if U_FAILURE(status) |
472 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); | |
473 if (U_FAILURE(status)) { | 549 if (U_FAILURE(status)) { |
474 return NULL; | 550 return NULL; |
475 } | 551 } |
476 return new RegionNameEnumeration(availableRegions[type],status); | 552 return new RegionNameEnumeration(availableRegions[type],status); |
477 } | 553 } |
478 | 554 |
479 /** | 555 /** |
480 * Returns a pointer to the region that contains this region. Returns NULL if t
his region is code "001" (World) | 556 * Returns a pointer to the region that contains this region. Returns NULL if t
his region is code "001" (World) |
481 * or "ZZ" (Unknown region). For example, calling this method with region "IT" (
Italy) returns the | 557 * or "ZZ" (Unknown region). For example, calling this method with region "IT" (
Italy) returns the |
482 * region "039" (Southern Europe). | 558 * region "039" (Southern Europe). |
(...skipping 13 matching lines...) Expand all Loading... |
496 * with region "IT" (Italy) for type "URGN_CONTINENT" returns the region "150" (
Europe ). | 572 * with region "IT" (Italy) for type "URGN_CONTINENT" returns the region "150" (
Europe ). |
497 */ | 573 */ |
498 const Region* | 574 const Region* |
499 Region::getContainingRegion(URegionType type) const { | 575 Region::getContainingRegion(URegionType type) const { |
500 UErrorCode status = U_ZERO_ERROR; | 576 UErrorCode status = U_ZERO_ERROR; |
501 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); | 577 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); |
502 if ( containingRegion == NULL ) { | 578 if ( containingRegion == NULL ) { |
503 return NULL; | 579 return NULL; |
504 } | 580 } |
505 | 581 |
506 if ( containingRegion->type == type ) { | 582 return ( containingRegion->type == type )? containingRegion: containingRegio
n->getContainingRegion(type); |
507 return containingRegion; | |
508 } else { | |
509 return containingRegion->getContainingRegion(type); | |
510 } | |
511 } | 583 } |
512 | 584 |
513 /** | 585 /** |
514 * Return an enumeration over the IDs of all the regions that are immediate chil
dren of this region in the | 586 * Return an enumeration over the IDs of all the regions that are immediate chil
dren of this region in the |
515 * region hierarchy. These returned regions could be either macro regions, terri
tories, or a mixture of the two, | 587 * region hierarchy. These returned regions could be either macro regions, terri
tories, or a mixture of the two, |
516 * depending on the containment data as defined in CLDR. This API may return NU
LL if this region doesn't have | 588 * depending on the containment data as defined in CLDR. This API may return NU
LL if this region doesn't have |
517 * any sub-regions. For example, calling this method with region "150" (Europe)
returns an enumeration containing | 589 * any sub-regions. For example, calling this method with region "150" (Europe)
returns an enumeration containing |
518 * the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern
Europe) - "154" (Northern Europe) | 590 * the various sub regions of Europe - "039" (Southern Europe) - "151" (Eastern
Europe) - "154" (Northern Europe) |
519 * and "155" (Western Europe). | 591 * and "155" (Western Europe). |
520 */ | 592 */ |
521 StringEnumeration* | 593 StringEnumeration* |
522 Region::getContainedRegions() const { | 594 Region::getContainedRegions(UErrorCode &status) const { |
523 UErrorCode status = U_ZERO_ERROR; | 595 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); // returns imme
diately if U_FAILURE(status) |
524 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); | 596 if (U_FAILURE(status)) { |
| 597 return NULL; |
| 598 } |
525 return new RegionNameEnumeration(containedRegions,status); | 599 return new RegionNameEnumeration(containedRegions,status); |
526 } | 600 } |
527 | 601 |
528 /** | 602 /** |
529 * Returns an enumeration over the IDs of all the regions that are children of t
his region anywhere in the region | 603 * Returns an enumeration over the IDs of all the regions that are children of t
his region anywhere in the region |
530 * hierarchy and match the given type. This API may return an empty enumeration
if this region doesn't have any | 604 * hierarchy and match the given type. This API may return an empty enumeration
if this region doesn't have any |
531 * sub-regions that match the given type. For example, calling this method with
region "150" (Europe) and type | 605 * sub-regions that match the given type. For example, calling this method with
region "150" (Europe) and type |
532 * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR
" (France) - "IT" (Italy) - "DE" (Germany) etc. ) | 606 * "URGN_TERRITORY" returns a set containing all the territories in Europe ( "FR
" (France) - "IT" (Italy) - "DE" (Germany) etc. ) |
533 */ | 607 */ |
534 StringEnumeration* | 608 StringEnumeration* |
535 Region::getContainedRegions( URegionType type ) const { | 609 Region::getContainedRegions( URegionType type, UErrorCode &status ) const { |
536 UErrorCode status = U_ZERO_ERROR; | 610 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); // returns imme
diately if U_FAILURE(status) |
537 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); | |
538 if (U_FAILURE(status)) { | 611 if (U_FAILURE(status)) { |
539 return NULL; | 612 return NULL; |
540 } | 613 } |
541 | 614 |
542 UVector *result = new UVector(NULL, uhash_compareChars, status); | 615 UVector *result = new UVector(NULL, uhash_compareChars, status); |
543 | 616 |
544 StringEnumeration *cr = getContainedRegions(); | 617 StringEnumeration *cr = getContainedRegions(status); |
545 | 618 |
546 for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) { | 619 for ( int32_t i = 0 ; i < cr->count(status) ; i++ ) { |
547 const char *id = cr->next(NULL,status); | 620 const char *id = cr->next(NULL,status); |
548 const Region *r = Region::getInstance(id,status); | 621 const Region *r = Region::getInstance(id,status); |
549 if ( r->getType() == type ) { | 622 if ( r->getType() == type ) { |
550 result->addElement((void *)&r->idStr,status); | 623 result->addElement((void *)&r->idStr,status); |
551 } else { | 624 } else { |
552 StringEnumeration *children = r->getContainedRegions(type); | 625 StringEnumeration *children = r->getContainedRegions(type, status); |
553 for ( int32_t j = 0 ; j < children->count(status) ; j++ ) { | 626 for ( int32_t j = 0 ; j < children->count(status) ; j++ ) { |
554 const char *id2 = children->next(NULL,status); | 627 const char *id2 = children->next(NULL,status); |
555 const Region *r2 = Region::getInstance(id2,status); | 628 const Region *r2 = Region::getInstance(id2,status); |
556 result->addElement((void *)&r2->idStr,status); | 629 result->addElement((void *)&r2->idStr,status); |
557 } | 630 } |
558 delete children; | 631 delete children; |
559 } | 632 } |
560 } | 633 } |
561 delete cr; | 634 delete cr; |
562 StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,stat
us); | 635 StringEnumeration* resultEnumeration = new RegionNameEnumeration(result,stat
us); |
(...skipping 26 matching lines...) Expand all Loading... |
589 | 662 |
590 return FALSE; | 663 return FALSE; |
591 } | 664 } |
592 | 665 |
593 /** | 666 /** |
594 * For deprecated regions, return an enumeration over the IDs of the regions tha
t are the preferred replacement | 667 * For deprecated regions, return an enumeration over the IDs of the regions tha
t are the preferred replacement |
595 * regions for this region. Returns NULL for a non-deprecated region. For exam
ple, calling this method with region | 668 * regions for this region. Returns NULL for a non-deprecated region. For exam
ple, calling this method with region |
596 * "SU" (Soviet Union) would return a list of the regions containing "RU" (Russi
a), "AM" (Armenia), "AZ" (Azerbaijan), etc... | 669 * "SU" (Soviet Union) would return a list of the regions containing "RU" (Russi
a), "AM" (Armenia), "AZ" (Azerbaijan), etc... |
597 */ | 670 */ |
598 StringEnumeration* | 671 StringEnumeration* |
599 Region::getPreferredValues() const { | 672 Region::getPreferredValues(UErrorCode &status) const { |
600 UErrorCode status = U_ZERO_ERROR; | 673 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); // returns imme
diately if U_FAILURE(status) |
601 umtx_initOnce(gRegionDataInitOnce, &loadRegionData, status); | 674 if (U_FAILURE(status) || type != URGN_DEPRECATED) { |
602 if ( type == URGN_DEPRECATED ) { | |
603 return new RegionNameEnumeration(preferredValues,status); | |
604 } else { | |
605 return NULL; | 675 return NULL; |
606 } | 676 } |
| 677 return new RegionNameEnumeration(preferredValues,status); |
607 } | 678 } |
608 | 679 |
609 | 680 |
610 /** | 681 /** |
611 * Return this region's canonical region code. | 682 * Return this region's canonical region code. |
612 */ | 683 */ |
613 const char* | 684 const char* |
614 Region::getRegionCode() const { | 685 Region::getRegionCode() const { |
615 return id; | 686 return id; |
616 } | 687 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 | 738 |
668 RegionNameEnumeration::~RegionNameEnumeration() { | 739 RegionNameEnumeration::~RegionNameEnumeration() { |
669 delete fRegionNames; | 740 delete fRegionNames; |
670 } | 741 } |
671 | 742 |
672 U_NAMESPACE_END | 743 U_NAMESPACE_END |
673 | 744 |
674 #endif /* #if !UCONFIG_NO_FORMATTING */ | 745 #endif /* #if !UCONFIG_NO_FORMATTING */ |
675 | 746 |
676 //eof | 747 //eof |
OLD | NEW |