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/build_config.h" 19 #include "src/base/file-utils.h" 20 21 #define ICU_UTIL_DATA_FILE 0 22 #define ICU_UTIL_DATA_SHARED 1 23 #define ICU_UTIL_DATA_STATIC 2 24 25 #define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat" 26 #define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt.dll" 27 #endif 28 29 namespace v8 { 30 31 namespace internal { 32 33 #if defined(V8_I18N_SUPPORT) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) 34 namespace { 35 char* g_icu_data_ptr = NULL; 36 37 void free_icu_data_ptr() { 38 delete[] g_icu_data_ptr; 39 } 40 41 } // namespace 42 #endif 43 44 bool InitializeICUDefaultLocation(const char* exec_path, 45 const char* icu_data_file) { 46 #if !defined(V8_I18N_SUPPORT) 47 return true; 48 #else 49 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE 50 if (icu_data_file) { 51 return InitializeICU(icu_data_file); 52 } 53 char* icu_data_file_default; 54 #if defined(V8_TARGET_LITTLE_ENDIAN) 55 base::RelativePath(&icu_data_file_default, exec_path, "icudtl.dat"); 56 #elif defined(V8_TARGET_BIG_ENDIAN) 57 base::RelativePath(&icu_data_file_default, exec_path, "icudtb.dat"); 58 #else 59 #error Unknown byte ordering 60 #endif 61 bool result = InitializeICU(icu_data_file_default); 62 free(icu_data_file_default); 63 return result; 64 #else 65 return InitializeICU(NULL); 66 #endif 67 #endif 68 } 69 70 bool InitializeICU(const char* icu_data_file) { 71 #if !defined(V8_I18N_SUPPORT) 72 return true; 73 #else 74 #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED 75 // We expect to find the ICU data module alongside the current module. 76 HMODULE module = LoadLibraryA(ICU_UTIL_DATA_SHARED_MODULE_NAME); 77 if (!module) return false; 78 79 FARPROC addr = GetProcAddress(module, ICU_UTIL_DATA_SYMBOL); 80 if (!addr) return false; 81 82 UErrorCode err = U_ZERO_ERROR; 83 udata_setCommonData(reinterpret_cast<void*>(addr), &err); 84 return err == U_ZERO_ERROR; 85 #elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_STATIC 86 // Mac/Linux bundle the ICU data in. 87 return true; 88 #elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE 89 if (!icu_data_file) return false; 90 91 if (g_icu_data_ptr) return true; 92 93 FILE* inf = fopen(icu_data_file, "rb"); 94 if (!inf) return false; 95 96 fseek(inf, 0, SEEK_END); 97 size_t size = ftell(inf); 98 rewind(inf); 99 100 g_icu_data_ptr = new char[size]; 101 if (fread(g_icu_data_ptr, 1, size, inf) != size) { 102 delete[] g_icu_data_ptr; 103 g_icu_data_ptr = NULL; 104 fclose(inf); 105 return false; 106 } 107 fclose(inf); 108 109 atexit(free_icu_data_ptr); 110 111 UErrorCode err = U_ZERO_ERROR; 112 udata_setCommonData(reinterpret_cast<void*>(g_icu_data_ptr), &err); 113 return err == U_ZERO_ERROR; 114 #endif 115 #endif 116 } 117 118 } // namespace internal 119 } // namespace v8 120