| OLD | NEW |
| 1 /* | 1 /* |
| 2 ****************************************************************************** | 2 ****************************************************************************** |
| 3 * | 3 * |
| 4 * Copyright (C) 1999-2013, International Business Machines | 4 * Copyright (C) 1999-2014, International Business Machines |
| 5 * Corporation and others. All Rights Reserved. | 5 * Corporation and others. All Rights Reserved. |
| 6 * | 6 * |
| 7 ****************************************************************************** | 7 ****************************************************************************** |
| 8 * file name: udata.cpp | 8 * file name: udata.cpp |
| 9 * encoding: US-ASCII | 9 * encoding: US-ASCII |
| 10 * tab size: 8 (not used) | 10 * tab size: 8 (not used) |
| 11 * indentation:4 | 11 * indentation:4 |
| 12 * | 12 * |
| 13 * created on: 1999oct25 | 13 * created on: 1999oct25 |
| 14 * created by: Markus W. Scherer | 14 * created by: Markus W. Scherer |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 | 64 |
| 65 /* configuration ---------------------------------------------------------- */ | 65 /* configuration ---------------------------------------------------------- */ |
| 66 | 66 |
| 67 /* If you are excruciatingly bored turn this on .. */ | 67 /* If you are excruciatingly bored turn this on .. */ |
| 68 /* #define UDATA_DEBUG 1 */ | 68 /* #define UDATA_DEBUG 1 */ |
| 69 | 69 |
| 70 #if defined(UDATA_DEBUG) | 70 #if defined(UDATA_DEBUG) |
| 71 # include <stdio.h> | 71 # include <stdio.h> |
| 72 #endif | 72 #endif |
| 73 | 73 |
| 74 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) | |
| 75 | |
| 76 U_NAMESPACE_USE | 74 U_NAMESPACE_USE |
| 77 | 75 |
| 78 /* | 76 /* |
| 79 * Forward declarations | 77 * Forward declarations |
| 80 */ | 78 */ |
| 81 static UDataMemory *udata_findCachedData(const char *path); | 79 static UDataMemory *udata_findCachedData(const char *path); |
| 82 | 80 |
| 83 /*********************************************************************** | 81 /*********************************************************************** |
| 84 * | 82 * |
| 85 * static (Global) data | 83 * static (Global) data |
| (...skipping 29 matching lines...) Expand all Loading... |
| 115 udata_cleanup(void) | 113 udata_cleanup(void) |
| 116 { | 114 { |
| 117 int32_t i; | 115 int32_t i; |
| 118 | 116 |
| 119 if (gCommonDataCache) { /* Delete the cache of user data mapping
s. */ | 117 if (gCommonDataCache) { /* Delete the cache of user data mapping
s. */ |
| 120 uhash_close(gCommonDataCache); /* Table owns the contents, and will d
elete them. */ | 118 uhash_close(gCommonDataCache); /* Table owns the contents, and will d
elete them. */ |
| 121 gCommonDataCache = NULL; /* Cleanup is not thread safe.
*/ | 119 gCommonDataCache = NULL; /* Cleanup is not thread safe.
*/ |
| 122 } | 120 } |
| 123 gCommonDataCacheInitOnce.reset(); | 121 gCommonDataCacheInitOnce.reset(); |
| 124 | 122 |
| 125 for (i = 0; i < LENGTHOF(gCommonICUDataArray) && gCommonICUDataArray[i] != N
ULL; ++i) { | 123 for (i = 0; i < UPRV_LENGTHOF(gCommonICUDataArray) && gCommonICUDataArray[i]
!= NULL; ++i) { |
| 126 udata_close(gCommonICUDataArray[i]); | 124 udata_close(gCommonICUDataArray[i]); |
| 127 gCommonICUDataArray[i] = NULL; | 125 gCommonICUDataArray[i] = NULL; |
| 128 } | 126 } |
| 129 gHaveTriedToLoadCommonData = FALSE; | 127 gHaveTriedToLoadCommonData = FALSE; |
| 130 | 128 |
| 131 return TRUE; /* Everything was cleaned up */ | 129 return TRUE; /* Everything was cleaned up */ |
| 132 } | 130 } |
| 133 | 131 |
| 134 static UBool U_CALLCONV | 132 static UBool U_CALLCONV |
| 135 findCommonICUDataByName(const char *inBasename) | 133 findCommonICUDataByName(const char *inBasename) |
| 136 { | 134 { |
| 137 UBool found = FALSE; | 135 UBool found = FALSE; |
| 138 int32_t i; | 136 int32_t i; |
| 139 | 137 |
| 140 UDataMemory *pData = udata_findCachedData(inBasename); | 138 UDataMemory *pData = udata_findCachedData(inBasename); |
| 141 if (pData == NULL) | 139 if (pData == NULL) |
| 142 return FALSE; | 140 return FALSE; |
| 143 | 141 |
| 144 for (i = 0; i < LENGTHOF(gCommonICUDataArray); ++i) { | 142 for (i = 0; i < UPRV_LENGTHOF(gCommonICUDataArray); ++i) { |
| 145 if ((gCommonICUDataArray[i] != NULL) && (gCommonICUDataArray[i]->pHeader
== pData->pHeader)) { | 143 if ((gCommonICUDataArray[i] != NULL) && (gCommonICUDataArray[i]->pHeader
== pData->pHeader)) { |
| 146 /* The data pointer is already in the array. */ | 144 /* The data pointer is already in the array. */ |
| 147 found = TRUE; | 145 found = TRUE; |
| 148 break; | 146 break; |
| 149 } | 147 } |
| 150 } | 148 } |
| 151 | 149 |
| 152 return found; | 150 return found; |
| 153 } | 151 } |
| 154 | 152 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 168 if (U_FAILURE(*pErr)) { | 166 if (U_FAILURE(*pErr)) { |
| 169 return FALSE; | 167 return FALSE; |
| 170 } | 168 } |
| 171 | 169 |
| 172 /* For the assignment, other threads must cleanly see either the old
*/ | 170 /* For the assignment, other threads must cleanly see either the old
*/ |
| 173 /* or the new, not some partially initialized new. The old can not be
*/ | 171 /* or the new, not some partially initialized new. The old can not be
*/ |
| 174 /* deleted - someone may still have a pointer to it lying around in
*/ | 172 /* deleted - someone may still have a pointer to it lying around in
*/ |
| 175 /* their locals.
*/ | 173 /* their locals.
*/ |
| 176 UDatamemory_assign(newCommonData, pData); | 174 UDatamemory_assign(newCommonData, pData); |
| 177 umtx_lock(NULL); | 175 umtx_lock(NULL); |
| 178 for (i = 0; i < LENGTHOF(gCommonICUDataArray); ++i) { | 176 for (i = 0; i < UPRV_LENGTHOF(gCommonICUDataArray); ++i) { |
| 179 if (gCommonICUDataArray[i] == NULL) { | 177 if (gCommonICUDataArray[i] == NULL) { |
| 180 gCommonICUDataArray[i] = newCommonData; | 178 gCommonICUDataArray[i] = newCommonData; |
| 181 ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); | |
| 182 didUpdate = TRUE; | 179 didUpdate = TRUE; |
| 183 break; | 180 break; |
| 184 } else if (gCommonICUDataArray[i]->pHeader == pData->pHeader) { | 181 } else if (gCommonICUDataArray[i]->pHeader == pData->pHeader) { |
| 185 /* The same data pointer is already in the array. */ | 182 /* The same data pointer is already in the array. */ |
| 186 break; | 183 break; |
| 187 } | 184 } |
| 188 } | 185 } |
| 189 umtx_unlock(NULL); | 186 umtx_unlock(NULL); |
| 190 | 187 |
| 191 if (i == LENGTHOF(gCommonICUDataArray) && warn) { | 188 if (i == UPRV_LENGTHOF(gCommonICUDataArray) && warn) { |
| 192 *pErr = U_USING_DEFAULT_WARNING; | 189 *pErr = U_USING_DEFAULT_WARNING; |
| 193 } | 190 } |
| 194 if (!didUpdate) { | 191 if (didUpdate) { |
| 192 ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); |
| 193 } else { |
| 195 uprv_free(newCommonData); | 194 uprv_free(newCommonData); |
| 196 } | 195 } |
| 197 return didUpdate; | 196 return didUpdate; |
| 198 } | 197 } |
| 199 | 198 |
| 200 static UBool | 199 static UBool |
| 201 setCommonICUDataPointer(const void *pData, UBool /*warn*/, UErrorCode *pErrorCod
e) { | 200 setCommonICUDataPointer(const void *pData, UBool /*warn*/, UErrorCode *pErrorCod
e) { |
| 202 UDataMemory tData; | 201 UDataMemory tData; |
| 203 UDataMemory_init(&tData); | 202 UDataMemory_init(&tData); |
| 204 UDataMemory_setData(&tData, pData); | 203 UDataMemory_setData(&tData, pData); |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 /* =============================================================================
=====*/ | 613 /* =============================================================================
=====*/ |
| 615 | 614 |
| 616 | 615 |
| 617 /*----------------------------------------------------------------------* | 616 /*----------------------------------------------------------------------* |
| 618 * * | 617 * * |
| 619 * Add a static reference to the common data library * | 618 * Add a static reference to the common data library * |
| 620 * Unless overridden by an explicit udata_setCommonData, this will be * | 619 * Unless overridden by an explicit udata_setCommonData, this will be * |
| 621 * our common data. * | 620 * our common data. * |
| 622 * * | 621 * * |
| 623 *----------------------------------------------------------------------*/ | 622 *----------------------------------------------------------------------*/ |
| 624 extern "C" const ICU_Data_Header U_DATA_API U_ICUDATA_ENTRY_POINT; | 623 extern "C" const DataHeader U_DATA_API U_ICUDATA_ENTRY_POINT; |
| 625 | 624 |
| 626 /* | 625 /* |
| 627 * This would be a good place for weak-linkage declarations of | 626 * This would be a good place for weak-linkage declarations of |
| 628 * partial-data-library access functions where each returns a pointer | 627 * partial-data-library access functions where each returns a pointer |
| 629 * to its data package, if it is linked in. | 628 * to its data package, if it is linked in. |
| 630 */ | 629 */ |
| 631 /* | 630 /* |
| 632 extern const void *uprv_getICUData_collation(void) ATTRIBUTE_WEAK; | 631 extern const void *uprv_getICUData_collation(void) ATTRIBUTE_WEAK; |
| 633 extern const void *uprv_getICUData_conversion(void) ATTRIBUTE_WEAK; | 632 extern const void *uprv_getICUData_conversion(void) ATTRIBUTE_WEAK; |
| 634 */ | 633 */ |
| (...skipping 19 matching lines...) Expand all Loading... |
| 654 | 653 |
| 655 if (U_FAILURE(*pErrorCode)) { | 654 if (U_FAILURE(*pErrorCode)) { |
| 656 return NULL; | 655 return NULL; |
| 657 } | 656 } |
| 658 | 657 |
| 659 UDataMemory_init(&tData); | 658 UDataMemory_init(&tData); |
| 660 | 659 |
| 661 /* ??????? TODO revisit this */ | 660 /* ??????? TODO revisit this */ |
| 662 if (commonDataIndex >= 0) { | 661 if (commonDataIndex >= 0) { |
| 663 /* "mini-cache" for common ICU data */ | 662 /* "mini-cache" for common ICU data */ |
| 664 if(commonDataIndex >= LENGTHOF(gCommonICUDataArray)) { | 663 if(commonDataIndex >= UPRV_LENGTHOF(gCommonICUDataArray)) { |
| 665 return NULL; | 664 return NULL; |
| 666 } | 665 } |
| 667 if(gCommonICUDataArray[commonDataIndex] == NULL) { | 666 if(gCommonICUDataArray[commonDataIndex] == NULL) { |
| 668 int32_t i; | 667 int32_t i; |
| 669 for(i = 0; i < commonDataIndex; ++i) { | 668 for(i = 0; i < commonDataIndex; ++i) { |
| 670 if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT.hdr
) { | 669 if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT) { |
| 671 /* The linked-in data is already in the list. */ | 670 /* The linked-in data is already in the list. */ |
| 672 return NULL; | 671 return NULL; |
| 673 } | 672 } |
| 674 } | 673 } |
| 675 | 674 |
| 676 /* Add the linked-in data to the list. */ | 675 /* Add the linked-in data to the list. */ |
| 677 /* | 676 /* |
| 678 * This is where we would check and call weakly linked partial-data-
library | 677 * This is where we would check and call weakly linked partial-data-
library |
| 679 * access functions. | 678 * access functions. |
| 680 */ | 679 */ |
| 681 /* | 680 /* |
| 682 if (uprv_getICUData_collation) { | 681 if (uprv_getICUData_collation) { |
| 683 setCommonICUDataPointer(uprv_getICUData_collation(), FALSE, pErr
orCode); | 682 setCommonICUDataPointer(uprv_getICUData_collation(), FALSE, pErr
orCode); |
| 684 } | 683 } |
| 685 if (uprv_getICUData_conversion) { | 684 if (uprv_getICUData_conversion) { |
| 686 setCommonICUDataPointer(uprv_getICUData_conversion(), FALSE, pEr
rorCode); | 685 setCommonICUDataPointer(uprv_getICUData_conversion(), FALSE, pEr
rorCode); |
| 687 } | 686 } |
| 688 */ | 687 */ |
| 689 setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT.hdr, FALSE, pErrorCod
e); | 688 setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT, FALSE, pErrorCode); |
| 690 } | 689 } |
| 691 return gCommonICUDataArray[commonDataIndex]; | 690 return gCommonICUDataArray[commonDataIndex]; |
| 692 } | 691 } |
| 693 | 692 |
| 694 | 693 |
| 695 /* request is NOT for ICU Data. */ | 694 /* request is NOT for ICU Data. */ |
| 696 | 695 |
| 697 /* Find the base name portion of the supplied path. */ | 696 /* Find the base name portion of the supplied path. */ |
| 698 /* inBasename will be left pointing somewhere within the original path str
ing. */ | 697 /* inBasename will be left pointing somewhere within the original path str
ing. */ |
| 699 inBasename = findBasename(path); | 698 inBasename = findBasename(path); |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 } else if ((!checkedExtendedICUData) && extendICUData(subErrorCode)) { | 1058 } else if ((!checkedExtendedICUData) && extendICUData(subErrorCode)) { |
| 1060 checkedExtendedICUData = TRUE; | 1059 checkedExtendedICUData = TRUE; |
| 1061 /* try this data package slot again: it changed from NULL to non-NUL
L */ | 1060 /* try this data package slot again: it changed from NULL to non-NUL
L */ |
| 1062 } else { | 1061 } else { |
| 1063 return NULL; | 1062 return NULL; |
| 1064 } | 1063 } |
| 1065 } | 1064 } |
| 1066 } | 1065 } |
| 1067 | 1066 |
| 1068 /* | 1067 /* |
| 1068 * Identify the Time Zone resources that are subject to special override data lo
ading. |
| 1069 */ |
| 1070 static UBool isTimeZoneFile(const char *name, const char *type) { |
| 1071 return ((uprv_strcmp(type, "res") == 0) && |
| 1072 (uprv_strcmp(name, "zoneinfo64") == 0 || |
| 1073 uprv_strcmp(name, "timezoneTypes") == 0 || |
| 1074 uprv_strcmp(name, "windowsZones") == 0 || |
| 1075 uprv_strcmp(name, "metaZones") == 0)); |
| 1076 } |
| 1077 |
| 1078 /* |
| 1069 * A note on the ownership of Mapped Memory | 1079 * A note on the ownership of Mapped Memory |
| 1070 * | 1080 * |
| 1071 * For common format files, ownership resides with the UDataMemory object | 1081 * For common format files, ownership resides with the UDataMemory object |
| 1072 * that lives in the cache of opened common data. These UDataMemorys are pri
vate | 1082 * that lives in the cache of opened common data. These UDataMemorys are pri
vate |
| 1073 * to the udata implementation, and are never seen directly by users. | 1083 * to the udata implementation, and are never seen directly by users. |
| 1074 * | 1084 * |
| 1075 * The UDataMemory objects returned to users will have the address of some de
sired | 1085 * The UDataMemory objects returned to users will have the address of some de
sired |
| 1076 * data within the mapped region, but they wont have the mapping info itself,
and thus | 1086 * data within the mapped region, but they wont have the mapping info itself,
and thus |
| 1077 * won't cause anything to be removed from memory when they are closed. | 1087 * won't cause anything to be removed from memory when they are closed. |
| 1078 * | 1088 * |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1226 } | 1236 } |
| 1227 | 1237 |
| 1228 /************************ Begin loop looking for ind. files ***************/ | 1238 /************************ Begin loop looking for ind. files ***************/ |
| 1229 #ifdef UDATA_DEBUG | 1239 #ifdef UDATA_DEBUG |
| 1230 fprintf(stderr, "IND: inBasename = %s, pkg=%s\n", "(n/a)", packageNameFromPa
th(path)); | 1240 fprintf(stderr, "IND: inBasename = %s, pkg=%s\n", "(n/a)", packageNameFromPa
th(path)); |
| 1231 #endif | 1241 #endif |
| 1232 | 1242 |
| 1233 /* End of dealing with a null basename */ | 1243 /* End of dealing with a null basename */ |
| 1234 dataPath = u_getDataDirectory(); | 1244 dataPath = u_getDataDirectory(); |
| 1235 | 1245 |
| 1246 /**** Time zone individual files override */ |
| 1247 if (isTimeZoneFile(name, type) && isICUData) { |
| 1248 const char *tzFilesDir = u_getTimeZoneFilesDirectory(pErrorCode); |
| 1249 if (tzFilesDir[0] != 0) { |
| 1250 #ifdef UDATA_DEBUG |
| 1251 fprintf(stderr, "Trying Time Zone Files directory = %s\n", tzFilesDi
r); |
| 1252 #endif |
| 1253 retVal = doLoadFromIndividualFiles(/* pkgName.data() */ "", tzFilesD
ir, tocEntryPathSuffix, |
| 1254 /* path */ "", type, name, isAcceptable, context, &s
ubErrorCode, pErrorCode); |
| 1255 if((retVal != NULL) || U_FAILURE(*pErrorCode)) { |
| 1256 return retVal; |
| 1257 } |
| 1258 } |
| 1259 } |
| 1260 |
| 1236 /**** COMMON PACKAGE - only if packages are first. */ | 1261 /**** COMMON PACKAGE - only if packages are first. */ |
| 1237 if(gDataFileAccess == UDATA_PACKAGES_FIRST) { | 1262 if(gDataFileAccess == UDATA_PACKAGES_FIRST) { |
| 1238 #ifdef UDATA_DEBUG | 1263 #ifdef UDATA_DEBUG |
| 1239 fprintf(stderr, "Trying packages (UDATA_PACKAGES_FIRST)\n"); | 1264 fprintf(stderr, "Trying packages (UDATA_PACKAGES_FIRST)\n"); |
| 1240 #endif | 1265 #endif |
| 1241 /* #2 */ | 1266 /* #2 */ |
| 1242 retVal = doLoadFromCommonData(isICUData, | 1267 retVal = doLoadFromCommonData(isICUData, |
| 1243 pkgName.data(), dataPath, tocEntryPathSuffix, tocEnt
ryName.data(), | 1268 pkgName.data(), dataPath, tocEntryPathSuffix, tocEnt
ryName.data(), |
| 1244 path, type, name, isAcceptable, context, &subErrorCo
de, pErrorCode); | 1269 path, type, name, isAcceptable, context, &subErrorCo
de, pErrorCode); |
| 1245 if((retVal != NULL) || U_FAILURE(*pErrorCode)) { | 1270 if((retVal != NULL) || U_FAILURE(*pErrorCode)) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 pInfo->size=0; | 1393 pInfo->size=0; |
| 1369 } | 1394 } |
| 1370 } | 1395 } |
| 1371 } | 1396 } |
| 1372 | 1397 |
| 1373 | 1398 |
| 1374 U_CAPI void U_EXPORT2 udata_setFileAccess(UDataFileAccess access, UErrorCode * /
*status*/) | 1399 U_CAPI void U_EXPORT2 udata_setFileAccess(UDataFileAccess access, UErrorCode * /
*status*/) |
| 1375 { | 1400 { |
| 1376 gDataFileAccess = access; | 1401 gDataFileAccess = access; |
| 1377 } | 1402 } |
| OLD | NEW |