1 /**************************************************************************/
2 /* */
3 /* OCaml */
4 /* */
5 /* David Allsopp, OCaml Labs, Cambridge. */
6 /* */
7 /* Copyright 2017 MetaStack Solutions Ltd. */
8 /* */
9 /* All rights reserved. This file is distributed under the terms of */
10 /* the GNU Lesser General Public License version 2.1, with the */
11 /* special exception on linking described in the file LICENSE. */
12 /* */
13 /**************************************************************************/
14
15 /* Need at least Windows Vista for WC_ERR_INVALID_CHARS */
16 #define _WIN32_WINNT 0x600
17 #define WINVER 0x600
18 #include <windows.h>
19
20 /* See corresponding values in runtime/win32.c */
21 static int windows_unicode_enabled = WINDOWS_UNICODE;
22 static int windows_unicode_strict = 1;
23
24 /* Adapted from runtime/win32.c */
25 int win_wide_char_to_multi_byte(const wchar_t *s, int slen,
26 char *out, int outlen)
27 {
28 int retcode;
29
30 if (slen == 0)
31 return 0;
32
33 if (windows_unicode_enabled != 0)
34 retcode =
35 WideCharToMultiByte(CP_UTF8,
36 windows_unicode_strict ? WC_ERR_INVALID_CHARS : 0,
37 s, slen, out, outlen, NULL, NULL);
38 else
39 retcode =
40 WideCharToMultiByte(CP_ACP, 0, s, slen, out, outlen, NULL, NULL);
41
42 if (retcode == 0)
43 return -1;
44
45 return retcode;
46 }
47
48 char* caml_stat_strdup_of_utf16(const wchar_t *s)
49 {
50 char *out = NULL;
51 int retcode;
52
53 retcode = win_wide_char_to_multi_byte(s, -1, NULL, 0);
54 if (retcode >= 0) {
55 out = (char *)malloc(retcode);
56 win_wide_char_to_multi_byte(s, -1, out, retcode);
57 }
58
59 return out;
60 }
61