OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
6 #if defined(HOST_OS_WINDOWS) | 6 #if defined(HOST_OS_WINDOWS) |
7 | 7 |
8 #include <errno.h> // NOLINT | 8 #include <errno.h> // NOLINT |
9 #include <time.h> // NOLINT | 9 #include <time.h> // NOLINT |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | 24 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
25 Log::PrintErr("FormatMessage failed for error code %d (error %d)\n", code, | 25 Log::PrintErr("FormatMessage failed for error code %d (error %d)\n", code, |
26 GetLastError()); | 26 GetLastError()); |
27 } | 27 } |
28 _snwprintf(buffer, buffer_length, L"OS Error %d", code); | 28 _snwprintf(buffer, buffer_length, L"OS Error %d", code); |
29 } | 29 } |
30 // Ensure string termination. | 30 // Ensure string termination. |
31 buffer[buffer_length - 1] = 0; | 31 buffer[buffer_length - 1] = 0; |
32 } | 32 } |
33 | 33 |
34 | |
35 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) { | 34 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) { |
36 set_code(GetLastError()); | 35 set_code(GetLastError()); |
37 | 36 |
38 static const int kMaxMessageLength = 256; | 37 static const int kMaxMessageLength = 256; |
39 wchar_t message[kMaxMessageLength]; | 38 wchar_t message[kMaxMessageLength]; |
40 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); | 39 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); |
41 char* utf8 = StringUtilsWin::WideToUtf8(message); | 40 char* utf8 = StringUtilsWin::WideToUtf8(message); |
42 SetMessage(utf8); | 41 SetMessage(utf8); |
43 } | 42 } |
44 | 43 |
45 | |
46 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) { | 44 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) { |
47 set_sub_system(sub_system); | 45 set_sub_system(sub_system); |
48 set_code(code); | 46 set_code(code); |
49 | 47 |
50 static const int kMaxMessageLength = 256; | 48 static const int kMaxMessageLength = 256; |
51 wchar_t message[kMaxMessageLength]; | 49 wchar_t message[kMaxMessageLength]; |
52 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); | 50 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); |
53 char* utf8 = StringUtilsWin::WideToUtf8(message); | 51 char* utf8 = StringUtilsWin::WideToUtf8(message); |
54 SetMessage(utf8); | 52 SetMessage(utf8); |
55 } | 53 } |
56 | 54 |
57 | |
58 char* StringUtils::ConsoleStringToUtf8(char* str, | 55 char* StringUtils::ConsoleStringToUtf8(char* str, |
59 intptr_t len, | 56 intptr_t len, |
60 intptr_t* result_len) { | 57 intptr_t* result_len) { |
61 int wide_len = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); | 58 int wide_len = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); |
62 wchar_t* wide; | 59 wchar_t* wide; |
63 wide = | 60 wide = |
64 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); | 61 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); |
65 MultiByteToWideChar(CP_ACP, 0, str, len, wide, wide_len); | 62 MultiByteToWideChar(CP_ACP, 0, str, len, wide, wide_len); |
66 char* utf8 = StringUtilsWin::WideToUtf8(wide, wide_len, result_len); | 63 char* utf8 = StringUtilsWin::WideToUtf8(wide, wide_len, result_len); |
67 return utf8; | 64 return utf8; |
68 } | 65 } |
69 | 66 |
70 | |
71 char* StringUtils::Utf8ToConsoleString(char* utf8, | 67 char* StringUtils::Utf8ToConsoleString(char* utf8, |
72 intptr_t len, | 68 intptr_t len, |
73 intptr_t* result_len) { | 69 intptr_t* result_len) { |
74 intptr_t wide_len; | 70 intptr_t wide_len; |
75 wchar_t* wide = StringUtilsWin::Utf8ToWide(utf8, len, &wide_len); | 71 wchar_t* wide = StringUtilsWin::Utf8ToWide(utf8, len, &wide_len); |
76 int system_len = | 72 int system_len = |
77 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, NULL, 0, NULL, NULL); | 73 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, NULL, 0, NULL, NULL); |
78 char* ansi; | 74 char* ansi; |
79 ansi = | 75 ansi = |
80 reinterpret_cast<char*>(Dart_ScopeAllocate(system_len * sizeof(*ansi))); | 76 reinterpret_cast<char*>(Dart_ScopeAllocate(system_len * sizeof(*ansi))); |
81 if (ansi == NULL) { | 77 if (ansi == NULL) { |
82 return NULL; | 78 return NULL; |
83 } | 79 } |
84 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, ansi, system_len, NULL, NULL); | 80 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, ansi, system_len, NULL, NULL); |
85 if (result_len != NULL) { | 81 if (result_len != NULL) { |
86 *result_len = system_len; | 82 *result_len = system_len; |
87 } | 83 } |
88 return ansi; | 84 return ansi; |
89 } | 85 } |
90 | 86 |
91 | |
92 char* StringUtilsWin::WideToUtf8(wchar_t* wide, | 87 char* StringUtilsWin::WideToUtf8(wchar_t* wide, |
93 intptr_t len, | 88 intptr_t len, |
94 intptr_t* result_len) { | 89 intptr_t* result_len) { |
95 // If len is -1 then WideCharToMultiByte will include the terminating | 90 // If len is -1 then WideCharToMultiByte will include the terminating |
96 // NUL byte in the length. | 91 // NUL byte in the length. |
97 int utf8_len = | 92 int utf8_len = |
98 WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, NULL); | 93 WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, NULL); |
99 char* utf8; | 94 char* utf8; |
100 utf8 = reinterpret_cast<char*>(Dart_ScopeAllocate(utf8_len * sizeof(*utf8))); | 95 utf8 = reinterpret_cast<char*>(Dart_ScopeAllocate(utf8_len * sizeof(*utf8))); |
101 WideCharToMultiByte(CP_UTF8, 0, wide, len, utf8, utf8_len, NULL, NULL); | 96 WideCharToMultiByte(CP_UTF8, 0, wide, len, utf8, utf8_len, NULL, NULL); |
102 if (result_len != NULL) { | 97 if (result_len != NULL) { |
103 *result_len = utf8_len; | 98 *result_len = utf8_len; |
104 } | 99 } |
105 return utf8; | 100 return utf8; |
106 } | 101 } |
107 | 102 |
108 | |
109 wchar_t* StringUtilsWin::Utf8ToWide(char* utf8, | 103 wchar_t* StringUtilsWin::Utf8ToWide(char* utf8, |
110 intptr_t len, | 104 intptr_t len, |
111 intptr_t* result_len) { | 105 intptr_t* result_len) { |
112 // If len is -1 then MultiByteToWideChar will include the terminating | 106 // If len is -1 then MultiByteToWideChar will include the terminating |
113 // NUL byte in the length. | 107 // NUL byte in the length. |
114 int wide_len = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); | 108 int wide_len = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); |
115 wchar_t* wide; | 109 wchar_t* wide; |
116 wide = | 110 wide = |
117 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); | 111 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); |
118 MultiByteToWideChar(CP_UTF8, 0, utf8, len, wide, wide_len); | 112 MultiByteToWideChar(CP_UTF8, 0, utf8, len, wide, wide_len); |
119 if (result_len != NULL) { | 113 if (result_len != NULL) { |
120 *result_len = wide_len; | 114 *result_len = wide_len; |
121 } | 115 } |
122 return wide; | 116 return wide; |
123 } | 117 } |
124 | 118 |
125 | |
126 const char* StringUtils::Utf8ToConsoleString(const char* utf8, | 119 const char* StringUtils::Utf8ToConsoleString(const char* utf8, |
127 intptr_t len, | 120 intptr_t len, |
128 intptr_t* result_len) { | 121 intptr_t* result_len) { |
129 return const_cast<const char*>(StringUtils::Utf8ToConsoleString( | 122 return const_cast<const char*>(StringUtils::Utf8ToConsoleString( |
130 const_cast<char*>(utf8), len, result_len)); | 123 const_cast<char*>(utf8), len, result_len)); |
131 } | 124 } |
132 | 125 |
133 | |
134 const char* StringUtils::ConsoleStringToUtf8(const char* str, | 126 const char* StringUtils::ConsoleStringToUtf8(const char* str, |
135 intptr_t len, | 127 intptr_t len, |
136 intptr_t* result_len) { | 128 intptr_t* result_len) { |
137 return const_cast<const char*>(StringUtils::ConsoleStringToUtf8( | 129 return const_cast<const char*>(StringUtils::ConsoleStringToUtf8( |
138 const_cast<char*>(str), len, result_len)); | 130 const_cast<char*>(str), len, result_len)); |
139 } | 131 } |
140 | 132 |
141 | |
142 const char* StringUtilsWin::WideToUtf8(const wchar_t* wide, | 133 const char* StringUtilsWin::WideToUtf8(const wchar_t* wide, |
143 intptr_t len, | 134 intptr_t len, |
144 intptr_t* result_len) { | 135 intptr_t* result_len) { |
145 return const_cast<const char*>( | 136 return const_cast<const char*>( |
146 StringUtilsWin::WideToUtf8(const_cast<wchar_t*>(wide), len, result_len)); | 137 StringUtilsWin::WideToUtf8(const_cast<wchar_t*>(wide), len, result_len)); |
147 } | 138 } |
148 | 139 |
149 | |
150 const wchar_t* StringUtilsWin::Utf8ToWide(const char* utf8, | 140 const wchar_t* StringUtilsWin::Utf8ToWide(const char* utf8, |
151 intptr_t len, | 141 intptr_t len, |
152 intptr_t* result_len) { | 142 intptr_t* result_len) { |
153 return const_cast<const wchar_t*>( | 143 return const_cast<const wchar_t*>( |
154 StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len)); | 144 StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len)); |
155 } | 145 } |
156 | 146 |
157 | |
158 char* StringUtils::StrNDup(const char* s, intptr_t n) { | 147 char* StringUtils::StrNDup(const char* s, intptr_t n) { |
159 intptr_t len = strlen(s); | 148 intptr_t len = strlen(s); |
160 if ((n < 0) || (len < 0)) { | 149 if ((n < 0) || (len < 0)) { |
161 return NULL; | 150 return NULL; |
162 } | 151 } |
163 if (n < len) { | 152 if (n < len) { |
164 len = n; | 153 len = n; |
165 } | 154 } |
166 char* result = reinterpret_cast<char*>(malloc(len + 1)); | 155 char* result = reinterpret_cast<char*>(malloc(len + 1)); |
167 if (result == NULL) { | 156 if (result == NULL) { |
168 return NULL; | 157 return NULL; |
169 } | 158 } |
170 result[len] = '\0'; | 159 result[len] = '\0'; |
171 return reinterpret_cast<char*>(memmove(result, s, len)); | 160 return reinterpret_cast<char*>(memmove(result, s, len)); |
172 } | 161 } |
173 | 162 |
174 | |
175 bool ShellUtils::GetUtf8Argv(int argc, char** argv) { | 163 bool ShellUtils::GetUtf8Argv(int argc, char** argv) { |
176 wchar_t* command_line = GetCommandLineW(); | 164 wchar_t* command_line = GetCommandLineW(); |
177 int unicode_argc; | 165 int unicode_argc; |
178 wchar_t** unicode_argv = CommandLineToArgvW(command_line, &unicode_argc); | 166 wchar_t** unicode_argv = CommandLineToArgvW(command_line, &unicode_argc); |
179 if (unicode_argv == NULL) { | 167 if (unicode_argv == NULL) { |
180 return false; | 168 return false; |
181 } | 169 } |
182 // The argc passed to main should have the same argc as we get here. | 170 // The argc passed to main should have the same argc as we get here. |
183 ASSERT(argc == unicode_argc); | 171 ASSERT(argc == unicode_argc); |
184 if (argc < unicode_argc) { | 172 if (argc < unicode_argc) { |
185 unicode_argc = argc; | 173 unicode_argc = argc; |
186 } | 174 } |
187 for (int i = 0; i < unicode_argc; i++) { | 175 for (int i = 0; i < unicode_argc; i++) { |
188 wchar_t* arg = unicode_argv[i]; | 176 wchar_t* arg = unicode_argv[i]; |
189 int arg_len = WideCharToMultiByte(CP_UTF8, 0, arg, -1, NULL, 0, NULL, NULL); | 177 int arg_len = WideCharToMultiByte(CP_UTF8, 0, arg, -1, NULL, 0, NULL, NULL); |
190 char* utf8_arg = reinterpret_cast<char*>(malloc(arg_len)); | 178 char* utf8_arg = reinterpret_cast<char*>(malloc(arg_len)); |
191 WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg, arg_len, NULL, NULL); | 179 WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg, arg_len, NULL, NULL); |
192 argv[i] = utf8_arg; | 180 argv[i] = utf8_arg; |
193 } | 181 } |
194 LocalFree(unicode_argv); | 182 LocalFree(unicode_argv); |
195 return true; | 183 return true; |
196 } | 184 } |
197 | 185 |
198 | |
199 // Although win32 uses 64-bit integers for representing timestamps, | 186 // Although win32 uses 64-bit integers for representing timestamps, |
200 // these are packed into a FILETIME structure. The FILETIME | 187 // these are packed into a FILETIME structure. The FILETIME |
201 // structure is just a struct representing a 64-bit integer. The | 188 // structure is just a struct representing a 64-bit integer. The |
202 // TimeStamp union allows access to both a FILETIME and an integer | 189 // TimeStamp union allows access to both a FILETIME and an integer |
203 // representation of the timestamp. The Windows timestamp is in | 190 // representation of the timestamp. The Windows timestamp is in |
204 // 100-nanosecond intervals since January 1, 1601. | 191 // 100-nanosecond intervals since January 1, 1601. |
205 union TimeStamp { | 192 union TimeStamp { |
206 FILETIME ft_; | 193 FILETIME ft_; |
207 int64_t t_; | 194 int64_t t_; |
208 }; | 195 }; |
209 | 196 |
210 | |
211 static int64_t GetCurrentTimeMicros() { | 197 static int64_t GetCurrentTimeMicros() { |
212 static const int64_t kTimeEpoc = 116444736000000000LL; | 198 static const int64_t kTimeEpoc = 116444736000000000LL; |
213 static const int64_t kTimeScaler = 10; // 100 ns to us. | 199 static const int64_t kTimeScaler = 10; // 100 ns to us. |
214 | 200 |
215 TimeStamp time; | 201 TimeStamp time; |
216 GetSystemTimeAsFileTime(&time.ft_); | 202 GetSystemTimeAsFileTime(&time.ft_); |
217 return (time.t_ - kTimeEpoc) / kTimeScaler; | 203 return (time.t_ - kTimeEpoc) / kTimeScaler; |
218 } | 204 } |
219 | 205 |
220 | |
221 static int64_t qpc_ticks_per_second = 0; | 206 static int64_t qpc_ticks_per_second = 0; |
222 | 207 |
223 void TimerUtils::InitOnce() { | 208 void TimerUtils::InitOnce() { |
224 LARGE_INTEGER ticks_per_sec; | 209 LARGE_INTEGER ticks_per_sec; |
225 if (!QueryPerformanceFrequency(&ticks_per_sec)) { | 210 if (!QueryPerformanceFrequency(&ticks_per_sec)) { |
226 qpc_ticks_per_second = 0; | 211 qpc_ticks_per_second = 0; |
227 } else { | 212 } else { |
228 qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart); | 213 qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart); |
229 } | 214 } |
230 } | 215 } |
231 | 216 |
232 | |
233 int64_t TimerUtils::GetCurrentMonotonicMillis() { | 217 int64_t TimerUtils::GetCurrentMonotonicMillis() { |
234 return GetCurrentMonotonicMicros() / 1000; | 218 return GetCurrentMonotonicMicros() / 1000; |
235 } | 219 } |
236 | 220 |
237 | |
238 int64_t TimerUtils::GetCurrentMonotonicMicros() { | 221 int64_t TimerUtils::GetCurrentMonotonicMicros() { |
239 if (qpc_ticks_per_second == 0) { | 222 if (qpc_ticks_per_second == 0) { |
240 // QueryPerformanceCounter not supported, fallback. | 223 // QueryPerformanceCounter not supported, fallback. |
241 return GetCurrentTimeMicros(); | 224 return GetCurrentTimeMicros(); |
242 } | 225 } |
243 // Grab performance counter value. | 226 // Grab performance counter value. |
244 LARGE_INTEGER now; | 227 LARGE_INTEGER now; |
245 QueryPerformanceCounter(&now); | 228 QueryPerformanceCounter(&now); |
246 int64_t qpc_value = static_cast<int64_t>(now.QuadPart); | 229 int64_t qpc_value = static_cast<int64_t>(now.QuadPart); |
247 // Convert to microseconds. | 230 // Convert to microseconds. |
248 int64_t seconds = qpc_value / qpc_ticks_per_second; | 231 int64_t seconds = qpc_value / qpc_ticks_per_second; |
249 int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second); | 232 int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second); |
250 int64_t result = seconds * kMicrosecondsPerSecond; | 233 int64_t result = seconds * kMicrosecondsPerSecond; |
251 result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second); | 234 result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second); |
252 return result; | 235 return result; |
253 } | 236 } |
254 | 237 |
255 | |
256 void TimerUtils::Sleep(int64_t millis) { | 238 void TimerUtils::Sleep(int64_t millis) { |
257 ::Sleep(millis); | 239 ::Sleep(millis); |
258 } | 240 } |
259 | 241 |
260 } // namespace bin | 242 } // namespace bin |
261 } // namespace dart | 243 } // namespace dart |
262 | 244 |
263 #endif // defined(HOST_OS_WINDOWS) | 245 #endif // defined(HOST_OS_WINDOWS) |
OLD | NEW |