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 |