127f654740f2a26ad62a5c155af9199af9e69b889claireho/* 227f654740f2a26ad62a5c155af9199af9e69b889claireho****************************************************************************** 327f654740f2a26ad62a5c155af9199af9e69b889claireho* 459d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1999-2013, International Business Machines 527f654740f2a26ad62a5c155af9199af9e69b889claireho* Corporation and others. All Rights Reserved. 627f654740f2a26ad62a5c155af9199af9e69b889claireho* 727f654740f2a26ad62a5c155af9199af9e69b889claireho****************************************************************************** 827f654740f2a26ad62a5c155af9199af9e69b889claireho* file name: udata.cpp 927f654740f2a26ad62a5c155af9199af9e69b889claireho* encoding: US-ASCII 1027f654740f2a26ad62a5c155af9199af9e69b889claireho* tab size: 8 (not used) 1127f654740f2a26ad62a5c155af9199af9e69b889claireho* indentation:4 1227f654740f2a26ad62a5c155af9199af9e69b889claireho* 1327f654740f2a26ad62a5c155af9199af9e69b889claireho* created on: 1999oct25 1427f654740f2a26ad62a5c155af9199af9e69b889claireho* created by: Markus W. Scherer 1527f654740f2a26ad62a5c155af9199af9e69b889claireho*/ 1627f654740f2a26ad62a5c155af9199af9e69b889claireho 17103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/utypes.h" /* U_PLATFORM etc. */ 1827f654740f2a26ad62a5c155af9199af9e69b889claireho 19103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#ifdef __GNUC__ 2027f654740f2a26ad62a5c155af9199af9e69b889claireho/* if gcc 2127f654740f2a26ad62a5c155af9199af9e69b889claireho#define ATTRIBUTE_WEAK __attribute__ ((weak)) 2227f654740f2a26ad62a5c155af9199af9e69b889clairehomight have to #include some other header 2327f654740f2a26ad62a5c155af9199af9e69b889claireho*/ 2427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 2527f654740f2a26ad62a5c155af9199af9e69b889claireho 2627f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/putil.h" 2727f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/udata.h" 2827f654740f2a26ad62a5c155af9199af9e69b889claireho#include "unicode/uversion.h" 2927f654740f2a26ad62a5c155af9199af9e69b889claireho#include "charstr.h" 3027f654740f2a26ad62a5c155af9199af9e69b889claireho#include "cmemory.h" 3127f654740f2a26ad62a5c155af9199af9e69b889claireho#include "cstring.h" 3227f654740f2a26ad62a5c155af9199af9e69b889claireho#include "putilimp.h" 3359d709d503bab6e2b61931737e662dd293b40578ccornelius#include "uassert.h" 3427f654740f2a26ad62a5c155af9199af9e69b889claireho#include "ucln_cmn.h" 3527f654740f2a26ad62a5c155af9199af9e69b889claireho#include "ucmndata.h" 3627f654740f2a26ad62a5c155af9199af9e69b889claireho#include "udatamem.h" 3727f654740f2a26ad62a5c155af9199af9e69b889claireho#include "uhash.h" 3827f654740f2a26ad62a5c155af9199af9e69b889claireho#include "umapfile.h" 3927f654740f2a26ad62a5c155af9199af9e69b889claireho#include "umutex.h" 4027f654740f2a26ad62a5c155af9199af9e69b889claireho 4127f654740f2a26ad62a5c155af9199af9e69b889claireho/*********************************************************************** 4227f654740f2a26ad62a5c155af9199af9e69b889claireho* 4327f654740f2a26ad62a5c155af9199af9e69b889claireho* Notes on the organization of the ICU data implementation 4427f654740f2a26ad62a5c155af9199af9e69b889claireho* 4527f654740f2a26ad62a5c155af9199af9e69b889claireho* All of the public API is defined in udata.h 4627f654740f2a26ad62a5c155af9199af9e69b889claireho* 4727f654740f2a26ad62a5c155af9199af9e69b889claireho* The implementation is split into several files... 4827f654740f2a26ad62a5c155af9199af9e69b889claireho* 4927f654740f2a26ad62a5c155af9199af9e69b889claireho* - udata.c (this file) contains higher level code that knows about 5027f654740f2a26ad62a5c155af9199af9e69b889claireho* the search paths for locating data, caching opened data, etc. 5127f654740f2a26ad62a5c155af9199af9e69b889claireho* 5227f654740f2a26ad62a5c155af9199af9e69b889claireho* - umapfile.c contains the low level platform-specific code for actually loading 5327f654740f2a26ad62a5c155af9199af9e69b889claireho* (memory mapping, file reading, whatever) data into memory. 5427f654740f2a26ad62a5c155af9199af9e69b889claireho* 5527f654740f2a26ad62a5c155af9199af9e69b889claireho* - ucmndata.c deals with the tables of contents of ICU data items within 5627f654740f2a26ad62a5c155af9199af9e69b889claireho* an ICU common format data file. The implementation includes 5727f654740f2a26ad62a5c155af9199af9e69b889claireho* an abstract interface and support for multiple TOC formats. 5827f654740f2a26ad62a5c155af9199af9e69b889claireho* All knowledge of any specific TOC format is encapsulated here. 5927f654740f2a26ad62a5c155af9199af9e69b889claireho* 6027f654740f2a26ad62a5c155af9199af9e69b889claireho* - udatamem.c has code for managing UDataMemory structs. These are little 6127f654740f2a26ad62a5c155af9199af9e69b889claireho* descriptor objects for blocks of memory holding ICU data of 6227f654740f2a26ad62a5c155af9199af9e69b889claireho* various types. 6327f654740f2a26ad62a5c155af9199af9e69b889claireho*/ 6427f654740f2a26ad62a5c155af9199af9e69b889claireho 6527f654740f2a26ad62a5c155af9199af9e69b889claireho/* configuration ---------------------------------------------------------- */ 6627f654740f2a26ad62a5c155af9199af9e69b889claireho 6727f654740f2a26ad62a5c155af9199af9e69b889claireho/* If you are excruciatingly bored turn this on .. */ 6827f654740f2a26ad62a5c155af9199af9e69b889claireho/* #define UDATA_DEBUG 1 */ 6927f654740f2a26ad62a5c155af9199af9e69b889claireho 7027f654740f2a26ad62a5c155af9199af9e69b889claireho#if defined(UDATA_DEBUG) 7127f654740f2a26ad62a5c155af9199af9e69b889claireho# include <stdio.h> 7227f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 7327f654740f2a26ad62a5c155af9199af9e69b889claireho 7427f654740f2a26ad62a5c155af9199af9e69b889claireho#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 7527f654740f2a26ad62a5c155af9199af9e69b889claireho 7627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_NAMESPACE_USE 7727f654740f2a26ad62a5c155af9199af9e69b889claireho 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Forward declarations 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UDataMemory *udata_findCachedData(const char *path); 82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 8327f654740f2a26ad62a5c155af9199af9e69b889claireho/*********************************************************************** 8427f654740f2a26ad62a5c155af9199af9e69b889claireho* 8527f654740f2a26ad62a5c155af9199af9e69b889claireho* static (Global) data 8627f654740f2a26ad62a5c155af9199af9e69b889claireho* 8727f654740f2a26ad62a5c155af9199af9e69b889claireho************************************************************************/ 8827f654740f2a26ad62a5c155af9199af9e69b889claireho 8927f654740f2a26ad62a5c155af9199af9e69b889claireho/* 9027f654740f2a26ad62a5c155af9199af9e69b889claireho * Pointers to the common ICU data. 9127f654740f2a26ad62a5c155af9199af9e69b889claireho * 9227f654740f2a26ad62a5c155af9199af9e69b889claireho * We store multiple pointers to ICU data packages and iterate through them 9327f654740f2a26ad62a5c155af9199af9e69b889claireho * when looking for a data item. 9427f654740f2a26ad62a5c155af9199af9e69b889claireho * 9527f654740f2a26ad62a5c155af9199af9e69b889claireho * It is possible to combine this with dependency inversion: 9627f654740f2a26ad62a5c155af9199af9e69b889claireho * One or more data package libraries may export 9727f654740f2a26ad62a5c155af9199af9e69b889claireho * functions that each return a pointer to their piece of the ICU data, 9827f654740f2a26ad62a5c155af9199af9e69b889claireho * and this file would import them as weak functions, without a 9927f654740f2a26ad62a5c155af9199af9e69b889claireho * strong linker dependency from the common library on the data library. 10027f654740f2a26ad62a5c155af9199af9e69b889claireho * 10127f654740f2a26ad62a5c155af9199af9e69b889claireho * Then we can have applications depend on only that part of ICU's data 10227f654740f2a26ad62a5c155af9199af9e69b889claireho * that they really need, reducing the size of binaries that take advantage 10327f654740f2a26ad62a5c155af9199af9e69b889claireho * of this. 10427f654740f2a26ad62a5c155af9199af9e69b889claireho */ 10527f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory *gCommonICUDataArray[10] = { NULL }; 10627f654740f2a26ad62a5c155af9199af9e69b889claireho 10727f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool gHaveTriedToLoadCommonData = FALSE; /* See extendICUData(). */ 10827f654740f2a26ad62a5c155af9199af9e69b889claireho 10927f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UHashtable *gCommonDataCache = NULL; /* Global hash table of opened ICU data files. */ 11059d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER; 11127f654740f2a26ad62a5c155af9199af9e69b889claireho 11227f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataFileAccess gDataFileAccess = UDATA_DEFAULT_ACCESS; 11327f654740f2a26ad62a5c155af9199af9e69b889claireho 11427f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool U_CALLCONV 11527f654740f2a26ad62a5c155af9199af9e69b889clairehoudata_cleanup(void) 11627f654740f2a26ad62a5c155af9199af9e69b889claireho{ 11727f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t i; 11827f654740f2a26ad62a5c155af9199af9e69b889claireho 11927f654740f2a26ad62a5c155af9199af9e69b889claireho if (gCommonDataCache) { /* Delete the cache of user data mappings. */ 12027f654740f2a26ad62a5c155af9199af9e69b889claireho uhash_close(gCommonDataCache); /* Table owns the contents, and will delete them. */ 12127f654740f2a26ad62a5c155af9199af9e69b889claireho gCommonDataCache = NULL; /* Cleanup is not thread safe. */ 12227f654740f2a26ad62a5c155af9199af9e69b889claireho } 12359d709d503bab6e2b61931737e662dd293b40578ccornelius gCommonDataCacheInitOnce.reset(); 12427f654740f2a26ad62a5c155af9199af9e69b889claireho 12527f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < LENGTHOF(gCommonICUDataArray) && gCommonICUDataArray[i] != NULL; ++i) { 12627f654740f2a26ad62a5c155af9199af9e69b889claireho udata_close(gCommonICUDataArray[i]); 12727f654740f2a26ad62a5c155af9199af9e69b889claireho gCommonICUDataArray[i] = NULL; 12827f654740f2a26ad62a5c155af9199af9e69b889claireho } 12927f654740f2a26ad62a5c155af9199af9e69b889claireho gHaveTriedToLoadCommonData = FALSE; 13027f654740f2a26ad62a5c155af9199af9e69b889claireho 13127f654740f2a26ad62a5c155af9199af9e69b889claireho return TRUE; /* Everything was cleaned up */ 13227f654740f2a26ad62a5c155af9199af9e69b889claireho} 13327f654740f2a26ad62a5c155af9199af9e69b889claireho 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehofindCommonICUDataByName(const char *inBasename) 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho{ 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool found = FALSE; 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t i; 139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UDataMemory *pData = udata_findCachedData(inBasename); 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (pData == NULL) 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (i = 0; i < LENGTHOF(gCommonICUDataArray); ++i) { 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((gCommonICUDataArray[i] != NULL) && (gCommonICUDataArray[i]->pHeader == pData->pHeader)) { 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho /* The data pointer is already in the array. */ 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho found = TRUE; 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 15127f654740f2a26ad62a5c155af9199af9e69b889claireho 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return found; 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 15427f654740f2a26ad62a5c155af9199af9e69b889claireho 15527f654740f2a26ad62a5c155af9199af9e69b889claireho 15627f654740f2a26ad62a5c155af9199af9e69b889claireho/* 15727f654740f2a26ad62a5c155af9199af9e69b889claireho * setCommonICUData. Set a UDataMemory to be the global ICU Data 15827f654740f2a26ad62a5c155af9199af9e69b889claireho */ 15927f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool 16027f654740f2a26ad62a5c155af9199af9e69b889clairehosetCommonICUData(UDataMemory *pData, /* The new common data. Belongs to caller, we copy it. */ 16127f654740f2a26ad62a5c155af9199af9e69b889claireho UBool warn, /* If true, set USING_DEFAULT warning if ICUData was */ 16227f654740f2a26ad62a5c155af9199af9e69b889claireho /* changed by another thread before we got to it. */ 16327f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErr) 16427f654740f2a26ad62a5c155af9199af9e69b889claireho{ 16527f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *newCommonData = UDataMemory_createNewInstance(pErr); 16627f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t i; 16727f654740f2a26ad62a5c155af9199af9e69b889claireho UBool didUpdate = FALSE; 16827f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErr)) { 16927f654740f2a26ad62a5c155af9199af9e69b889claireho return FALSE; 17027f654740f2a26ad62a5c155af9199af9e69b889claireho } 17127f654740f2a26ad62a5c155af9199af9e69b889claireho 17227f654740f2a26ad62a5c155af9199af9e69b889claireho /* For the assignment, other threads must cleanly see either the old */ 17327f654740f2a26ad62a5c155af9199af9e69b889claireho /* or the new, not some partially initialized new. The old can not be */ 17427f654740f2a26ad62a5c155af9199af9e69b889claireho /* deleted - someone may still have a pointer to it lying around in */ 17527f654740f2a26ad62a5c155af9199af9e69b889claireho /* their locals. */ 17627f654740f2a26ad62a5c155af9199af9e69b889claireho UDatamemory_assign(newCommonData, pData); 17727f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_lock(NULL); 17827f654740f2a26ad62a5c155af9199af9e69b889claireho for (i = 0; i < LENGTHOF(gCommonICUDataArray); ++i) { 17927f654740f2a26ad62a5c155af9199af9e69b889claireho if (gCommonICUDataArray[i] == NULL) { 18027f654740f2a26ad62a5c155af9199af9e69b889claireho gCommonICUDataArray[i] = newCommonData; 18127f654740f2a26ad62a5c155af9199af9e69b889claireho ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); 18227f654740f2a26ad62a5c155af9199af9e69b889claireho didUpdate = TRUE; 18327f654740f2a26ad62a5c155af9199af9e69b889claireho break; 18427f654740f2a26ad62a5c155af9199af9e69b889claireho } else if (gCommonICUDataArray[i]->pHeader == pData->pHeader) { 18527f654740f2a26ad62a5c155af9199af9e69b889claireho /* The same data pointer is already in the array. */ 18627f654740f2a26ad62a5c155af9199af9e69b889claireho break; 18727f654740f2a26ad62a5c155af9199af9e69b889claireho } 18827f654740f2a26ad62a5c155af9199af9e69b889claireho } 18927f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_unlock(NULL); 19027f654740f2a26ad62a5c155af9199af9e69b889claireho 19127f654740f2a26ad62a5c155af9199af9e69b889claireho if (i == LENGTHOF(gCommonICUDataArray) && warn) { 19227f654740f2a26ad62a5c155af9199af9e69b889claireho *pErr = U_USING_DEFAULT_WARNING; 19327f654740f2a26ad62a5c155af9199af9e69b889claireho } 19427f654740f2a26ad62a5c155af9199af9e69b889claireho if (!didUpdate) { 19527f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newCommonData); 19627f654740f2a26ad62a5c155af9199af9e69b889claireho } 19727f654740f2a26ad62a5c155af9199af9e69b889claireho return didUpdate; 19827f654740f2a26ad62a5c155af9199af9e69b889claireho} 19927f654740f2a26ad62a5c155af9199af9e69b889claireho 20027f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool 20127f654740f2a26ad62a5c155af9199af9e69b889clairehosetCommonICUDataPointer(const void *pData, UBool /*warn*/, UErrorCode *pErrorCode) { 20227f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory tData; 20327f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_init(&tData); 20459d709d503bab6e2b61931737e662dd293b40578ccornelius UDataMemory_setData(&tData, pData); 20527f654740f2a26ad62a5c155af9199af9e69b889claireho udata_checkCommonData(&tData, pErrorCode); 20627f654740f2a26ad62a5c155af9199af9e69b889claireho return setCommonICUData(&tData, FALSE, pErrorCode); 20727f654740f2a26ad62a5c155af9199af9e69b889claireho} 20827f654740f2a26ad62a5c155af9199af9e69b889claireho 20927f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char * 21027f654740f2a26ad62a5c155af9199af9e69b889clairehofindBasename(const char *path) { 21127f654740f2a26ad62a5c155af9199af9e69b889claireho const char *basename=uprv_strrchr(path, U_FILE_SEP_CHAR); 21227f654740f2a26ad62a5c155af9199af9e69b889claireho if(basename==NULL) { 21327f654740f2a26ad62a5c155af9199af9e69b889claireho return path; 21427f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 21527f654740f2a26ad62a5c155af9199af9e69b889claireho return basename+1; 21627f654740f2a26ad62a5c155af9199af9e69b889claireho } 21727f654740f2a26ad62a5c155af9199af9e69b889claireho} 21827f654740f2a26ad62a5c155af9199af9e69b889claireho 21927f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 22027f654740f2a26ad62a5c155af9199af9e69b889clairehostatic const char * 22127f654740f2a26ad62a5c155af9199af9e69b889clairehopackageNameFromPath(const char *path) 22227f654740f2a26ad62a5c155af9199af9e69b889claireho{ 22327f654740f2a26ad62a5c155af9199af9e69b889claireho if((path == NULL) || (*path == 0)) { 22427f654740f2a26ad62a5c155af9199af9e69b889claireho return U_ICUDATA_NAME; 22527f654740f2a26ad62a5c155af9199af9e69b889claireho } 22627f654740f2a26ad62a5c155af9199af9e69b889claireho 22727f654740f2a26ad62a5c155af9199af9e69b889claireho path = findBasename(path); 22827f654740f2a26ad62a5c155af9199af9e69b889claireho 22927f654740f2a26ad62a5c155af9199af9e69b889claireho if((path == NULL) || (*path == 0)) { 23027f654740f2a26ad62a5c155af9199af9e69b889claireho return U_ICUDATA_NAME; 23127f654740f2a26ad62a5c155af9199af9e69b889claireho } 23227f654740f2a26ad62a5c155af9199af9e69b889claireho 23327f654740f2a26ad62a5c155af9199af9e69b889claireho return path; 23427f654740f2a26ad62a5c155af9199af9e69b889claireho} 23527f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 23627f654740f2a26ad62a5c155af9199af9e69b889claireho 23727f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------* 23827f654740f2a26ad62a5c155af9199af9e69b889claireho * * 23927f654740f2a26ad62a5c155af9199af9e69b889claireho * Cache for common data * 24027f654740f2a26ad62a5c155af9199af9e69b889claireho * Functions for looking up or adding entries to a cache of * 24127f654740f2a26ad62a5c155af9199af9e69b889claireho * data that has been previously opened. Avoids a potentially * 24227f654740f2a26ad62a5c155af9199af9e69b889claireho * expensive operation of re-opening the data for subsequent * 24327f654740f2a26ad62a5c155af9199af9e69b889claireho * uses. * 24427f654740f2a26ad62a5c155af9199af9e69b889claireho * * 24527f654740f2a26ad62a5c155af9199af9e69b889claireho * Data remains cached for the duration of the process. * 24627f654740f2a26ad62a5c155af9199af9e69b889claireho * * 24727f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------*/ 24827f654740f2a26ad62a5c155af9199af9e69b889claireho 24927f654740f2a26ad62a5c155af9199af9e69b889clairehotypedef struct DataCacheElement { 25027f654740f2a26ad62a5c155af9199af9e69b889claireho char *name; 25127f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *item; 25227f654740f2a26ad62a5c155af9199af9e69b889claireho} DataCacheElement; 25327f654740f2a26ad62a5c155af9199af9e69b889claireho 25427f654740f2a26ad62a5c155af9199af9e69b889claireho 25527f654740f2a26ad62a5c155af9199af9e69b889claireho 25627f654740f2a26ad62a5c155af9199af9e69b889claireho/* 25727f654740f2a26ad62a5c155af9199af9e69b889claireho * Deleter function for DataCacheElements. 25827f654740f2a26ad62a5c155af9199af9e69b889claireho * udata cleanup function closes the hash table; hash table in turn calls back to 25927f654740f2a26ad62a5c155af9199af9e69b889claireho * here for each entry. 26027f654740f2a26ad62a5c155af9199af9e69b889claireho */ 26127f654740f2a26ad62a5c155af9199af9e69b889clairehostatic void U_CALLCONV DataCacheElement_deleter(void *pDCEl) { 26227f654740f2a26ad62a5c155af9199af9e69b889claireho DataCacheElement *p = (DataCacheElement *)pDCEl; 26327f654740f2a26ad62a5c155af9199af9e69b889claireho udata_close(p->item); /* unmaps storage */ 26427f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(p->name); /* delete the hash key string. */ 26527f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(pDCEl); /* delete 'this' */ 26627f654740f2a26ad62a5c155af9199af9e69b889claireho} 26727f654740f2a26ad62a5c155af9199af9e69b889claireho 26859d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void udata_initHashTable() { 26959d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode err = U_ZERO_ERROR; 27059d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gCommonDataCache == NULL); 27159d709d503bab6e2b61931737e662dd293b40578ccornelius gCommonDataCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err); 27259d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_FAILURE(err)) { 27359d709d503bab6e2b61931737e662dd293b40578ccornelius // TODO: handle errors better. 27459d709d503bab6e2b61931737e662dd293b40578ccornelius gCommonDataCache = NULL; 27527f654740f2a26ad62a5c155af9199af9e69b889claireho } 27659d709d503bab6e2b61931737e662dd293b40578ccornelius if (gCommonDataCache != NULL) { 27759d709d503bab6e2b61931737e662dd293b40578ccornelius uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter); 27827f654740f2a26ad62a5c155af9199af9e69b889claireho ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup); 27927f654740f2a26ad62a5c155af9199af9e69b889claireho } 28059d709d503bab6e2b61931737e662dd293b40578ccornelius} 28127f654740f2a26ad62a5c155af9199af9e69b889claireho 28259d709d503bab6e2b61931737e662dd293b40578ccornelius /* udata_getCacheHashTable() 28359d709d503bab6e2b61931737e662dd293b40578ccornelius * Get the hash table used to store the data cache entries. 28459d709d503bab6e2b61931737e662dd293b40578ccornelius * Lazy create it if it doesn't yet exist. 28559d709d503bab6e2b61931737e662dd293b40578ccornelius */ 28659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic UHashtable *udata_getHashTable() { 28759d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable); 28827f654740f2a26ad62a5c155af9199af9e69b889claireho return gCommonDataCache; 28927f654740f2a26ad62a5c155af9199af9e69b889claireho} 29027f654740f2a26ad62a5c155af9199af9e69b889claireho 29127f654740f2a26ad62a5c155af9199af9e69b889claireho 29227f654740f2a26ad62a5c155af9199af9e69b889claireho 29327f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory *udata_findCachedData(const char *path) 29427f654740f2a26ad62a5c155af9199af9e69b889claireho{ 29527f654740f2a26ad62a5c155af9199af9e69b889claireho UHashtable *htable; 29627f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *retVal = NULL; 29727f654740f2a26ad62a5c155af9199af9e69b889claireho DataCacheElement *el; 29827f654740f2a26ad62a5c155af9199af9e69b889claireho const char *baseName; 29927f654740f2a26ad62a5c155af9199af9e69b889claireho 30027f654740f2a26ad62a5c155af9199af9e69b889claireho baseName = findBasename(path); /* Cache remembers only the base name, not the full path. */ 30127f654740f2a26ad62a5c155af9199af9e69b889claireho htable = udata_getHashTable(); 30227f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_lock(NULL); 30327f654740f2a26ad62a5c155af9199af9e69b889claireho el = (DataCacheElement *)uhash_get(htable, baseName); 30427f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_unlock(NULL); 30527f654740f2a26ad62a5c155af9199af9e69b889claireho if (el != NULL) { 30627f654740f2a26ad62a5c155af9199af9e69b889claireho retVal = el->item; 30727f654740f2a26ad62a5c155af9199af9e69b889claireho } 30827f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 30927f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Cache: [%s] -> %p\n", baseName, retVal); 31027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 31127f654740f2a26ad62a5c155af9199af9e69b889claireho return retVal; 31227f654740f2a26ad62a5c155af9199af9e69b889claireho} 31327f654740f2a26ad62a5c155af9199af9e69b889claireho 31427f654740f2a26ad62a5c155af9199af9e69b889claireho 31527f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory *udata_cacheDataItem(const char *path, UDataMemory *item, UErrorCode *pErr) { 31627f654740f2a26ad62a5c155af9199af9e69b889claireho DataCacheElement *newElement; 31727f654740f2a26ad62a5c155af9199af9e69b889claireho const char *baseName; 31827f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t nameLen; 31927f654740f2a26ad62a5c155af9199af9e69b889claireho UHashtable *htable; 32027f654740f2a26ad62a5c155af9199af9e69b889claireho DataCacheElement *oldValue = NULL; 32127f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode subErr = U_ZERO_ERROR; 32227f654740f2a26ad62a5c155af9199af9e69b889claireho 32327f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErr)) { 32427f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 32527f654740f2a26ad62a5c155af9199af9e69b889claireho } 32627f654740f2a26ad62a5c155af9199af9e69b889claireho 32727f654740f2a26ad62a5c155af9199af9e69b889claireho /* Create a new DataCacheElement - the thingy we store in the hash table - 32827f654740f2a26ad62a5c155af9199af9e69b889claireho * and copy the supplied path and UDataMemoryItems into it. 32927f654740f2a26ad62a5c155af9199af9e69b889claireho */ 33027f654740f2a26ad62a5c155af9199af9e69b889claireho newElement = (DataCacheElement *)uprv_malloc(sizeof(DataCacheElement)); 33127f654740f2a26ad62a5c155af9199af9e69b889claireho if (newElement == NULL) { 33227f654740f2a26ad62a5c155af9199af9e69b889claireho *pErr = U_MEMORY_ALLOCATION_ERROR; 33327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 33427f654740f2a26ad62a5c155af9199af9e69b889claireho } 33527f654740f2a26ad62a5c155af9199af9e69b889claireho newElement->item = UDataMemory_createNewInstance(pErr); 33627f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErr)) { 33727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newElement); 33827f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 33927f654740f2a26ad62a5c155af9199af9e69b889claireho } 34027f654740f2a26ad62a5c155af9199af9e69b889claireho UDatamemory_assign(newElement->item, item); 34127f654740f2a26ad62a5c155af9199af9e69b889claireho 34227f654740f2a26ad62a5c155af9199af9e69b889claireho baseName = findBasename(path); 34327f654740f2a26ad62a5c155af9199af9e69b889claireho nameLen = (int32_t)uprv_strlen(baseName); 34427f654740f2a26ad62a5c155af9199af9e69b889claireho newElement->name = (char *)uprv_malloc(nameLen+1); 34527f654740f2a26ad62a5c155af9199af9e69b889claireho if (newElement->name == NULL) { 34627f654740f2a26ad62a5c155af9199af9e69b889claireho *pErr = U_MEMORY_ALLOCATION_ERROR; 34727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newElement->item); 34827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newElement); 34927f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 35027f654740f2a26ad62a5c155af9199af9e69b889claireho } 35127f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcpy(newElement->name, baseName); 35227f654740f2a26ad62a5c155af9199af9e69b889claireho 35327f654740f2a26ad62a5c155af9199af9e69b889claireho /* Stick the new DataCacheElement into the hash table. 35427f654740f2a26ad62a5c155af9199af9e69b889claireho */ 35527f654740f2a26ad62a5c155af9199af9e69b889claireho htable = udata_getHashTable(); 35627f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_lock(NULL); 35727f654740f2a26ad62a5c155af9199af9e69b889claireho oldValue = (DataCacheElement *)uhash_get(htable, path); 35827f654740f2a26ad62a5c155af9199af9e69b889claireho if (oldValue != NULL) { 35927f654740f2a26ad62a5c155af9199af9e69b889claireho subErr = U_USING_DEFAULT_WARNING; 36027f654740f2a26ad62a5c155af9199af9e69b889claireho } 36127f654740f2a26ad62a5c155af9199af9e69b889claireho else { 36227f654740f2a26ad62a5c155af9199af9e69b889claireho uhash_put( 36327f654740f2a26ad62a5c155af9199af9e69b889claireho htable, 36427f654740f2a26ad62a5c155af9199af9e69b889claireho newElement->name, /* Key */ 36527f654740f2a26ad62a5c155af9199af9e69b889claireho newElement, /* Value */ 36627f654740f2a26ad62a5c155af9199af9e69b889claireho &subErr); 36727f654740f2a26ad62a5c155af9199af9e69b889claireho } 36827f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_unlock(NULL); 36927f654740f2a26ad62a5c155af9199af9e69b889claireho 37027f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 37127f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Cache: [%s] <<< %p : %s. vFunc=%p\n", newElement->name, 37227f654740f2a26ad62a5c155af9199af9e69b889claireho newElement->item, u_errorName(subErr), newElement->item->vFuncs); 37327f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 37427f654740f2a26ad62a5c155af9199af9e69b889claireho 37527f654740f2a26ad62a5c155af9199af9e69b889claireho if (subErr == U_USING_DEFAULT_WARNING || U_FAILURE(subErr)) { 37627f654740f2a26ad62a5c155af9199af9e69b889claireho *pErr = subErr; /* copy sub err unto fillin ONLY if something happens. */ 37727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newElement->name); 37827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newElement->item); 37927f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_free(newElement); 38027f654740f2a26ad62a5c155af9199af9e69b889claireho return oldValue ? oldValue->item : NULL; 38127f654740f2a26ad62a5c155af9199af9e69b889claireho } 38227f654740f2a26ad62a5c155af9199af9e69b889claireho 38327f654740f2a26ad62a5c155af9199af9e69b889claireho return newElement->item; 38427f654740f2a26ad62a5c155af9199af9e69b889claireho} 38527f654740f2a26ad62a5c155af9199af9e69b889claireho 38627f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------*============== 38727f654740f2a26ad62a5c155af9199af9e69b889claireho * * 38827f654740f2a26ad62a5c155af9199af9e69b889claireho * Path management. Could be shared with other tools/etc if need be * 38927f654740f2a26ad62a5c155af9199af9e69b889claireho * later on. * 39027f654740f2a26ad62a5c155af9199af9e69b889claireho * * 39127f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------*/ 39227f654740f2a26ad62a5c155af9199af9e69b889claireho 39327f654740f2a26ad62a5c155af9199af9e69b889claireho#define U_DATA_PATHITER_BUFSIZ 128 /* Size of local buffer for paths */ 39427f654740f2a26ad62a5c155af9199af9e69b889claireho /* Overflow causes malloc of larger buf */ 39527f654740f2a26ad62a5c155af9199af9e69b889claireho 39627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_NAMESPACE_BEGIN 39727f654740f2a26ad62a5c155af9199af9e69b889claireho 39827f654740f2a26ad62a5c155af9199af9e69b889clairehoclass UDataPathIterator 39927f654740f2a26ad62a5c155af9199af9e69b889claireho{ 40027f654740f2a26ad62a5c155af9199af9e69b889clairehopublic: 40127f654740f2a26ad62a5c155af9199af9e69b889claireho UDataPathIterator(const char *path, const char *pkg, 40227f654740f2a26ad62a5c155af9199af9e69b889claireho const char *item, const char *suffix, UBool doCheckLastFour, 40327f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode); 40427f654740f2a26ad62a5c155af9199af9e69b889claireho const char *next(UErrorCode *pErrorCode); 40527f654740f2a26ad62a5c155af9199af9e69b889claireho 40627f654740f2a26ad62a5c155af9199af9e69b889clairehoprivate: 40727f654740f2a26ad62a5c155af9199af9e69b889claireho const char *path; /* working path (u_icudata_Dir) */ 40827f654740f2a26ad62a5c155af9199af9e69b889claireho const char *nextPath; /* path following this one */ 40927f654740f2a26ad62a5c155af9199af9e69b889claireho const char *basename; /* item's basename (icudt22e_mt.res)*/ 41027f654740f2a26ad62a5c155af9199af9e69b889claireho const char *suffix; /* item suffix (can be null) */ 41127f654740f2a26ad62a5c155af9199af9e69b889claireho 41227f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t basenameLen; /* length of basename */ 41327f654740f2a26ad62a5c155af9199af9e69b889claireho 41427f654740f2a26ad62a5c155af9199af9e69b889claireho CharString itemPath; /* path passed in with item name */ 41527f654740f2a26ad62a5c155af9199af9e69b889claireho CharString pathBuffer; /* output path for this it'ion */ 41627f654740f2a26ad62a5c155af9199af9e69b889claireho CharString packageStub; /* example: "/icudt28b". Will ignore that leaf in set paths. */ 41727f654740f2a26ad62a5c155af9199af9e69b889claireho 41827f654740f2a26ad62a5c155af9199af9e69b889claireho UBool checkLastFour; /* if TRUE then allow paths such as '/foo/myapp.dat' 41927f654740f2a26ad62a5c155af9199af9e69b889claireho * to match, checks last 4 chars of suffix with 42027f654740f2a26ad62a5c155af9199af9e69b889claireho * last 4 of path, then previous chars. */ 42127f654740f2a26ad62a5c155af9199af9e69b889claireho}; 42227f654740f2a26ad62a5c155af9199af9e69b889claireho 42327f654740f2a26ad62a5c155af9199af9e69b889claireho/** 42427f654740f2a26ad62a5c155af9199af9e69b889claireho * @param iter The iterator to be initialized. Its current state does not matter. 42527f654740f2a26ad62a5c155af9199af9e69b889claireho * @param path The full pathname to be iterated over. If NULL, defaults to U_ICUDATA_NAME 42627f654740f2a26ad62a5c155af9199af9e69b889claireho * @param pkg Package which is being searched for, ex "icudt28l". Will ignore leave directories such as /icudt28l 42727f654740f2a26ad62a5c155af9199af9e69b889claireho * @param item Item to be searched for. Can include full path, such as /a/b/foo.dat 42827f654740f2a26ad62a5c155af9199af9e69b889claireho * @param suffix Optional item suffix, if not-null (ex. ".dat") then 'path' can contain 'item' explicitly. 42927f654740f2a26ad62a5c155af9199af9e69b889claireho * Ex: 'stuff.dat' would be found in '/a/foo:/tmp/stuff.dat:/bar/baz' as item #2. 43027f654740f2a26ad62a5c155af9199af9e69b889claireho * '/blarg/stuff.dat' would also be found. 43127f654740f2a26ad62a5c155af9199af9e69b889claireho */ 43227f654740f2a26ad62a5c155af9199af9e69b889clairehoUDataPathIterator::UDataPathIterator(const char *inPath, const char *pkg, 43327f654740f2a26ad62a5c155af9199af9e69b889claireho const char *item, const char *inSuffix, UBool doCheckLastFour, 43427f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) 43527f654740f2a26ad62a5c155af9199af9e69b889claireho{ 43627f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 43727f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "SUFFIX1=%s PATH=%s\n", inSuffix, inPath); 43827f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 43927f654740f2a26ad62a5c155af9199af9e69b889claireho /** Path **/ 44027f654740f2a26ad62a5c155af9199af9e69b889claireho if(inPath == NULL) { 44127f654740f2a26ad62a5c155af9199af9e69b889claireho path = u_getDataDirectory(); 44227f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 44327f654740f2a26ad62a5c155af9199af9e69b889claireho path = inPath; 44427f654740f2a26ad62a5c155af9199af9e69b889claireho } 44527f654740f2a26ad62a5c155af9199af9e69b889claireho 44627f654740f2a26ad62a5c155af9199af9e69b889claireho /** Package **/ 44727f654740f2a26ad62a5c155af9199af9e69b889claireho if(pkg != NULL) { 44827f654740f2a26ad62a5c155af9199af9e69b889claireho packageStub.append(U_FILE_SEP_CHAR, *pErrorCode).append(pkg, *pErrorCode); 44927f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 45027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "STUB=%s [%d]\n", packageStub.data(), packageStub.length()); 45127f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 45227f654740f2a26ad62a5c155af9199af9e69b889claireho } 45327f654740f2a26ad62a5c155af9199af9e69b889claireho 45427f654740f2a26ad62a5c155af9199af9e69b889claireho /** Item **/ 45527f654740f2a26ad62a5c155af9199af9e69b889claireho basename = findBasename(item); 45627f654740f2a26ad62a5c155af9199af9e69b889claireho basenameLen = (int32_t)uprv_strlen(basename); 45727f654740f2a26ad62a5c155af9199af9e69b889claireho 45827f654740f2a26ad62a5c155af9199af9e69b889claireho /** Item path **/ 45927f654740f2a26ad62a5c155af9199af9e69b889claireho if(basename == item) { 46027f654740f2a26ad62a5c155af9199af9e69b889claireho nextPath = path; 46127f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 46227f654740f2a26ad62a5c155af9199af9e69b889claireho itemPath.append(item, (int32_t)(basename-item), *pErrorCode); 46327f654740f2a26ad62a5c155af9199af9e69b889claireho nextPath = itemPath.data(); 46427f654740f2a26ad62a5c155af9199af9e69b889claireho } 46527f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 46627f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "SUFFIX=%s [%p]\n", inSuffix, inSuffix); 46727f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 46827f654740f2a26ad62a5c155af9199af9e69b889claireho 46927f654740f2a26ad62a5c155af9199af9e69b889claireho /** Suffix **/ 47027f654740f2a26ad62a5c155af9199af9e69b889claireho if(inSuffix != NULL) { 47127f654740f2a26ad62a5c155af9199af9e69b889claireho suffix = inSuffix; 47227f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 47327f654740f2a26ad62a5c155af9199af9e69b889claireho suffix = ""; 47427f654740f2a26ad62a5c155af9199af9e69b889claireho } 47527f654740f2a26ad62a5c155af9199af9e69b889claireho 47627f654740f2a26ad62a5c155af9199af9e69b889claireho checkLastFour = doCheckLastFour; 47727f654740f2a26ad62a5c155af9199af9e69b889claireho 47827f654740f2a26ad62a5c155af9199af9e69b889claireho /* pathBuffer will hold the output path strings returned by this iterator */ 47927f654740f2a26ad62a5c155af9199af9e69b889claireho 48027f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 48127f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "%p: init %s -> [path=%s], [base=%s], [suff=%s], [itempath=%s], [nextpath=%s], [checklast4=%s]\n", 48227f654740f2a26ad62a5c155af9199af9e69b889claireho iter, 48327f654740f2a26ad62a5c155af9199af9e69b889claireho item, 48427f654740f2a26ad62a5c155af9199af9e69b889claireho path, 48527f654740f2a26ad62a5c155af9199af9e69b889claireho basename, 48627f654740f2a26ad62a5c155af9199af9e69b889claireho suffix, 48727f654740f2a26ad62a5c155af9199af9e69b889claireho itemPath.data(), 48827f654740f2a26ad62a5c155af9199af9e69b889claireho nextPath, 48927f654740f2a26ad62a5c155af9199af9e69b889claireho checkLastFour?"TRUE":"false"); 49027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 49127f654740f2a26ad62a5c155af9199af9e69b889claireho} 49227f654740f2a26ad62a5c155af9199af9e69b889claireho 49327f654740f2a26ad62a5c155af9199af9e69b889claireho/** 49427f654740f2a26ad62a5c155af9199af9e69b889claireho * Get the next path on the list. 49527f654740f2a26ad62a5c155af9199af9e69b889claireho * 49627f654740f2a26ad62a5c155af9199af9e69b889claireho * @param iter The Iter to be used 49727f654740f2a26ad62a5c155af9199af9e69b889claireho * @param len If set, pointer to the length of the returned path, for convenience. 49827f654740f2a26ad62a5c155af9199af9e69b889claireho * @return Pointer to the next path segment, or NULL if there are no more. 49927f654740f2a26ad62a5c155af9199af9e69b889claireho */ 50027f654740f2a26ad62a5c155af9199af9e69b889clairehoconst char *UDataPathIterator::next(UErrorCode *pErrorCode) 50127f654740f2a26ad62a5c155af9199af9e69b889claireho{ 50227f654740f2a26ad62a5c155af9199af9e69b889claireho if(U_FAILURE(*pErrorCode)) { 50327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 50427f654740f2a26ad62a5c155af9199af9e69b889claireho } 50527f654740f2a26ad62a5c155af9199af9e69b889claireho 50627f654740f2a26ad62a5c155af9199af9e69b889claireho const char *currentPath = NULL; 50727f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t pathLen = 0; 50827f654740f2a26ad62a5c155af9199af9e69b889claireho const char *pathBasename; 50927f654740f2a26ad62a5c155af9199af9e69b889claireho 51027f654740f2a26ad62a5c155af9199af9e69b889claireho do 51127f654740f2a26ad62a5c155af9199af9e69b889claireho { 51227f654740f2a26ad62a5c155af9199af9e69b889claireho if( nextPath == NULL ) { 51327f654740f2a26ad62a5c155af9199af9e69b889claireho break; 51427f654740f2a26ad62a5c155af9199af9e69b889claireho } 51527f654740f2a26ad62a5c155af9199af9e69b889claireho currentPath = nextPath; 51627f654740f2a26ad62a5c155af9199af9e69b889claireho 51727f654740f2a26ad62a5c155af9199af9e69b889claireho if(nextPath == itemPath.data()) { /* we were processing item's path. */ 51827f654740f2a26ad62a5c155af9199af9e69b889claireho nextPath = path; /* start with regular path next tm. */ 51927f654740f2a26ad62a5c155af9199af9e69b889claireho pathLen = (int32_t)uprv_strlen(currentPath); 52027f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 52127f654740f2a26ad62a5c155af9199af9e69b889claireho /* fix up next for next time */ 52227f654740f2a26ad62a5c155af9199af9e69b889claireho nextPath = uprv_strchr(currentPath, U_PATH_SEP_CHAR); 52327f654740f2a26ad62a5c155af9199af9e69b889claireho if(nextPath == NULL) { 52427f654740f2a26ad62a5c155af9199af9e69b889claireho /* segment: entire path */ 52527f654740f2a26ad62a5c155af9199af9e69b889claireho pathLen = (int32_t)uprv_strlen(currentPath); 52627f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 52727f654740f2a26ad62a5c155af9199af9e69b889claireho /* segment: until next segment */ 52827f654740f2a26ad62a5c155af9199af9e69b889claireho pathLen = (int32_t)(nextPath - currentPath); 52927f654740f2a26ad62a5c155af9199af9e69b889claireho /* skip divider */ 53027f654740f2a26ad62a5c155af9199af9e69b889claireho nextPath ++; 53127f654740f2a26ad62a5c155af9199af9e69b889claireho } 53227f654740f2a26ad62a5c155af9199af9e69b889claireho } 53327f654740f2a26ad62a5c155af9199af9e69b889claireho 53427f654740f2a26ad62a5c155af9199af9e69b889claireho if(pathLen == 0) { 53527f654740f2a26ad62a5c155af9199af9e69b889claireho continue; 53627f654740f2a26ad62a5c155af9199af9e69b889claireho } 53727f654740f2a26ad62a5c155af9199af9e69b889claireho 53827f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 53927f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "rest of path (IDD) = %s\n", currentPath); 54027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, " "); 54127f654740f2a26ad62a5c155af9199af9e69b889claireho { 54227f654740f2a26ad62a5c155af9199af9e69b889claireho uint32_t qqq; 54327f654740f2a26ad62a5c155af9199af9e69b889claireho for(qqq=0;qqq<pathLen;qqq++) 54427f654740f2a26ad62a5c155af9199af9e69b889claireho { 54527f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, " "); 54627f654740f2a26ad62a5c155af9199af9e69b889claireho } 54727f654740f2a26ad62a5c155af9199af9e69b889claireho 54827f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "^\n"); 54927f654740f2a26ad62a5c155af9199af9e69b889claireho } 55027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 55127f654740f2a26ad62a5c155af9199af9e69b889claireho pathBuffer.clear().append(currentPath, pathLen, *pErrorCode); 55227f654740f2a26ad62a5c155af9199af9e69b889claireho 55327f654740f2a26ad62a5c155af9199af9e69b889claireho /* check for .dat files */ 55427f654740f2a26ad62a5c155af9199af9e69b889claireho pathBasename = findBasename(pathBuffer.data()); 55527f654740f2a26ad62a5c155af9199af9e69b889claireho 55627f654740f2a26ad62a5c155af9199af9e69b889claireho if(checkLastFour == TRUE && 55727f654740f2a26ad62a5c155af9199af9e69b889claireho (pathLen>=4) && 55827f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strncmp(pathBuffer.data() +(pathLen-4), suffix, 4)==0 && /* suffix matches */ 55927f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strncmp(findBasename(pathBuffer.data()), basename, basenameLen)==0 && /* base matches */ 56027f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strlen(pathBasename)==(basenameLen+4)) { /* base+suffix = full len */ 56127f654740f2a26ad62a5c155af9199af9e69b889claireho 56227f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 56327f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Have %s file on the path: %s\n", suffix, pathBuffer.data()); 56427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 56527f654740f2a26ad62a5c155af9199af9e69b889claireho /* do nothing */ 56627f654740f2a26ad62a5c155af9199af9e69b889claireho } 56727f654740f2a26ad62a5c155af9199af9e69b889claireho else 56827f654740f2a26ad62a5c155af9199af9e69b889claireho { /* regular dir path */ 56927f654740f2a26ad62a5c155af9199af9e69b889claireho if(pathBuffer[pathLen-1] != U_FILE_SEP_CHAR) { 57027f654740f2a26ad62a5c155af9199af9e69b889claireho if((pathLen>=4) && 57127f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strncmp(pathBuffer.data()+(pathLen-4), ".dat", 4) == 0) 57227f654740f2a26ad62a5c155af9199af9e69b889claireho { 57327f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 57427f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "skipping non-directory .dat file %s\n", pathBuffer.data()); 57527f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 57627f654740f2a26ad62a5c155af9199af9e69b889claireho continue; 57727f654740f2a26ad62a5c155af9199af9e69b889claireho } 57827f654740f2a26ad62a5c155af9199af9e69b889claireho 57927f654740f2a26ad62a5c155af9199af9e69b889claireho /* Check if it is a directory with the same name as our package */ 58027f654740f2a26ad62a5c155af9199af9e69b889claireho if(!packageStub.isEmpty() && 58127f654740f2a26ad62a5c155af9199af9e69b889claireho (pathLen > packageStub.length()) && 58227f654740f2a26ad62a5c155af9199af9e69b889claireho !uprv_strcmp(pathBuffer.data() + pathLen - packageStub.length(), packageStub.data())) { 58327f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 58427f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Found stub %s (will add package %s of len %d)\n", packageStub.data(), basename, basenameLen); 58527f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 58627f654740f2a26ad62a5c155af9199af9e69b889claireho pathBuffer.truncate(pathLen - packageStub.length()); 58727f654740f2a26ad62a5c155af9199af9e69b889claireho } 58827f654740f2a26ad62a5c155af9199af9e69b889claireho pathBuffer.append(U_FILE_SEP_CHAR, *pErrorCode); 58927f654740f2a26ad62a5c155af9199af9e69b889claireho } 59027f654740f2a26ad62a5c155af9199af9e69b889claireho 59127f654740f2a26ad62a5c155af9199af9e69b889claireho /* + basename */ 59227f654740f2a26ad62a5c155af9199af9e69b889claireho pathBuffer.append(packageStub.data()+1, packageStub.length()-1, *pErrorCode); 59327f654740f2a26ad62a5c155af9199af9e69b889claireho 59427f654740f2a26ad62a5c155af9199af9e69b889claireho if(*suffix) /* tack on suffix */ 59527f654740f2a26ad62a5c155af9199af9e69b889claireho { 59627f654740f2a26ad62a5c155af9199af9e69b889claireho pathBuffer.append(suffix, *pErrorCode); 59727f654740f2a26ad62a5c155af9199af9e69b889claireho } 59827f654740f2a26ad62a5c155af9199af9e69b889claireho } 59927f654740f2a26ad62a5c155af9199af9e69b889claireho 60027f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 60127f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, " --> %s\n", pathBuffer.data()); 60227f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 60327f654740f2a26ad62a5c155af9199af9e69b889claireho 60427f654740f2a26ad62a5c155af9199af9e69b889claireho return pathBuffer.data(); 60527f654740f2a26ad62a5c155af9199af9e69b889claireho 60627f654740f2a26ad62a5c155af9199af9e69b889claireho } while(path); 60727f654740f2a26ad62a5c155af9199af9e69b889claireho 60827f654740f2a26ad62a5c155af9199af9e69b889claireho /* fell way off the end */ 60927f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 61027f654740f2a26ad62a5c155af9199af9e69b889claireho} 61127f654740f2a26ad62a5c155af9199af9e69b889claireho 61227f654740f2a26ad62a5c155af9199af9e69b889clairehoU_NAMESPACE_END 61327f654740f2a26ad62a5c155af9199af9e69b889claireho 61427f654740f2a26ad62a5c155af9199af9e69b889claireho/* ==================================================================================*/ 61527f654740f2a26ad62a5c155af9199af9e69b889claireho 61627f654740f2a26ad62a5c155af9199af9e69b889claireho 61727f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------* 61827f654740f2a26ad62a5c155af9199af9e69b889claireho * * 61927f654740f2a26ad62a5c155af9199af9e69b889claireho * Add a static reference to the common data library * 62027f654740f2a26ad62a5c155af9199af9e69b889claireho * Unless overridden by an explicit udata_setCommonData, this will be * 62127f654740f2a26ad62a5c155af9199af9e69b889claireho * our common data. * 62227f654740f2a26ad62a5c155af9199af9e69b889claireho * * 62327f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------*/ 62427f654740f2a26ad62a5c155af9199af9e69b889clairehoextern "C" const DataHeader U_DATA_API U_ICUDATA_ENTRY_POINT; 62527f654740f2a26ad62a5c155af9199af9e69b889claireho 62627f654740f2a26ad62a5c155af9199af9e69b889claireho/* 62727f654740f2a26ad62a5c155af9199af9e69b889claireho * This would be a good place for weak-linkage declarations of 62827f654740f2a26ad62a5c155af9199af9e69b889claireho * partial-data-library access functions where each returns a pointer 62927f654740f2a26ad62a5c155af9199af9e69b889claireho * to its data package, if it is linked in. 63027f654740f2a26ad62a5c155af9199af9e69b889claireho */ 63127f654740f2a26ad62a5c155af9199af9e69b889claireho/* 63227f654740f2a26ad62a5c155af9199af9e69b889clairehoextern const void *uprv_getICUData_collation(void) ATTRIBUTE_WEAK; 63327f654740f2a26ad62a5c155af9199af9e69b889clairehoextern const void *uprv_getICUData_conversion(void) ATTRIBUTE_WEAK; 63459d709d503bab6e2b61931737e662dd293b40578ccornelius */ 63527f654740f2a26ad62a5c155af9199af9e69b889claireho 63627f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------* 63727f654740f2a26ad62a5c155af9199af9e69b889claireho * * 63827f654740f2a26ad62a5c155af9199af9e69b889claireho * openCommonData Attempt to open a common format (.dat) file * 63927f654740f2a26ad62a5c155af9199af9e69b889claireho * Map it into memory (if it's not there already) * 64027f654740f2a26ad62a5c155af9199af9e69b889claireho * and return a UDataMemory object for it. * 64127f654740f2a26ad62a5c155af9199af9e69b889claireho * * 64227f654740f2a26ad62a5c155af9199af9e69b889claireho * If the requested data is already open and cached * 64327f654740f2a26ad62a5c155af9199af9e69b889claireho * just return the cached UDataMem object. * 64427f654740f2a26ad62a5c155af9199af9e69b889claireho * * 64527f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------*/ 64627f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory * 64727f654740f2a26ad62a5c155af9199af9e69b889clairehoopenCommonData(const char *path, /* Path from OpenChoice? */ 64827f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t commonDataIndex, /* ICU Data (index >= 0) if path == NULL */ 64927f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) 65027f654740f2a26ad62a5c155af9199af9e69b889claireho{ 65127f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory tData; 65227f654740f2a26ad62a5c155af9199af9e69b889claireho const char *pathBuffer; 65327f654740f2a26ad62a5c155af9199af9e69b889claireho const char *inBasename; 65427f654740f2a26ad62a5c155af9199af9e69b889claireho 65527f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErrorCode)) { 65627f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 65727f654740f2a26ad62a5c155af9199af9e69b889claireho } 65827f654740f2a26ad62a5c155af9199af9e69b889claireho 65927f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_init(&tData); 66027f654740f2a26ad62a5c155af9199af9e69b889claireho 66127f654740f2a26ad62a5c155af9199af9e69b889claireho /* ??????? TODO revisit this */ 66227f654740f2a26ad62a5c155af9199af9e69b889claireho if (commonDataIndex >= 0) { 66327f654740f2a26ad62a5c155af9199af9e69b889claireho /* "mini-cache" for common ICU data */ 66427f654740f2a26ad62a5c155af9199af9e69b889claireho if(commonDataIndex >= LENGTHOF(gCommonICUDataArray)) { 66527f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 66627f654740f2a26ad62a5c155af9199af9e69b889claireho } 66727f654740f2a26ad62a5c155af9199af9e69b889claireho if(gCommonICUDataArray[commonDataIndex] == NULL) { 66827f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t i; 66927f654740f2a26ad62a5c155af9199af9e69b889claireho for(i = 0; i < commonDataIndex; ++i) { 67027f654740f2a26ad62a5c155af9199af9e69b889claireho if(gCommonICUDataArray[i]->pHeader == &U_ICUDATA_ENTRY_POINT) { 67127f654740f2a26ad62a5c155af9199af9e69b889claireho /* The linked-in data is already in the list. */ 67227f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 67327f654740f2a26ad62a5c155af9199af9e69b889claireho } 67427f654740f2a26ad62a5c155af9199af9e69b889claireho } 67527f654740f2a26ad62a5c155af9199af9e69b889claireho 67627f654740f2a26ad62a5c155af9199af9e69b889claireho /* Add the linked-in data to the list. */ 67727f654740f2a26ad62a5c155af9199af9e69b889claireho /* 67827f654740f2a26ad62a5c155af9199af9e69b889claireho * This is where we would check and call weakly linked partial-data-library 67927f654740f2a26ad62a5c155af9199af9e69b889claireho * access functions. 68027f654740f2a26ad62a5c155af9199af9e69b889claireho */ 68127f654740f2a26ad62a5c155af9199af9e69b889claireho setCommonICUDataPointer(&U_ICUDATA_ENTRY_POINT, FALSE, pErrorCode); 68227f654740f2a26ad62a5c155af9199af9e69b889claireho } 68327f654740f2a26ad62a5c155af9199af9e69b889claireho return gCommonICUDataArray[commonDataIndex]; 68427f654740f2a26ad62a5c155af9199af9e69b889claireho } 68527f654740f2a26ad62a5c155af9199af9e69b889claireho 68627f654740f2a26ad62a5c155af9199af9e69b889claireho 68727f654740f2a26ad62a5c155af9199af9e69b889claireho /* request is NOT for ICU Data. */ 68827f654740f2a26ad62a5c155af9199af9e69b889claireho 68927f654740f2a26ad62a5c155af9199af9e69b889claireho /* Find the base name portion of the supplied path. */ 69027f654740f2a26ad62a5c155af9199af9e69b889claireho /* inBasename will be left pointing somewhere within the original path string. */ 69127f654740f2a26ad62a5c155af9199af9e69b889claireho inBasename = findBasename(path); 69227f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 69327f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "inBasename = %s\n", inBasename); 69427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 69527f654740f2a26ad62a5c155af9199af9e69b889claireho 69627f654740f2a26ad62a5c155af9199af9e69b889claireho if(*inBasename==0) { 69727f654740f2a26ad62a5c155af9199af9e69b889claireho /* no basename. This will happen if the original path was a directory name, */ 69827f654740f2a26ad62a5c155af9199af9e69b889claireho /* like "a/b/c/". (Fallback to separate files will still work.) */ 69927f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 70027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "ocd: no basename in %s, bailing.\n", path); 70127f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 70227f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=U_FILE_ACCESS_ERROR; 70327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 70427f654740f2a26ad62a5c155af9199af9e69b889claireho } 70527f654740f2a26ad62a5c155af9199af9e69b889claireho 70627f654740f2a26ad62a5c155af9199af9e69b889claireho /* Is the requested common data file already open and cached? */ 70727f654740f2a26ad62a5c155af9199af9e69b889claireho /* Note that the cache is keyed by the base name only. The rest of the path, */ 70827f654740f2a26ad62a5c155af9199af9e69b889claireho /* if any, is not considered. */ 70927f654740f2a26ad62a5c155af9199af9e69b889claireho { 71027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *dataToReturn = udata_findCachedData(inBasename); 71127f654740f2a26ad62a5c155af9199af9e69b889claireho if (dataToReturn != NULL) { 71227f654740f2a26ad62a5c155af9199af9e69b889claireho return dataToReturn; 71327f654740f2a26ad62a5c155af9199af9e69b889claireho } 71427f654740f2a26ad62a5c155af9199af9e69b889claireho } 71527f654740f2a26ad62a5c155af9199af9e69b889claireho 71627f654740f2a26ad62a5c155af9199af9e69b889claireho /* Requested item is not in the cache. 71727f654740f2a26ad62a5c155af9199af9e69b889claireho * Hunt it down, trying all the path locations 71827f654740f2a26ad62a5c155af9199af9e69b889claireho */ 71927f654740f2a26ad62a5c155af9199af9e69b889claireho 72027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataPathIterator iter(u_getDataDirectory(), inBasename, path, ".dat", TRUE, pErrorCode); 72127f654740f2a26ad62a5c155af9199af9e69b889claireho 72227f654740f2a26ad62a5c155af9199af9e69b889claireho while((UDataMemory_isLoaded(&tData)==FALSE) && (pathBuffer = iter.next(pErrorCode)) != NULL) 72327f654740f2a26ad62a5c155af9199af9e69b889claireho { 72427f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 72527f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "ocd: trying path %s - ", pathBuffer); 72627f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 72727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_mapFile(&tData, pathBuffer); 72827f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 72927f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "%s\n", UDataMemory_isLoaded(&tData)?"LOADED":"not loaded"); 73027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 73127f654740f2a26ad62a5c155af9199af9e69b889claireho } 73227f654740f2a26ad62a5c155af9199af9e69b889claireho 73327f654740f2a26ad62a5c155af9199af9e69b889claireho#if defined(OS390_STUBDATA) && defined(OS390BATCH) 73427f654740f2a26ad62a5c155af9199af9e69b889claireho if (!UDataMemory_isLoaded(&tData)) { 73527f654740f2a26ad62a5c155af9199af9e69b889claireho char ourPathBuffer[1024]; 73627f654740f2a26ad62a5c155af9199af9e69b889claireho /* One more chance, for extendCommonData() */ 73727f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strncpy(ourPathBuffer, path, 1019); 73827f654740f2a26ad62a5c155af9199af9e69b889claireho ourPathBuffer[1019]=0; 73927f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strcat(ourPathBuffer, ".dat"); 74027f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_mapFile(&tData, ourPathBuffer); 74127f654740f2a26ad62a5c155af9199af9e69b889claireho } 74227f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 74327f654740f2a26ad62a5c155af9199af9e69b889claireho 74427f654740f2a26ad62a5c155af9199af9e69b889claireho if (!UDataMemory_isLoaded(&tData)) { 74527f654740f2a26ad62a5c155af9199af9e69b889claireho /* no common data */ 74627f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=U_FILE_ACCESS_ERROR; 74727f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 74827f654740f2a26ad62a5c155af9199af9e69b889claireho } 74927f654740f2a26ad62a5c155af9199af9e69b889claireho 75027f654740f2a26ad62a5c155af9199af9e69b889claireho /* we have mapped a file, check its header */ 75127f654740f2a26ad62a5c155af9199af9e69b889claireho udata_checkCommonData(&tData, pErrorCode); 75227f654740f2a26ad62a5c155af9199af9e69b889claireho 75327f654740f2a26ad62a5c155af9199af9e69b889claireho 75427f654740f2a26ad62a5c155af9199af9e69b889claireho /* Cache the UDataMemory struct for this .dat file, 75527f654740f2a26ad62a5c155af9199af9e69b889claireho * so we won't need to hunt it down and map it again next time 75627f654740f2a26ad62a5c155af9199af9e69b889claireho * something is needed from it. */ 75727f654740f2a26ad62a5c155af9199af9e69b889claireho return udata_cacheDataItem(inBasename, &tData, pErrorCode); 75827f654740f2a26ad62a5c155af9199af9e69b889claireho} 75927f654740f2a26ad62a5c155af9199af9e69b889claireho 76027f654740f2a26ad62a5c155af9199af9e69b889claireho 76127f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------* 76227f654740f2a26ad62a5c155af9199af9e69b889claireho * * 76327f654740f2a26ad62a5c155af9199af9e69b889claireho * extendICUData If the full set of ICU data was not loaded at * 76427f654740f2a26ad62a5c155af9199af9e69b889claireho * program startup, load it now. This function will * 76527f654740f2a26ad62a5c155af9199af9e69b889claireho * be called when the lookup of an ICU data item in * 76627f654740f2a26ad62a5c155af9199af9e69b889claireho * the common ICU data fails. * 76727f654740f2a26ad62a5c155af9199af9e69b889claireho * * 76827f654740f2a26ad62a5c155af9199af9e69b889claireho * return true if new data is loaded, false otherwise.* 76927f654740f2a26ad62a5c155af9199af9e69b889claireho * * 77027f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------*/ 77127f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UBool extendICUData(UErrorCode *pErr) 77227f654740f2a26ad62a5c155af9199af9e69b889claireho{ 77327f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *pData; 77427f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory copyPData; 77527f654740f2a26ad62a5c155af9199af9e69b889claireho UBool didUpdate = FALSE; 77627f654740f2a26ad62a5c155af9199af9e69b889claireho 77727f654740f2a26ad62a5c155af9199af9e69b889claireho /* 77827f654740f2a26ad62a5c155af9199af9e69b889claireho * There is a chance for a race condition here. 77927f654740f2a26ad62a5c155af9199af9e69b889claireho * Normally, ICU data is loaded from a DLL or via mmap() and 78027f654740f2a26ad62a5c155af9199af9e69b889claireho * setCommonICUData() will detect if the same address is set twice. 78127f654740f2a26ad62a5c155af9199af9e69b889claireho * If ICU is built with data loading via fread() then the address will 78227f654740f2a26ad62a5c155af9199af9e69b889claireho * be different each time the common data is loaded and we may add 78327f654740f2a26ad62a5c155af9199af9e69b889claireho * multiple copies of the data. 78427f654740f2a26ad62a5c155af9199af9e69b889claireho * In this case, use a mutex to prevent the race. 78527f654740f2a26ad62a5c155af9199af9e69b889claireho * Use a specific mutex to avoid nested locks of the global mutex. 78627f654740f2a26ad62a5c155af9199af9e69b889claireho */ 78727f654740f2a26ad62a5c155af9199af9e69b889claireho#if MAP_IMPLEMENTATION==MAP_STDIO 78854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius static UMutex extendICUDataMutex = U_MUTEX_INITIALIZER; 78927f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_lock(&extendICUDataMutex); 79027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 79127f654740f2a26ad62a5c155af9199af9e69b889claireho if(!gHaveTriedToLoadCommonData) { 79227f654740f2a26ad62a5c155af9199af9e69b889claireho /* See if we can explicitly open a .dat file for the ICUData. */ 79327f654740f2a26ad62a5c155af9199af9e69b889claireho pData = openCommonData( 79427f654740f2a26ad62a5c155af9199af9e69b889claireho U_ICUDATA_NAME, /* "icudt20l" , for example. */ 79527f654740f2a26ad62a5c155af9199af9e69b889claireho -1, /* Pretend we're not opening ICUData */ 79627f654740f2a26ad62a5c155af9199af9e69b889claireho pErr); 79727f654740f2a26ad62a5c155af9199af9e69b889claireho 79827f654740f2a26ad62a5c155af9199af9e69b889claireho /* How about if there is no pData, eh... */ 79927f654740f2a26ad62a5c155af9199af9e69b889claireho 80027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_init(©PData); 80127f654740f2a26ad62a5c155af9199af9e69b889claireho if(pData != NULL) { 80227f654740f2a26ad62a5c155af9199af9e69b889claireho UDatamemory_assign(©PData, pData); 80327f654740f2a26ad62a5c155af9199af9e69b889claireho copyPData.map = 0; /* The mapping for this data is owned by the hash table */ 80427f654740f2a26ad62a5c155af9199af9e69b889claireho copyPData.mapAddr = 0; /* which will unmap it when ICU is shut down. */ 80527f654740f2a26ad62a5c155af9199af9e69b889claireho /* CommonICUData is also unmapped when ICU is shut down.*/ 80627f654740f2a26ad62a5c155af9199af9e69b889claireho /* To avoid unmapping the data twice, zero out the map */ 80727f654740f2a26ad62a5c155af9199af9e69b889claireho /* fields in the UDataMemory that we're assigning */ 80827f654740f2a26ad62a5c155af9199af9e69b889claireho /* to CommonICUData. */ 80927f654740f2a26ad62a5c155af9199af9e69b889claireho 810b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho didUpdate = /* no longer using this result */ 81127f654740f2a26ad62a5c155af9199af9e69b889claireho setCommonICUData(©PData,/* The new common data. */ 81227f654740f2a26ad62a5c155af9199af9e69b889claireho FALSE, /* No warnings if write didn't happen */ 81327f654740f2a26ad62a5c155af9199af9e69b889claireho pErr); /* setCommonICUData honors errors; NOP if error set */ 81427f654740f2a26ad62a5c155af9199af9e69b889claireho } 815b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 816b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho gHaveTriedToLoadCommonData = TRUE; 81727f654740f2a26ad62a5c155af9199af9e69b889claireho } 818b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 819b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho didUpdate = findCommonICUDataByName(U_ICUDATA_NAME); /* Return 'true' when a racing writes out the extended */ 820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho /* data after another thread has failed to see it (in openCommonData), so */ 821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho /* extended data can be examined. */ 822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho /* Also handles a race through here before gHaveTriedToLoadCommonData is set. */ 823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 82427f654740f2a26ad62a5c155af9199af9e69b889claireho#if MAP_IMPLEMENTATION==MAP_STDIO 82527f654740f2a26ad62a5c155af9199af9e69b889claireho umtx_unlock(&extendICUDataMutex); 82627f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 82727f654740f2a26ad62a5c155af9199af9e69b889claireho return didUpdate; /* Return true if ICUData pointer was updated. */ 82827f654740f2a26ad62a5c155af9199af9e69b889claireho /* (Could potentialy have been done by another thread racing */ 82927f654740f2a26ad62a5c155af9199af9e69b889claireho /* us through here, but that's fine, we still return true */ 83027f654740f2a26ad62a5c155af9199af9e69b889claireho /* so that current thread will also examine extended data. */ 83127f654740f2a26ad62a5c155af9199af9e69b889claireho} 83227f654740f2a26ad62a5c155af9199af9e69b889claireho 83327f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------* 83427f654740f2a26ad62a5c155af9199af9e69b889claireho * * 83527f654740f2a26ad62a5c155af9199af9e69b889claireho * udata_setCommonData * 83627f654740f2a26ad62a5c155af9199af9e69b889claireho * * 83727f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------*/ 83827f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI void U_EXPORT2 83927f654740f2a26ad62a5c155af9199af9e69b889clairehoudata_setCommonData(const void *data, UErrorCode *pErrorCode) { 84027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory dataMemory; 84127f654740f2a26ad62a5c155af9199af9e69b889claireho 84227f654740f2a26ad62a5c155af9199af9e69b889claireho if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 84327f654740f2a26ad62a5c155af9199af9e69b889claireho return; 84427f654740f2a26ad62a5c155af9199af9e69b889claireho } 84527f654740f2a26ad62a5c155af9199af9e69b889claireho 84627f654740f2a26ad62a5c155af9199af9e69b889claireho if(data==NULL) { 84727f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 84827f654740f2a26ad62a5c155af9199af9e69b889claireho return; 84927f654740f2a26ad62a5c155af9199af9e69b889claireho } 85027f654740f2a26ad62a5c155af9199af9e69b889claireho 85127f654740f2a26ad62a5c155af9199af9e69b889claireho /* set the data pointer and test for validity */ 85227f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_init(&dataMemory); 85327f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_setData(&dataMemory, data); 85427f654740f2a26ad62a5c155af9199af9e69b889claireho udata_checkCommonData(&dataMemory, pErrorCode); 85527f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErrorCode)) {return;} 85627f654740f2a26ad62a5c155af9199af9e69b889claireho 85727f654740f2a26ad62a5c155af9199af9e69b889claireho /* we have good data */ 85827f654740f2a26ad62a5c155af9199af9e69b889claireho /* Set it up as the ICU Common Data. */ 85927f654740f2a26ad62a5c155af9199af9e69b889claireho setCommonICUData(&dataMemory, TRUE, pErrorCode); 86027f654740f2a26ad62a5c155af9199af9e69b889claireho} 86127f654740f2a26ad62a5c155af9199af9e69b889claireho 86227f654740f2a26ad62a5c155af9199af9e69b889claireho/*--------------------------------------------------------------------------- 86327f654740f2a26ad62a5c155af9199af9e69b889claireho * 86427f654740f2a26ad62a5c155af9199af9e69b889claireho * udata_setAppData 86527f654740f2a26ad62a5c155af9199af9e69b889claireho * 86627f654740f2a26ad62a5c155af9199af9e69b889claireho *---------------------------------------------------------------------------- */ 86727f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI void U_EXPORT2 86827f654740f2a26ad62a5c155af9199af9e69b889clairehoudata_setAppData(const char *path, const void *data, UErrorCode *err) 86927f654740f2a26ad62a5c155af9199af9e69b889claireho{ 87027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory udm; 87127f654740f2a26ad62a5c155af9199af9e69b889claireho 87227f654740f2a26ad62a5c155af9199af9e69b889claireho if(err==NULL || U_FAILURE(*err)) { 87327f654740f2a26ad62a5c155af9199af9e69b889claireho return; 87427f654740f2a26ad62a5c155af9199af9e69b889claireho } 87527f654740f2a26ad62a5c155af9199af9e69b889claireho if(data==NULL) { 87627f654740f2a26ad62a5c155af9199af9e69b889claireho *err=U_ILLEGAL_ARGUMENT_ERROR; 87727f654740f2a26ad62a5c155af9199af9e69b889claireho return; 87827f654740f2a26ad62a5c155af9199af9e69b889claireho } 87927f654740f2a26ad62a5c155af9199af9e69b889claireho 88027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_init(&udm); 88127f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory_setData(&udm, data); 88227f654740f2a26ad62a5c155af9199af9e69b889claireho udata_checkCommonData(&udm, err); 88327f654740f2a26ad62a5c155af9199af9e69b889claireho udata_cacheDataItem(path, &udm, err); 88427f654740f2a26ad62a5c155af9199af9e69b889claireho} 88527f654740f2a26ad62a5c155af9199af9e69b889claireho 88627f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------------* 88727f654740f2a26ad62a5c155af9199af9e69b889claireho * * 88827f654740f2a26ad62a5c155af9199af9e69b889claireho * checkDataItem Given a freshly located/loaded data item, either * 88927f654740f2a26ad62a5c155af9199af9e69b889claireho * an entry in a common file or a separately loaded file, * 89027f654740f2a26ad62a5c155af9199af9e69b889claireho * sanity check its header, and see if the data is * 89127f654740f2a26ad62a5c155af9199af9e69b889claireho * acceptable to the app. * 89227f654740f2a26ad62a5c155af9199af9e69b889claireho * If the data is good, create and return a UDataMemory * 89327f654740f2a26ad62a5c155af9199af9e69b889claireho * object that can be returned to the application. * 89427f654740f2a26ad62a5c155af9199af9e69b889claireho * Return NULL on any sort of failure. * 89527f654740f2a26ad62a5c155af9199af9e69b889claireho * * 89627f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------------*/ 89727f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory * 89827f654740f2a26ad62a5c155af9199af9e69b889clairehocheckDataItem 89927f654740f2a26ad62a5c155af9199af9e69b889claireho( 90027f654740f2a26ad62a5c155af9199af9e69b889claireho const DataHeader *pHeader, /* The data item to be checked. */ 90127f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemoryIsAcceptable *isAcceptable, /* App's call-back function */ 90227f654740f2a26ad62a5c155af9199af9e69b889claireho void *context, /* pass-thru param for above. */ 90327f654740f2a26ad62a5c155af9199af9e69b889claireho const char *type, /* pass-thru param for above. */ 90427f654740f2a26ad62a5c155af9199af9e69b889claireho const char *name, /* pass-thru param for above. */ 90527f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *nonFatalErr, /* Error code if this data was not acceptable */ 90627f654740f2a26ad62a5c155af9199af9e69b889claireho /* but openChoice should continue with */ 90727f654740f2a26ad62a5c155af9199af9e69b889claireho /* trying to get data from fallback path. */ 90827f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *fatalErr /* Bad error, caller should return immediately */ 90927f654740f2a26ad62a5c155af9199af9e69b889claireho ) 91027f654740f2a26ad62a5c155af9199af9e69b889claireho{ 91127f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *rDataMem = NULL; /* the new UDataMemory, to be returned. */ 91227f654740f2a26ad62a5c155af9199af9e69b889claireho 91327f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*fatalErr)) { 91427f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 91527f654740f2a26ad62a5c155af9199af9e69b889claireho } 91627f654740f2a26ad62a5c155af9199af9e69b889claireho 91727f654740f2a26ad62a5c155af9199af9e69b889claireho if(pHeader->dataHeader.magic1==0xda && 91827f654740f2a26ad62a5c155af9199af9e69b889claireho pHeader->dataHeader.magic2==0x27 && 91927f654740f2a26ad62a5c155af9199af9e69b889claireho (isAcceptable==NULL || isAcceptable(context, type, name, &pHeader->info)) 92027f654740f2a26ad62a5c155af9199af9e69b889claireho ) { 92127f654740f2a26ad62a5c155af9199af9e69b889claireho rDataMem=UDataMemory_createNewInstance(fatalErr); 92227f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*fatalErr)) { 92327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 92427f654740f2a26ad62a5c155af9199af9e69b889claireho } 92527f654740f2a26ad62a5c155af9199af9e69b889claireho rDataMem->pHeader = pHeader; 92627f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 92727f654740f2a26ad62a5c155af9199af9e69b889claireho /* the data is not acceptable, look further */ 92827f654740f2a26ad62a5c155af9199af9e69b889claireho /* If we eventually find something good, this errorcode will be */ 92927f654740f2a26ad62a5c155af9199af9e69b889claireho /* cleared out. */ 93027f654740f2a26ad62a5c155af9199af9e69b889claireho *nonFatalErr=U_INVALID_FORMAT_ERROR; 93127f654740f2a26ad62a5c155af9199af9e69b889claireho } 93227f654740f2a26ad62a5c155af9199af9e69b889claireho return rDataMem; 93327f654740f2a26ad62a5c155af9199af9e69b889claireho} 93427f654740f2a26ad62a5c155af9199af9e69b889claireho 93527f654740f2a26ad62a5c155af9199af9e69b889claireho/** 93627f654740f2a26ad62a5c155af9199af9e69b889claireho * @return 0 if not loaded, 1 if loaded or err 93727f654740f2a26ad62a5c155af9199af9e69b889claireho */ 93827f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory *doLoadFromIndividualFiles(const char *pkgName, 93927f654740f2a26ad62a5c155af9199af9e69b889claireho const char *dataPath, const char *tocEntryPathSuffix, 94027f654740f2a26ad62a5c155af9199af9e69b889claireho /* following arguments are the same as doOpenChoice itself */ 94127f654740f2a26ad62a5c155af9199af9e69b889claireho const char *path, const char *type, const char *name, 94227f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemoryIsAcceptable *isAcceptable, void *context, 94327f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *subErrorCode, 94427f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) 94527f654740f2a26ad62a5c155af9199af9e69b889claireho{ 94627f654740f2a26ad62a5c155af9199af9e69b889claireho const char *pathBuffer; 94727f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory dataMemory; 94827f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *pEntryData; 94927f654740f2a26ad62a5c155af9199af9e69b889claireho 95027f654740f2a26ad62a5c155af9199af9e69b889claireho /* look in ind. files: package\nam.typ ========================= */ 95127f654740f2a26ad62a5c155af9199af9e69b889claireho /* init path iterator for individual files */ 95227f654740f2a26ad62a5c155af9199af9e69b889claireho UDataPathIterator iter(dataPath, pkgName, path, tocEntryPathSuffix, FALSE, pErrorCode); 95327f654740f2a26ad62a5c155af9199af9e69b889claireho 95427f654740f2a26ad62a5c155af9199af9e69b889claireho while((pathBuffer = iter.next(pErrorCode))) 95527f654740f2a26ad62a5c155af9199af9e69b889claireho { 95627f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 95727f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "UDATA: trying individual file %s\n", pathBuffer); 95827f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 95927f654740f2a26ad62a5c155af9199af9e69b889claireho if(uprv_mapFile(&dataMemory, pathBuffer)) 96027f654740f2a26ad62a5c155af9199af9e69b889claireho { 96127f654740f2a26ad62a5c155af9199af9e69b889claireho pEntryData = checkDataItem(dataMemory.pHeader, isAcceptable, context, type, name, subErrorCode, pErrorCode); 96227f654740f2a26ad62a5c155af9199af9e69b889claireho if (pEntryData != NULL) { 96327f654740f2a26ad62a5c155af9199af9e69b889claireho /* Data is good. 96427f654740f2a26ad62a5c155af9199af9e69b889claireho * Hand off ownership of the backing memory to the user's UDataMemory. 96527f654740f2a26ad62a5c155af9199af9e69b889claireho * and return it. */ 96627f654740f2a26ad62a5c155af9199af9e69b889claireho pEntryData->mapAddr = dataMemory.mapAddr; 96727f654740f2a26ad62a5c155af9199af9e69b889claireho pEntryData->map = dataMemory.map; 96827f654740f2a26ad62a5c155af9199af9e69b889claireho 96927f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 97027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "** Mapped file: %s\n", pathBuffer); 97127f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 97227f654740f2a26ad62a5c155af9199af9e69b889claireho return pEntryData; 97327f654740f2a26ad62a5c155af9199af9e69b889claireho } 97427f654740f2a26ad62a5c155af9199af9e69b889claireho 97527f654740f2a26ad62a5c155af9199af9e69b889claireho /* the data is not acceptable, or some error occured. Either way, unmap the memory */ 97627f654740f2a26ad62a5c155af9199af9e69b889claireho udata_close(&dataMemory); 97727f654740f2a26ad62a5c155af9199af9e69b889claireho 97827f654740f2a26ad62a5c155af9199af9e69b889claireho /* If we had a nasty error, bail out completely. */ 97927f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErrorCode)) { 98027f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 98127f654740f2a26ad62a5c155af9199af9e69b889claireho } 98227f654740f2a26ad62a5c155af9199af9e69b889claireho 98327f654740f2a26ad62a5c155af9199af9e69b889claireho /* Otherwise remember that we found data but didn't like it for some reason */ 98427f654740f2a26ad62a5c155af9199af9e69b889claireho *subErrorCode=U_INVALID_FORMAT_ERROR; 98527f654740f2a26ad62a5c155af9199af9e69b889claireho } 98627f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 98727f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "%s\n", UDataMemory_isLoaded(&dataMemory)?"LOADED":"not loaded"); 98827f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 98927f654740f2a26ad62a5c155af9199af9e69b889claireho } 99027f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 99127f654740f2a26ad62a5c155af9199af9e69b889claireho} 99227f654740f2a26ad62a5c155af9199af9e69b889claireho 99327f654740f2a26ad62a5c155af9199af9e69b889claireho/** 99427f654740f2a26ad62a5c155af9199af9e69b889claireho * @return 0 if not loaded, 1 if loaded or err 99527f654740f2a26ad62a5c155af9199af9e69b889claireho */ 99627f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory *doLoadFromCommonData(UBool isICUData, const char * /*pkgName*/, 99727f654740f2a26ad62a5c155af9199af9e69b889claireho const char * /*dataPath*/, const char * /*tocEntryPathSuffix*/, const char *tocEntryName, 99827f654740f2a26ad62a5c155af9199af9e69b889claireho /* following arguments are the same as doOpenChoice itself */ 99927f654740f2a26ad62a5c155af9199af9e69b889claireho const char *path, const char *type, const char *name, 100027f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemoryIsAcceptable *isAcceptable, void *context, 100127f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *subErrorCode, 100227f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) 100327f654740f2a26ad62a5c155af9199af9e69b889claireho{ 100427f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *pEntryData; 100527f654740f2a26ad62a5c155af9199af9e69b889claireho const DataHeader *pHeader; 100627f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *pCommonData; 100727f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t commonDataIndex; 1008b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool checkedExtendedICUData = FALSE; 100927f654740f2a26ad62a5c155af9199af9e69b889claireho /* try to get common data. The loop is for platforms such as the 390 that do 101027f654740f2a26ad62a5c155af9199af9e69b889claireho * not initially load the full set of ICU data. If the lookup of an ICU data item 101127f654740f2a26ad62a5c155af9199af9e69b889claireho * fails, the full (but slower to load) set is loaded, the and the loop repeats, 101227f654740f2a26ad62a5c155af9199af9e69b889claireho * trying the lookup again. Once the full set of ICU data is loaded, the loop wont 101327f654740f2a26ad62a5c155af9199af9e69b889claireho * repeat because the full set will be checked the first time through. 101427f654740f2a26ad62a5c155af9199af9e69b889claireho * 101527f654740f2a26ad62a5c155af9199af9e69b889claireho * The loop also handles the fallback to a .dat file if the application linked 101627f654740f2a26ad62a5c155af9199af9e69b889claireho * to the stub data library rather than a real library. 101727f654740f2a26ad62a5c155af9199af9e69b889claireho */ 101827f654740f2a26ad62a5c155af9199af9e69b889claireho for (commonDataIndex = isICUData ? 0 : -1;;) { 101927f654740f2a26ad62a5c155af9199af9e69b889claireho pCommonData=openCommonData(path, commonDataIndex, subErrorCode); /** search for pkg **/ 102027f654740f2a26ad62a5c155af9199af9e69b889claireho 102127f654740f2a26ad62a5c155af9199af9e69b889claireho if(U_SUCCESS(*subErrorCode) && pCommonData!=NULL) { 102227f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t length; 102327f654740f2a26ad62a5c155af9199af9e69b889claireho 102427f654740f2a26ad62a5c155af9199af9e69b889claireho /* look up the data piece in the common data */ 102527f654740f2a26ad62a5c155af9199af9e69b889claireho pHeader=pCommonData->vFuncs->Lookup(pCommonData, tocEntryName, &length, subErrorCode); 102627f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 102727f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "%s: pHeader=%p - %s\n", tocEntryName, pHeader, u_errorName(*subErrorCode)); 102827f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 102927f654740f2a26ad62a5c155af9199af9e69b889claireho 103027f654740f2a26ad62a5c155af9199af9e69b889claireho if(pHeader!=NULL) { 103127f654740f2a26ad62a5c155af9199af9e69b889claireho pEntryData = checkDataItem(pHeader, isAcceptable, context, type, name, subErrorCode, pErrorCode); 103227f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 103327f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "pEntryData=%p\n", pEntryData); 103427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 103527f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(*pErrorCode)) { 103627f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 103727f654740f2a26ad62a5c155af9199af9e69b889claireho } 103827f654740f2a26ad62a5c155af9199af9e69b889claireho if (pEntryData != NULL) { 103927f654740f2a26ad62a5c155af9199af9e69b889claireho pEntryData->length = length; 104027f654740f2a26ad62a5c155af9199af9e69b889claireho return pEntryData; 104127f654740f2a26ad62a5c155af9199af9e69b889claireho } 104227f654740f2a26ad62a5c155af9199af9e69b889claireho } 104327f654740f2a26ad62a5c155af9199af9e69b889claireho } 104427f654740f2a26ad62a5c155af9199af9e69b889claireho /* Data wasn't found. If we were looking for an ICUData item and there is 104527f654740f2a26ad62a5c155af9199af9e69b889claireho * more data available, load it and try again, 104627f654740f2a26ad62a5c155af9199af9e69b889claireho * otherwise break out of this loop. */ 104727f654740f2a26ad62a5c155af9199af9e69b889claireho if (!isICUData) { 104827f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 104927f654740f2a26ad62a5c155af9199af9e69b889claireho } else if (pCommonData != NULL) { 105027f654740f2a26ad62a5c155af9199af9e69b889claireho ++commonDataIndex; /* try the next data package */ 1051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if ((!checkedExtendedICUData) && extendICUData(subErrorCode)) { 1052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho checkedExtendedICUData = TRUE; 105327f654740f2a26ad62a5c155af9199af9e69b889claireho /* try this data package slot again: it changed from NULL to non-NULL */ 105427f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 105527f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 105627f654740f2a26ad62a5c155af9199af9e69b889claireho } 105727f654740f2a26ad62a5c155af9199af9e69b889claireho } 105827f654740f2a26ad62a5c155af9199af9e69b889claireho} 105927f654740f2a26ad62a5c155af9199af9e69b889claireho 106027f654740f2a26ad62a5c155af9199af9e69b889claireho/* 106127f654740f2a26ad62a5c155af9199af9e69b889claireho * A note on the ownership of Mapped Memory 106227f654740f2a26ad62a5c155af9199af9e69b889claireho * 106327f654740f2a26ad62a5c155af9199af9e69b889claireho * For common format files, ownership resides with the UDataMemory object 106427f654740f2a26ad62a5c155af9199af9e69b889claireho * that lives in the cache of opened common data. These UDataMemorys are private 106527f654740f2a26ad62a5c155af9199af9e69b889claireho * to the udata implementation, and are never seen directly by users. 106627f654740f2a26ad62a5c155af9199af9e69b889claireho * 106727f654740f2a26ad62a5c155af9199af9e69b889claireho * The UDataMemory objects returned to users will have the address of some desired 106827f654740f2a26ad62a5c155af9199af9e69b889claireho * data within the mapped region, but they wont have the mapping info itself, and thus 106927f654740f2a26ad62a5c155af9199af9e69b889claireho * won't cause anything to be removed from memory when they are closed. 107027f654740f2a26ad62a5c155af9199af9e69b889claireho * 107127f654740f2a26ad62a5c155af9199af9e69b889claireho * For individual data files, the UDataMemory returned to the user holds the 107227f654740f2a26ad62a5c155af9199af9e69b889claireho * information necessary to unmap the data on close. If the user independently 107327f654740f2a26ad62a5c155af9199af9e69b889claireho * opens the same data file twice, two completely independent mappings will be made. 107427f654740f2a26ad62a5c155af9199af9e69b889claireho * (There is no cache of opened data items from individual files, only a cache of 107527f654740f2a26ad62a5c155af9199af9e69b889claireho * opened Common Data files, that is, files containing a collection of data items.) 107627f654740f2a26ad62a5c155af9199af9e69b889claireho * 107727f654740f2a26ad62a5c155af9199af9e69b889claireho * For common data passed in from the user via udata_setAppData() or 107827f654740f2a26ad62a5c155af9199af9e69b889claireho * udata_setCommonData(), ownership remains with the user. 107927f654740f2a26ad62a5c155af9199af9e69b889claireho * 108027f654740f2a26ad62a5c155af9199af9e69b889claireho * UDataMemory objects themselves, as opposed to the memory they describe, 108127f654740f2a26ad62a5c155af9199af9e69b889claireho * can be anywhere - heap, stack/local or global. 108227f654740f2a26ad62a5c155af9199af9e69b889claireho * They have a flag to indicate when they're heap allocated and thus 108327f654740f2a26ad62a5c155af9199af9e69b889claireho * must be deleted when closed. 108427f654740f2a26ad62a5c155af9199af9e69b889claireho */ 108527f654740f2a26ad62a5c155af9199af9e69b889claireho 108627f654740f2a26ad62a5c155af9199af9e69b889claireho 108727f654740f2a26ad62a5c155af9199af9e69b889claireho/*----------------------------------------------------------------------------* 108827f654740f2a26ad62a5c155af9199af9e69b889claireho * * 108927f654740f2a26ad62a5c155af9199af9e69b889claireho * main data loading functions * 109027f654740f2a26ad62a5c155af9199af9e69b889claireho * * 109127f654740f2a26ad62a5c155af9199af9e69b889claireho *----------------------------------------------------------------------------*/ 109227f654740f2a26ad62a5c155af9199af9e69b889clairehostatic UDataMemory * 109327f654740f2a26ad62a5c155af9199af9e69b889clairehodoOpenChoice(const char *path, const char *type, const char *name, 109427f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemoryIsAcceptable *isAcceptable, void *context, 109527f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) 109627f654740f2a26ad62a5c155af9199af9e69b889claireho{ 109727f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemory *retVal = NULL; 109827f654740f2a26ad62a5c155af9199af9e69b889claireho 109927f654740f2a26ad62a5c155af9199af9e69b889claireho const char *dataPath; 110027f654740f2a26ad62a5c155af9199af9e69b889claireho 110127f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t tocEntrySuffixIndex; 110227f654740f2a26ad62a5c155af9199af9e69b889claireho const char *tocEntryPathSuffix; 110327f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode subErrorCode=U_ZERO_ERROR; 110427f654740f2a26ad62a5c155af9199af9e69b889claireho const char *treeChar; 110527f654740f2a26ad62a5c155af9199af9e69b889claireho 110627f654740f2a26ad62a5c155af9199af9e69b889claireho UBool isICUData = FALSE; 110727f654740f2a26ad62a5c155af9199af9e69b889claireho 110827f654740f2a26ad62a5c155af9199af9e69b889claireho 110927f654740f2a26ad62a5c155af9199af9e69b889claireho /* Is this path ICU data? */ 111027f654740f2a26ad62a5c155af9199af9e69b889claireho if(path == NULL || 111127f654740f2a26ad62a5c155af9199af9e69b889claireho !strcmp(path, U_ICUDATA_ALIAS) || /* "ICUDATA" */ 111227f654740f2a26ad62a5c155af9199af9e69b889claireho !uprv_strncmp(path, U_ICUDATA_NAME U_TREE_SEPARATOR_STRING, /* "icudt26e-" */ 111327f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strlen(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING)) || 111427f654740f2a26ad62a5c155af9199af9e69b889claireho !uprv_strncmp(path, U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING, /* "ICUDATA-" */ 111527f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_strlen(U_ICUDATA_ALIAS U_TREE_SEPARATOR_STRING))) { 111627f654740f2a26ad62a5c155af9199af9e69b889claireho isICUData = TRUE; 111727f654740f2a26ad62a5c155af9199af9e69b889claireho } 111827f654740f2a26ad62a5c155af9199af9e69b889claireho 111927f654740f2a26ad62a5c155af9199af9e69b889claireho#if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR) /* Windows: try "foo\bar" and "foo/bar" */ 112027f654740f2a26ad62a5c155af9199af9e69b889claireho /* remap from alternate path char to the main one */ 112127f654740f2a26ad62a5c155af9199af9e69b889claireho CharString altSepPath; 112227f654740f2a26ad62a5c155af9199af9e69b889claireho if(path) { 112327f654740f2a26ad62a5c155af9199af9e69b889claireho if(uprv_strchr(path,U_FILE_ALT_SEP_CHAR) != NULL) { 112427f654740f2a26ad62a5c155af9199af9e69b889claireho altSepPath.append(path, *pErrorCode); 112527f654740f2a26ad62a5c155af9199af9e69b889claireho char *p; 112627f654740f2a26ad62a5c155af9199af9e69b889claireho while((p=uprv_strchr(altSepPath.data(), U_FILE_ALT_SEP_CHAR))) { 112727f654740f2a26ad62a5c155af9199af9e69b889claireho *p = U_FILE_SEP_CHAR; 112827f654740f2a26ad62a5c155af9199af9e69b889claireho } 112927f654740f2a26ad62a5c155af9199af9e69b889claireho#if defined (UDATA_DEBUG) 113027f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Changed path from [%s] to [%s]\n", path, altSepPath.s); 113127f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 113227f654740f2a26ad62a5c155af9199af9e69b889claireho path = altSepPath.data(); 113327f654740f2a26ad62a5c155af9199af9e69b889claireho } 113427f654740f2a26ad62a5c155af9199af9e69b889claireho } 113527f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 113627f654740f2a26ad62a5c155af9199af9e69b889claireho 113727f654740f2a26ad62a5c155af9199af9e69b889claireho CharString tocEntryName; /* entry name in tree format. ex: 'icudt28b/coll/ar.res' */ 113827f654740f2a26ad62a5c155af9199af9e69b889claireho CharString tocEntryPath; /* entry name in path format. ex: 'icudt28b\\coll\\ar.res' */ 113927f654740f2a26ad62a5c155af9199af9e69b889claireho 114027f654740f2a26ad62a5c155af9199af9e69b889claireho CharString pkgName; 114127f654740f2a26ad62a5c155af9199af9e69b889claireho CharString treeName; 114227f654740f2a26ad62a5c155af9199af9e69b889claireho 114327f654740f2a26ad62a5c155af9199af9e69b889claireho /* ======= Set up strings */ 114427f654740f2a26ad62a5c155af9199af9e69b889claireho if(path==NULL) { 114527f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(U_ICUDATA_NAME, *pErrorCode); 114627f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 114727f654740f2a26ad62a5c155af9199af9e69b889claireho const char *pkg; 114827f654740f2a26ad62a5c155af9199af9e69b889claireho const char *first; 114927f654740f2a26ad62a5c155af9199af9e69b889claireho pkg = uprv_strrchr(path, U_FILE_SEP_CHAR); 115027f654740f2a26ad62a5c155af9199af9e69b889claireho first = uprv_strchr(path, U_FILE_SEP_CHAR); 115127f654740f2a26ad62a5c155af9199af9e69b889claireho if(uprv_pathIsAbsolute(path) || (pkg != first)) { /* more than one slash in the path- not a tree name */ 115227f654740f2a26ad62a5c155af9199af9e69b889claireho /* see if this is an /absolute/path/to/package path */ 115327f654740f2a26ad62a5c155af9199af9e69b889claireho if(pkg) { 115427f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(pkg+1, *pErrorCode); 115527f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 115627f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(path, *pErrorCode); 115727f654740f2a26ad62a5c155af9199af9e69b889claireho } 115827f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 115927f654740f2a26ad62a5c155af9199af9e69b889claireho treeChar = uprv_strchr(path, U_TREE_SEPARATOR); 116027f654740f2a26ad62a5c155af9199af9e69b889claireho if(treeChar) { 116127f654740f2a26ad62a5c155af9199af9e69b889claireho treeName.append(treeChar+1, *pErrorCode); /* following '-' */ 116227f654740f2a26ad62a5c155af9199af9e69b889claireho if(isICUData) { 116327f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(U_ICUDATA_NAME, *pErrorCode); 116427f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 116527f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(path, (int32_t)(treeChar-path), *pErrorCode); 116627f654740f2a26ad62a5c155af9199af9e69b889claireho if (first == NULL) { 116727f654740f2a26ad62a5c155af9199af9e69b889claireho /* 116827f654740f2a26ad62a5c155af9199af9e69b889claireho This user data has no path, but there is a tree name. 116927f654740f2a26ad62a5c155af9199af9e69b889claireho Look up the correct path from the data cache later. 117027f654740f2a26ad62a5c155af9199af9e69b889claireho */ 117127f654740f2a26ad62a5c155af9199af9e69b889claireho path = pkgName.data(); 117227f654740f2a26ad62a5c155af9199af9e69b889claireho } 117327f654740f2a26ad62a5c155af9199af9e69b889claireho } 117427f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 117527f654740f2a26ad62a5c155af9199af9e69b889claireho if(isICUData) { 117627f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(U_ICUDATA_NAME, *pErrorCode); 117727f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 117827f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.append(path, *pErrorCode); 117927f654740f2a26ad62a5c155af9199af9e69b889claireho } 118027f654740f2a26ad62a5c155af9199af9e69b889claireho } 118127f654740f2a26ad62a5c155af9199af9e69b889claireho } 118227f654740f2a26ad62a5c155af9199af9e69b889claireho } 118327f654740f2a26ad62a5c155af9199af9e69b889claireho 118427f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 118527f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, " P=%s T=%s\n", pkgName.data(), treeName.data()); 118627f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 118727f654740f2a26ad62a5c155af9199af9e69b889claireho 118827f654740f2a26ad62a5c155af9199af9e69b889claireho /* setting up the entry name and file name 118927f654740f2a26ad62a5c155af9199af9e69b889claireho * Make up a full name by appending the type to the supplied 119027f654740f2a26ad62a5c155af9199af9e69b889claireho * name, assuming that a type was supplied. 119127f654740f2a26ad62a5c155af9199af9e69b889claireho */ 119227f654740f2a26ad62a5c155af9199af9e69b889claireho 119327f654740f2a26ad62a5c155af9199af9e69b889claireho /* prepend the package */ 119427f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryName.append(pkgName, *pErrorCode); 119527f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryPath.append(pkgName, *pErrorCode); 119627f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntrySuffixIndex = tocEntryName.length(); 119727f654740f2a26ad62a5c155af9199af9e69b889claireho 119827f654740f2a26ad62a5c155af9199af9e69b889claireho if(!treeName.isEmpty()) { 119927f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryName.append(U_TREE_ENTRY_SEP_CHAR, *pErrorCode).append(treeName, *pErrorCode); 120027f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryPath.append(U_FILE_SEP_CHAR, *pErrorCode).append(treeName, *pErrorCode); 120127f654740f2a26ad62a5c155af9199af9e69b889claireho } 120227f654740f2a26ad62a5c155af9199af9e69b889claireho 120327f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryName.append(U_TREE_ENTRY_SEP_CHAR, *pErrorCode).append(name, *pErrorCode); 120427f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryPath.append(U_FILE_SEP_CHAR, *pErrorCode).append(name, *pErrorCode); 120527f654740f2a26ad62a5c155af9199af9e69b889claireho if(type!=NULL && *type!=0) { 120627f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryName.append(".", *pErrorCode).append(type, *pErrorCode); 120727f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryPath.append(".", *pErrorCode).append(type, *pErrorCode); 120827f654740f2a26ad62a5c155af9199af9e69b889claireho } 120927f654740f2a26ad62a5c155af9199af9e69b889claireho tocEntryPathSuffix = tocEntryPath.data()+tocEntrySuffixIndex; /* suffix starts here */ 121027f654740f2a26ad62a5c155af9199af9e69b889claireho 121127f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 121227f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, " tocEntryName = %s\n", tocEntryName.data()); 121327f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, " tocEntryPath = %s\n", tocEntryName.data()); 121427f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 121527f654740f2a26ad62a5c155af9199af9e69b889claireho 121627f654740f2a26ad62a5c155af9199af9e69b889claireho if(path == NULL) { 121727f654740f2a26ad62a5c155af9199af9e69b889claireho path = COMMON_DATA_NAME; /* "icudt26e" */ 121827f654740f2a26ad62a5c155af9199af9e69b889claireho } 121927f654740f2a26ad62a5c155af9199af9e69b889claireho 122027f654740f2a26ad62a5c155af9199af9e69b889claireho /************************ Begin loop looking for ind. files ***************/ 122127f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 122227f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "IND: inBasename = %s, pkg=%s\n", "(n/a)", packageNameFromPath(path)); 122327f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 122427f654740f2a26ad62a5c155af9199af9e69b889claireho 122527f654740f2a26ad62a5c155af9199af9e69b889claireho /* End of dealing with a null basename */ 122627f654740f2a26ad62a5c155af9199af9e69b889claireho dataPath = u_getDataDirectory(); 122727f654740f2a26ad62a5c155af9199af9e69b889claireho 122827f654740f2a26ad62a5c155af9199af9e69b889claireho /**** COMMON PACKAGE - only if packages are first. */ 122927f654740f2a26ad62a5c155af9199af9e69b889claireho if(gDataFileAccess == UDATA_PACKAGES_FIRST) { 123027f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 123127f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Trying packages (UDATA_PACKAGES_FIRST)\n"); 123227f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 123327f654740f2a26ad62a5c155af9199af9e69b889claireho /* #2 */ 123427f654740f2a26ad62a5c155af9199af9e69b889claireho retVal = doLoadFromCommonData(isICUData, 123527f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.data(), dataPath, tocEntryPathSuffix, tocEntryName.data(), 123627f654740f2a26ad62a5c155af9199af9e69b889claireho path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); 123727f654740f2a26ad62a5c155af9199af9e69b889claireho if((retVal != NULL) || U_FAILURE(*pErrorCode)) { 123827f654740f2a26ad62a5c155af9199af9e69b889claireho return retVal; 123927f654740f2a26ad62a5c155af9199af9e69b889claireho } 124027f654740f2a26ad62a5c155af9199af9e69b889claireho } 124127f654740f2a26ad62a5c155af9199af9e69b889claireho 124227f654740f2a26ad62a5c155af9199af9e69b889claireho /**** INDIVIDUAL FILES */ 124327f654740f2a26ad62a5c155af9199af9e69b889claireho if((gDataFileAccess==UDATA_PACKAGES_FIRST) || 124427f654740f2a26ad62a5c155af9199af9e69b889claireho (gDataFileAccess==UDATA_FILES_FIRST)) { 124527f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 124627f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Trying individual files\n"); 124727f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 124827f654740f2a26ad62a5c155af9199af9e69b889claireho /* Check to make sure that there is a dataPath to iterate over */ 124927f654740f2a26ad62a5c155af9199af9e69b889claireho if ((dataPath && *dataPath) || !isICUData) { 125027f654740f2a26ad62a5c155af9199af9e69b889claireho retVal = doLoadFromIndividualFiles(pkgName.data(), dataPath, tocEntryPathSuffix, 125127f654740f2a26ad62a5c155af9199af9e69b889claireho path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); 125227f654740f2a26ad62a5c155af9199af9e69b889claireho if((retVal != NULL) || U_FAILURE(*pErrorCode)) { 125327f654740f2a26ad62a5c155af9199af9e69b889claireho return retVal; 125427f654740f2a26ad62a5c155af9199af9e69b889claireho } 125527f654740f2a26ad62a5c155af9199af9e69b889claireho } 125627f654740f2a26ad62a5c155af9199af9e69b889claireho } 125727f654740f2a26ad62a5c155af9199af9e69b889claireho 125827f654740f2a26ad62a5c155af9199af9e69b889claireho /**** COMMON PACKAGE */ 125927f654740f2a26ad62a5c155af9199af9e69b889claireho if((gDataFileAccess==UDATA_ONLY_PACKAGES) || 126027f654740f2a26ad62a5c155af9199af9e69b889claireho (gDataFileAccess==UDATA_FILES_FIRST)) { 126127f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 126227f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Trying packages (UDATA_ONLY_PACKAGES || UDATA_FILES_FIRST)\n"); 126327f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 126427f654740f2a26ad62a5c155af9199af9e69b889claireho retVal = doLoadFromCommonData(isICUData, 126527f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.data(), dataPath, tocEntryPathSuffix, tocEntryName.data(), 126627f654740f2a26ad62a5c155af9199af9e69b889claireho path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); 126727f654740f2a26ad62a5c155af9199af9e69b889claireho if((retVal != NULL) || U_FAILURE(*pErrorCode)) { 126827f654740f2a26ad62a5c155af9199af9e69b889claireho return retVal; 126927f654740f2a26ad62a5c155af9199af9e69b889claireho } 127027f654740f2a26ad62a5c155af9199af9e69b889claireho } 127127f654740f2a26ad62a5c155af9199af9e69b889claireho 127227f654740f2a26ad62a5c155af9199af9e69b889claireho /* Load from DLL. If we haven't attempted package load, we also haven't had any chance to 127327f654740f2a26ad62a5c155af9199af9e69b889claireho try a DLL (static or setCommonData/etc) load. 127427f654740f2a26ad62a5c155af9199af9e69b889claireho If we ever have a "UDATA_ONLY_FILES", add it to the or list here. */ 127527f654740f2a26ad62a5c155af9199af9e69b889claireho if(gDataFileAccess==UDATA_NO_FILES) { 127627f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 127727f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "Trying common data (UDATA_NO_FILES)\n"); 127827f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 127927f654740f2a26ad62a5c155af9199af9e69b889claireho retVal = doLoadFromCommonData(isICUData, 128027f654740f2a26ad62a5c155af9199af9e69b889claireho pkgName.data(), "", tocEntryPathSuffix, tocEntryName.data(), 128127f654740f2a26ad62a5c155af9199af9e69b889claireho path, type, name, isAcceptable, context, &subErrorCode, pErrorCode); 128227f654740f2a26ad62a5c155af9199af9e69b889claireho if((retVal != NULL) || U_FAILURE(*pErrorCode)) { 128327f654740f2a26ad62a5c155af9199af9e69b889claireho return retVal; 128427f654740f2a26ad62a5c155af9199af9e69b889claireho } 128527f654740f2a26ad62a5c155af9199af9e69b889claireho } 128627f654740f2a26ad62a5c155af9199af9e69b889claireho 128727f654740f2a26ad62a5c155af9199af9e69b889claireho /* data not found */ 128827f654740f2a26ad62a5c155af9199af9e69b889claireho if(U_SUCCESS(*pErrorCode)) { 128927f654740f2a26ad62a5c155af9199af9e69b889claireho if(U_SUCCESS(subErrorCode)) { 129027f654740f2a26ad62a5c155af9199af9e69b889claireho /* file not found */ 129127f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=U_FILE_ACCESS_ERROR; 129227f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 129327f654740f2a26ad62a5c155af9199af9e69b889claireho /* entry point not found or rejected */ 129427f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=subErrorCode; 129527f654740f2a26ad62a5c155af9199af9e69b889claireho } 129627f654740f2a26ad62a5c155af9199af9e69b889claireho } 129727f654740f2a26ad62a5c155af9199af9e69b889claireho return retVal; 129827f654740f2a26ad62a5c155af9199af9e69b889claireho} 129927f654740f2a26ad62a5c155af9199af9e69b889claireho 130027f654740f2a26ad62a5c155af9199af9e69b889claireho 130127f654740f2a26ad62a5c155af9199af9e69b889claireho 130227f654740f2a26ad62a5c155af9199af9e69b889claireho/* API ---------------------------------------------------------------------- */ 130327f654740f2a26ad62a5c155af9199af9e69b889claireho 130427f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI UDataMemory * U_EXPORT2 130527f654740f2a26ad62a5c155af9199af9e69b889clairehoudata_open(const char *path, const char *type, const char *name, 130627f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) { 130727f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 130827f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "udata_open(): Opening: %s : %s . %s\n", (path?path:"NULL"), name, type); 130927f654740f2a26ad62a5c155af9199af9e69b889claireho fflush(stderr); 131027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 131127f654740f2a26ad62a5c155af9199af9e69b889claireho 131227f654740f2a26ad62a5c155af9199af9e69b889claireho if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 131327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 131427f654740f2a26ad62a5c155af9199af9e69b889claireho } else if(name==NULL || *name==0) { 131527f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 131627f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 131727f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 131827f654740f2a26ad62a5c155af9199af9e69b889claireho return doOpenChoice(path, type, name, NULL, NULL, pErrorCode); 131927f654740f2a26ad62a5c155af9199af9e69b889claireho } 132027f654740f2a26ad62a5c155af9199af9e69b889claireho} 132127f654740f2a26ad62a5c155af9199af9e69b889claireho 132227f654740f2a26ad62a5c155af9199af9e69b889claireho 132327f654740f2a26ad62a5c155af9199af9e69b889claireho 132427f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI UDataMemory * U_EXPORT2 132527f654740f2a26ad62a5c155af9199af9e69b889clairehoudata_openChoice(const char *path, const char *type, const char *name, 132627f654740f2a26ad62a5c155af9199af9e69b889claireho UDataMemoryIsAcceptable *isAcceptable, void *context, 132727f654740f2a26ad62a5c155af9199af9e69b889claireho UErrorCode *pErrorCode) { 132827f654740f2a26ad62a5c155af9199af9e69b889claireho#ifdef UDATA_DEBUG 132927f654740f2a26ad62a5c155af9199af9e69b889claireho fprintf(stderr, "udata_openChoice(): Opening: %s : %s . %s\n", (path?path:"NULL"), name, type); 133027f654740f2a26ad62a5c155af9199af9e69b889claireho#endif 133127f654740f2a26ad62a5c155af9199af9e69b889claireho 133227f654740f2a26ad62a5c155af9199af9e69b889claireho if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 133327f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 133427f654740f2a26ad62a5c155af9199af9e69b889claireho } else if(name==NULL || *name==0 || isAcceptable==NULL) { 133527f654740f2a26ad62a5c155af9199af9e69b889claireho *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 133627f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 133727f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 133827f654740f2a26ad62a5c155af9199af9e69b889claireho return doOpenChoice(path, type, name, isAcceptable, context, pErrorCode); 133927f654740f2a26ad62a5c155af9199af9e69b889claireho } 134027f654740f2a26ad62a5c155af9199af9e69b889claireho} 134127f654740f2a26ad62a5c155af9199af9e69b889claireho 134227f654740f2a26ad62a5c155af9199af9e69b889claireho 134327f654740f2a26ad62a5c155af9199af9e69b889claireho 134427f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI void U_EXPORT2 134527f654740f2a26ad62a5c155af9199af9e69b889clairehoudata_getInfo(UDataMemory *pData, UDataInfo *pInfo) { 134627f654740f2a26ad62a5c155af9199af9e69b889claireho if(pInfo!=NULL) { 134727f654740f2a26ad62a5c155af9199af9e69b889claireho if(pData!=NULL && pData->pHeader!=NULL) { 134827f654740f2a26ad62a5c155af9199af9e69b889claireho const UDataInfo *info=&pData->pHeader->info; 134927f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t dataInfoSize=udata_getInfoSize(info); 135027f654740f2a26ad62a5c155af9199af9e69b889claireho if(pInfo->size>dataInfoSize) { 135127f654740f2a26ad62a5c155af9199af9e69b889claireho pInfo->size=dataInfoSize; 135227f654740f2a26ad62a5c155af9199af9e69b889claireho } 135327f654740f2a26ad62a5c155af9199af9e69b889claireho uprv_memcpy((uint16_t *)pInfo+1, (const uint16_t *)info+1, pInfo->size-2); 135427f654740f2a26ad62a5c155af9199af9e69b889claireho if(info->isBigEndian!=U_IS_BIG_ENDIAN) { 135527f654740f2a26ad62a5c155af9199af9e69b889claireho /* opposite endianness */ 135627f654740f2a26ad62a5c155af9199af9e69b889claireho uint16_t x=info->reservedWord; 135727f654740f2a26ad62a5c155af9199af9e69b889claireho pInfo->reservedWord=(uint16_t)((x<<8)|(x>>8)); 135827f654740f2a26ad62a5c155af9199af9e69b889claireho } 135927f654740f2a26ad62a5c155af9199af9e69b889claireho } else { 136027f654740f2a26ad62a5c155af9199af9e69b889claireho pInfo->size=0; 136127f654740f2a26ad62a5c155af9199af9e69b889claireho } 136227f654740f2a26ad62a5c155af9199af9e69b889claireho } 136327f654740f2a26ad62a5c155af9199af9e69b889claireho} 136427f654740f2a26ad62a5c155af9199af9e69b889claireho 136527f654740f2a26ad62a5c155af9199af9e69b889claireho 136627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CAPI void U_EXPORT2 udata_setFileAccess(UDataFileAccess access, UErrorCode * /*status*/) 136727f654740f2a26ad62a5c155af9199af9e69b889claireho{ 136827f654740f2a26ad62a5c155af9199af9e69b889claireho gDataFileAccess = access; 136927f654740f2a26ad62a5c155af9199af9e69b889claireho} 1370