int main(int argc, char **argv) { UConverter *c; UErrorCode status = U_ZERO_ERROR; udata_setCommonData(NULL, &status); printf("setCommonData(NULL) -> %s [should fail]\n", u_errorName(status)); if(status != U_ILLEGAL_ARGUMENT_ERROR) { printf("*** FAIL: should have returned U_ILLEGAL_ARGUMENT_ERROR\n"); return 1; } status = U_ZERO_ERROR; udata_setCommonData(&U_ICUDATA_ENTRY_POINT, &status); printf("setCommonData(%p) -> %s\n", (void*)&U_ICUDATA_ENTRY_POINT, u_errorName(status)); if(U_FAILURE(status)) { printf("*** FAIL: should have returned U_ZERO_ERROR\n"); return 1; } status = U_ZERO_ERROR; c = ucnv_open("iso-8859-3", &status); printf("ucnv_open(iso-8859-3)-> %p, err = %s, name=%s\n", (void *)c, u_errorName(status), (!c)?"?":ucnv_getName(c,&status) ); if(status != U_ZERO_ERROR) { printf("\n*** FAIL: should have returned U_ZERO_ERROR;\n"); return 1; } else { ucnv_close(c); } status = U_ZERO_ERROR; udata_setCommonData(&U_ICUDATA_ENTRY_POINT, &status); printf("setCommonData(%p) -> %s [should pass]\n", (void*) &U_ICUDATA_ENTRY_POINT, u_errorName(status)); if (U_FAILURE(status) || status == U_USING_DEFAULT_WARNING ) { printf("\n*** FAIL: should pass and not set U_USING_DEFAULT_ERROR\n"); return 1; } printf("\n*** PASS PASS PASS, test PASSED!!!!!!!!\n"); return 0; }
// --------------------------------------------------------------------------- // ICUTransService: Constructors and Destructor // --------------------------------------------------------------------------- ICUTransService::ICUTransService() { #if (U_ICU_VERSION_MAJOR_NUM > 2 || (U_ICU_VERSION_MAJOR_NUM == 2 && U_ICU_VERSION_MINOR_NUM >= 6)) UErrorCode errorCode=U_ZERO_ERROR; u_init(&errorCode); if(U_FAILURE(errorCode)) { XMLPlatformUtils::panic(PanicHandler::Panic_NoTransService); } #endif #if !defined(XML_OS390) && !defined(XML_AS400) && !defined(XML_HPUX) && !defined(XML_PTX) #if (U_ICU_VERSION_MAJOR_NUM < 2) // Starting with ICU 2.0, ICU itself includes a static reference to the data // entrypoint symbol. // // ICU 1.8 (and previous) did not include a static reference, but would // dynamically load the data dll when it was first needed, however this dynamic // loading proved unreliable in some of the odd environments that Xerces needed // to run in. Hence, the static reference. // Pass the location of the converter data to ICU. By doing so, we are // forcing the load of ICU converter data DLL, after the Xerces-C DLL is // loaded. This implies that Xerces-C, now has to explicitly link with the // ICU converter dll. However, the advantage is that we no longer depend // on the code which does demand dynamic loading of DLL's. The demand // loading is highly system dependent and was a constant source of support // calls. UErrorCode uerr = U_ZERO_ERROR; udata_setCommonData((void *) icudata_dat, &uerr); #endif #endif }
void OsmAnd::ICU::initialize() { // Initialize ICU UErrorCode icuError = U_ZERO_ERROR; g_IcuData = qMove(std::unique_ptr<QByteArray>(new QByteArray(EmbeddedResources::decompressResource(QLatin1String("icu4c/icu-data-l.dat"))))); udata_setCommonData(g_IcuData->constData(), &icuError); if (U_FAILURE(icuError)) { LogPrintf(LogSeverityLevel::Error, "Failed to initialize ICU data: %d", icuError); return; } u_init(&icuError); if (U_FAILURE(icuError)) { LogPrintf(LogSeverityLevel::Error, "Failed to initialize ICU: %d", icuError); return; } // Allocate resources: g_pIcuAnyToLatinTransliterator = Transliterator::createInstance(UnicodeString("Any-Latin/BGN"), UTRANS_FORWARD, icuError); if (U_FAILURE(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to create global ICU Any-to-Latin transliterator: %d", icuError); icuError = U_ZERO_ERROR; g_pIcuAccentsAndDiacriticsConverter = Transliterator::createInstance(UnicodeString("NFD; [:Mn:] Remove; NFC"), UTRANS_FORWARD, icuError); if (U_FAILURE(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to create global ICU accents&diacritics converter: %d", icuError); icuError = U_ZERO_ERROR; g_pIcuWordBreakIterator = BreakIterator::createWordInstance(Locale::getRoot(), icuError); if (U_FAILURE(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to create global ICU word break iterator: %d", icuError); }
void register_libcore_icu_ICU(JNIEnv* env) { std::string path; path = u_getDataDirectory(); path += "/"; path += U_ICUDATA_NAME; path += ".dat"; #define FAIL_WITH_STRERROR(s) \ ALOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ abort(); #define MAYBE_FAIL_WITH_ICU_ERROR(s) \ if (status != U_ZERO_ERROR) {\ ALOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ abort(); \ } // Open the file and get its length. ScopedFd fd(open(path.c_str(), O_RDONLY)); if (fd.get() == -1) { FAIL_WITH_STRERROR("open"); } struct stat sb; if (fstat(fd.get(), &sb) == -1) { FAIL_WITH_STRERROR("stat"); } // Map it. void* data = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd.get(), 0); if (data == MAP_FAILED) { FAIL_WITH_STRERROR("mmap"); } // Tell the kernel that accesses are likely to be random rather than sequential. if (madvise(data, sb.st_size, MADV_RANDOM) == -1) { FAIL_WITH_STRERROR("madvise(MADV_RANDOM)"); } // Tell ICU to use our memory-mapped data. UErrorCode status = U_ZERO_ERROR; udata_setCommonData(data, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); // Tell ICU it can *only* use our memory-mapped data. udata_setFileAccess(UDATA_NO_FILES, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setFileAccess"); // Failures to find the ICU data tend to be somewhat obscure because ICU loads its data on first // use, which can be anywhere. Force initialization up front so we can report a nice clear error // and bail. u_init(&status); MAYBE_FAIL_WITH_ICU_ERROR("u_init"); jniRegisterNativeMethods(env, "libcore/icu/ICU", gMethods, NELEM(gMethods)); }
// This function attempts to load the ICU data tables from a DLL. // Returns 0 on failure, nonzero on success. // This a hack job of icu_utils.cc:Initialize(). It's Chrome-specific code. int sqlite_shell_init_icu() { HMODULE module; FARPROC addr; UErrorCode err; module = LoadLibrary(L"icudt38.dll"); if (!module) return 0; addr = GetProcAddress(module, "icudt38_dat"); if (!addr) return 0; err = U_ZERO_ERROR; udata_setCommonData(addr, &err); return 1; }
void OsmAnd::ICU::initialize() { // Initialize ICU UErrorCode icuError = U_ZERO_ERROR; g_IcuData = qMove(std::unique_ptr<QByteArray>(new QByteArray(EmbeddedResources::decompressResource(QLatin1String("icu4c/icu-data-l.xml"))))); udata_setCommonData(g_IcuData->constData(), &icuError); if(!U_SUCCESS(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to initialize ICU data: %d", icuError); u_init(&icuError); if(!U_SUCCESS(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to initialize ICU: %d", icuError); // Allocate resources icuError = U_ZERO_ERROR; g_pIcuTransliterator = Transliterator::createInstance(UnicodeString("Any-Latin/UNGEGN; NFD; [:M:] Remove; NFC"), UTRANS_FORWARD, icuError); if(!U_SUCCESS(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to create global ICU transliterator: %d", icuError); icuError = U_ZERO_ERROR; g_pIcuWordBreakIterator = BreakIterator::createWordInstance(Locale::getRoot(), icuError); if(!U_SUCCESS(icuError)) LogPrintf(LogSeverityLevel::Error, "Failed to create global ICU word break iterator: %d", icuError); }
int register_libcore_icu_ICU(JNIEnv* env) { std::string path; #define FAIL_WITH_STRERROR(s) \ ALOGE("Couldn't " s " '%s': %s", path.c_str(), strerror(errno)); \ abort(); #define MAYBE_FAIL_WITH_ICU_ERROR(s) \ if (status != U_ZERO_ERROR) {\ ALOGE("Couldn't initialize ICU (" s "): %s (%s)", u_errorName(status), path.c_str()); \ abort(); \ } // RoboVM note: Start change. Look for custom ICU data and fall back to builtin minimal data if not found. if (!findCustomICUData(path)) { ALOGI("Using builtin minimal ICU data"); void* data = malloc(out_icudt51l_dat_len); if (!data) { ALOGE("Failed to allocate %d bytes for builtin ICU data", out_icudt51l_dat_len); abort(); } int ret = inflate(out_icudt51l_dat_gz, out_icudt51l_dat_gz_len, data, out_icudt51l_dat_len); if (ret != out_icudt51l_dat_len) { ALOGE("Failed to inflate %d->%d bytes of builtin ICU data: %d", out_icudt51l_dat_gz_len, out_icudt51l_dat_len, ret); abort(); } UErrorCode status = U_ZERO_ERROR; udata_setCommonData(data, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); // Tell ICU it can *only* use our data. udata_setFileAccess(UDATA_NO_FILES, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setFileAccess"); // Force initialization up front so we can report a nice clear error and bail. u_init(&status); MAYBE_FAIL_WITH_ICU_ERROR("u_init"); return 0; } ALOGI("Using custom ICU data file: '%s'", path.c_str()); // RoboVM note: End change. // Open the file and get its length. ScopedFd fd(open(path.c_str(), O_RDONLY)); if (fd.get() == -1) { FAIL_WITH_STRERROR("open"); } struct stat sb; if (fstat(fd.get(), &sb) == -1) { FAIL_WITH_STRERROR("stat"); } // Map it. void* data = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd.get(), 0); if (data == MAP_FAILED) { FAIL_WITH_STRERROR("mmap"); } // Tell the kernel that accesses are likely to be random rather than sequential. if (madvise(data, sb.st_size, MADV_RANDOM) == -1) { FAIL_WITH_STRERROR("madvise(MADV_RANDOM)"); } // Tell ICU to use our memory-mapped data. UErrorCode status = U_ZERO_ERROR; udata_setCommonData(data, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setCommonData"); // Tell ICU it can *only* use our memory-mapped data. udata_setFileAccess(UDATA_NO_FILES, &status); MAYBE_FAIL_WITH_ICU_ERROR("udata_setFileAccess"); // Failures to find the ICU data tend to be somewhat obscure because ICU loads its data on first // use, which can be anywhere. Force initialization up front so we can report a nice clear error // and bail. u_init(&status); MAYBE_FAIL_WITH_ICU_ERROR("u_init"); return 0; }
Bool CodeSet_Init(const char *icuDataDir) // IN: ICU data file location in Current code page. // Default is used if NULL. { DynBuf dbpath; #ifdef _WIN32 DWORD attribs; utf16_t *modPath = NULL; utf16_t *lastSlash; utf16_t *wpath; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapping = NULL; void *memMappedData = NULL; #else struct stat finfo; #endif char *path = NULL; Bool ret = FALSE; DynBuf_Init(&dbpath); #ifdef USE_ICU /* * We're using system ICU, which finds its own data. So nothing to * do here. */ dontUseIcu = FALSE; ret = TRUE; goto exit; #endif /* * ********************* WARNING * Must avoid recursive calls into the codeset library here, hence * the idiotic hoop-jumping. DO NOT change any of these calls to * wrapper equivalents or call any other functions that may perform * string conversion. * ********************* WARNING */ #ifdef _WIN32 // { #if vmx86_devel /* * Devel builds use toolchain directory first. */ { WCHAR icuFilePath[MAX_PATH] = { 0 }; DWORD n = ExpandEnvironmentStringsW(ICU_DATA_FILE_PATH, icuFilePath, ARRAYSIZE(icuFilePath)); if (n > 0 && n < ARRAYSIZE(icuFilePath)) { attribs = GetFileAttributesW(icuFilePath); if ((INVALID_FILE_ATTRIBUTES != attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY) == 0) { if (!CodeSetOld_Utf16leToCurrent((const char *) icuFilePath, n * sizeof *icuFilePath, &path, NULL)) { goto exit; } goto found; } } } #endif if (icuDataDir) { /* * Data file must be in the specified directory. */ size_t length = strlen(icuDataDir); if (!DynBuf_Append(&dbpath, icuDataDir, length)) { goto exit; } if (length && icuDataDir[length - 1] != DIRSEPC) { if (!DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS))) { goto exit; } } if (!DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. */ attribs = GetFileAttributesA(DynBuf_Get(&dbpath)); if ((INVALID_FILE_ATTRIBUTES == attribs) || (attribs & FILE_ATTRIBUTE_DIRECTORY)) { goto exit; } path = (char *) DynBuf_Detach(&dbpath); } else { /* * Data file must be in the directory of the current module * (i.e. the module that contains CodeSet_Init()). */ HMODULE hModule = W32Util_GetModuleByAddress((void *) CodeSet_Init); if (!hModule) { goto exit; } modPath = CodeSetGetModulePath(hModule); if (!modPath) { goto exit; } lastSlash = wcsrchr(modPath, DIRSEPC_W); if (!lastSlash) { goto exit; } *lastSlash = L'\0'; if (!DynBuf_Append(&dbpath, modPath, wcslen(modPath) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, DIRSEPS_W, wcslen(DIRSEPS_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE_W, wcslen(ICU_DATA_FILE_W) * sizeof(utf16_t)) || !DynBuf_Append(&dbpath, L"\0", 2)) { goto exit; } /* * Since u_setDataDirectory can't handle UTF-16, we would have to * now convert this path to local encoding. But that fails when * the module is in a path containing characters not in the * local encoding (see 282524). So we'll memory-map the file * instead and call udata_setCommonData() below. */ wpath = (utf16_t *) DynBuf_Get(&dbpath); hFile = CreateFileW(wpath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hFile) { goto exit; } hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (NULL == hMapping) { goto exit; } memMappedData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (NULL == memMappedData) { goto exit; } } #else // } _WIN32 { #if vmx86_devel { char *modPath; char *lastSlash; /* * Devel builds use toolchain directory first. */ if (stat(ICU_DATA_FILE_PATH, &finfo) >= 0 && !S_ISDIR(finfo.st_mode)) { if ((path = strdup(ICU_DATA_FILE_PATH)) == NULL) { goto exit; } goto found; } /* * Then we try module directory, if we can get it. */ modPath = CodeSetGetModulePath(HGMP_PRIVILEGE); if (modPath) { lastSlash = strrchr(modPath, DIRSEPC); if (lastSlash) { *lastSlash = '\0'; if (DynBuf_Append(&dbpath, modPath, strlen(modPath)) && DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) && DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) && DynBuf_Append(&dbpath, "\0", 1)) { if ((stat((const char *) DynBuf_Get(&dbpath), &finfo) >= 0) && !S_ISDIR(finfo.st_mode)) { free(modPath); path = DynBuf_Detach(&dbpath); goto found; } else { DynBuf_SetSize(&dbpath, 0); } } } free(modPath); } } #endif // vmx86_devel /* * Data file is either in POSIX_ICU_DIR or user specified dir. */ if (!icuDataDir) { icuDataDir = POSIX_ICU_DIR; } if (!DynBuf_Append(&dbpath, icuDataDir, strlen(icuDataDir)) || !DynBuf_Append(&dbpath, DIRSEPS, strlen(DIRSEPS)) || !DynBuf_Append(&dbpath, ICU_DATA_FILE, strlen(ICU_DATA_FILE)) || !DynBuf_Append(&dbpath, "\0", 1)) { goto exit; } /* * Check for file existence. (DO NOT CHANGE TO 'stat' WRAPPER). */ path = (char *) DynBuf_Detach(&dbpath); if (stat(path, &finfo) < 0 || S_ISDIR(finfo.st_mode)) { goto exit; } #endif // } _WIN32 #if vmx86_devel found: #endif #ifdef _WIN32 if (memMappedData) { /* * Tell ICU to use this mapped data. */ UErrorCode uerr = U_ZERO_ERROR; ASSERT(memMappedData); udata_setCommonData(memMappedData, &uerr); if (uerr != U_ZERO_ERROR) { UnmapViewOfFile(memMappedData); goto exit; } } else { #endif /* * Tell ICU to use this directory. */ u_setDataDirectory(path); #ifdef _WIN32 } #endif dontUseIcu = FALSE; ret = TRUE; exit: if (!ret) { /* * There was an error initing ICU, but if we can fall back on * non-ICU (old CodeSet) then things are OK. */ if (CODESET_CAN_FALLBACK_ON_NON_ICU) { ret = TRUE; dontUseIcu = TRUE; #ifdef _WIN32 OutputDebugStringW(L"CodeSet_Init: no ICU\n"); #endif } } #ifdef _WIN32 free(modPath); if (hMapping) { CloseHandle(hMapping); } if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } #endif free(path); DynBuf_Destroy(&dbpath); return ret; }