1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/icu_util.h" 6 7 #if defined(_WIN32) 8 #include <windows.h> 9 #endif 10 11 #if defined(V8_I18N_SUPPORT) 12 #include <stdio.h> 13 #include <stdlib.h> 14 15 #include "unicode/putil.h" 16 #include "unicode/udata.h" 17 18 #include "src/base/file-utils.h" 19 20 #define ICU_UTIL_DATA_FILE 0 21 #define ICU_UTIL_DATA_SHARED 1 22 #define ICU_UTIL_DATA_STATIC 2 23 24 #define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" 25 #define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt.dll" 26 #endif 27 28 namespace v8 { 29 30 namespace internal { 31 32 #if defined(V8_I18N_SUPPORT) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) 33 namespace { 34 char* g_icu_data_ptr = NULL; 35 36 void free_icu_data_ptr() { 37 delete[] g_icu_data_ptr; 38 } 39 40 } // namespace 41 #endif 42 43 bool InitializeICUDefaultLocation(const char* exec_path, 44 const char* icu_data_file) { 45 #if !defined(V8_I18N_SUPPORT) 46 return true; 47 #else 48 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE 49 if (icu_data_file) { 50 return InitializeICU(icu_data_file); 51 } 52 char* icu_data_file_default; 53 RelativePath(&icu_data_file_default, exec_path, "icudtl.dat"); 54 bool result = InitializeICU(icu_data_file_default); 55 free(icu_data_file_default); 56 return result; 57 #else 58 return InitializeICU(NULL); 59 #endif 60 #endif 61 } 62 63 bool InitializeICU(const char* icu_data_file) { 64 #if !defined(V8_I18N_SUPPORT) 65 return true; 66 #else 67 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED 68 // We expect to find the ICU data module alongside the current module. 69 HMODULE module = LoadLibraryA(ICU_UTIL_DATA_SHARED_MODULE_NAME); 70 if (!module) return false; 71 72 FARPROC addr = GetProcAddress(module, ICU_UTIL_DATA_SYMBOL); 73 if (!addr) return false; 74 75 UErrorCode err = U_ZERO_ERROR; 76 udata_setCommonData(reinterpret_cast<void*>(addr), &err); 77 return err == U_ZERO_ERROR; 78 #elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_STATIC 79 // Mac/Linux bundle the ICU data in. 80 return true; 81 #elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE 82 if (!icu_data_file) return false; 83 84 if (g_icu_data_ptr) return true; 85 86 FILE* inf = fopen(icu_data_file, "rb"); 87 if (!inf) return false; 88 89 fseek(inf, 0, SEEK_END); 90 size_t size = ftell(inf); 91 rewind(inf); 92 93 g_icu_data_ptr = new char[size]; 94 if (fread(g_icu_data_ptr, 1, size, inf) != size) { 95 delete[] g_icu_data_ptr; 96 g_icu_data_ptr = NULL; 97 fclose(inf); 98 return false; 99 } 100 fclose(inf); 101 102 atexit(free_icu_data_ptr); 103 104 UErrorCode err = U_ZERO_ERROR; 105 udata_setCommonData(reinterpret_cast<void*>(g_icu_data_ptr), &err); 106 return err == U_ZERO_ERROR; 107 #endif 108 #endif 109 } 110 111 } // namespace internal 112 } // namespace v8 113