blob: b323942d02a3f43664800e0f786d486fb46c6946 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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#define ICU_UTIL_DATA_FILE 0
19#define ICU_UTIL_DATA_SHARED 1
20#define ICU_UTIL_DATA_STATIC 2
21
22#define ICU_UTIL_DATA_SYMBOL "icudt" U_ICU_VERSION_SHORT "_dat"
23#define ICU_UTIL_DATA_SHARED_MODULE_NAME "icudt.dll"
24#endif
25
26namespace v8 {
27
28namespace internal {
29
30#if defined(V8_I18N_SUPPORT) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
31namespace {
32char* g_icu_data_ptr = NULL;
33
34void free_icu_data_ptr() {
35 delete[] g_icu_data_ptr;
36}
37
38} // namespace
39#endif
40
41bool InitializeICU(const char* icu_data_file) {
42#if !defined(V8_I18N_SUPPORT)
43 return true;
44#else
45#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_SHARED
46 // We expect to find the ICU data module alongside the current module.
47 HMODULE module = LoadLibraryA(ICU_UTIL_DATA_SHARED_MODULE_NAME);
48 if (!module) return false;
49
50 FARPROC addr = GetProcAddress(module, ICU_UTIL_DATA_SYMBOL);
51 if (!addr) return false;
52
53 UErrorCode err = U_ZERO_ERROR;
54 udata_setCommonData(reinterpret_cast<void*>(addr), &err);
55 return err == U_ZERO_ERROR;
56#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_STATIC
57 // Mac/Linux bundle the ICU data in.
58 return true;
59#elif ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
60 if (!icu_data_file) return false;
61
62 if (g_icu_data_ptr) return true;
63
64 FILE* inf = fopen(icu_data_file, "rb");
65 if (!inf) return false;
66
67 fseek(inf, 0, SEEK_END);
68 size_t size = ftell(inf);
69 rewind(inf);
70
71 g_icu_data_ptr = new char[size];
72 if (fread(g_icu_data_ptr, 1, size, inf) != size) {
73 delete[] g_icu_data_ptr;
74 g_icu_data_ptr = NULL;
75 fclose(inf);
76 return false;
77 }
78 fclose(inf);
79
80 atexit(free_icu_data_ptr);
81
82 UErrorCode err = U_ZERO_ERROR;
83 udata_setCommonData(reinterpret_cast<void*>(g_icu_data_ptr), &err);
84 return err == U_ZERO_ERROR;
85#endif
86#endif
87}
88
89} } // namespace v8::internal