| 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 |