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 "src/base/win32-headers.h" |
9 | #endif |
10 | |
11 | #if defined(V8_INTL_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_STATIC 1 |
23 | |
24 | #endif |
25 | |
26 | namespace v8 { |
27 | |
28 | namespace internal { |
29 | |
30 | #if defined(V8_INTL_SUPPORT) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE) |
31 | namespace { |
32 | char* g_icu_data_ptr = nullptr; |
33 | |
34 | void free_icu_data_ptr() { |
35 | delete[] g_icu_data_ptr; |
36 | } |
37 | |
38 | } // namespace |
39 | #endif |
40 | |
41 | bool InitializeICUDefaultLocation(const char* exec_path, |
42 | const char* icu_data_file) { |
43 | #if !defined(V8_INTL_SUPPORT) |
44 | return true; |
45 | #else |
46 | #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE |
47 | if (icu_data_file) { |
48 | return InitializeICU(icu_data_file); |
49 | } |
50 | char* icu_data_file_default; |
51 | #if defined(V8_TARGET_LITTLE_ENDIAN) |
52 | base::RelativePath(&icu_data_file_default, exec_path, "icudtl.dat" ); |
53 | #elif defined(V8_TARGET_BIG_ENDIAN) |
54 | base::RelativePath(&icu_data_file_default, exec_path, "icudtb.dat" ); |
55 | #else |
56 | #error Unknown byte ordering |
57 | #endif |
58 | bool result = InitializeICU(icu_data_file_default); |
59 | free(icu_data_file_default); |
60 | return result; |
61 | #else |
62 | return InitializeICU(nullptr); |
63 | #endif |
64 | #endif |
65 | } |
66 | |
67 | bool InitializeICU(const char* icu_data_file) { |
68 | #if !defined(V8_INTL_SUPPORT) |
69 | return true; |
70 | #else |
71 | #if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_STATIC |
72 | // Use bundled ICU data. |
73 | return true; |
74 | #elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE |
75 | if (!icu_data_file) return false; |
76 | |
77 | if (g_icu_data_ptr) return true; |
78 | |
79 | FILE* inf = fopen(icu_data_file, "rb" ); |
80 | if (!inf) return false; |
81 | |
82 | fseek(inf, 0, SEEK_END); |
83 | size_t size = ftell(inf); |
84 | rewind(inf); |
85 | |
86 | g_icu_data_ptr = new char[size]; |
87 | if (fread(g_icu_data_ptr, 1, size, inf) != size) { |
88 | delete[] g_icu_data_ptr; |
89 | g_icu_data_ptr = nullptr; |
90 | fclose(inf); |
91 | return false; |
92 | } |
93 | fclose(inf); |
94 | |
95 | atexit(free_icu_data_ptr); |
96 | |
97 | UErrorCode err = U_ZERO_ERROR; |
98 | udata_setCommonData(reinterpret_cast<void*>(g_icu_data_ptr), &err); |
99 | // Never try to load ICU data from files. |
100 | udata_setFileAccess(UDATA_ONLY_PACKAGES, &err); |
101 | return err == U_ZERO_ERROR; |
102 | #endif |
103 | #endif |
104 | } |
105 | |
106 | #undef ICU_UTIL_DATA_FILE |
107 | #undef ICU_UTIL_DATA_STATIC |
108 | |
109 | } // namespace internal |
110 | } // namespace v8 |
111 | |