1#include <stdlib.h>
2#include <stdio.h>
3#include <wchar.h>
4#include <errno.h>
5#include <windows.h>
6#include <winnls.h>
7
8int __cdecl __mingw_str_wide_utf8(const wchar_t * const wptr, char **mbptr, size_t *buflen)
9{
10 int len;
11 char *buf;
12 int ret = 0;
13
14 len = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, NULL, 0, NULL, NULL); /* Get utf-8 string length */
15 if (len <= 0) {
16 switch (GetLastError()) {
17 case ERROR_INVALID_PARAMETER: /* CP_UTF8 is not supported */
18 case ERROR_INVALID_FLAGS: /* CP_UTF8 is not supported */
19 errno = ENOSYS;
20 *mbptr = NULL;
21 if (buflen != NULL) *buflen = 0;
22 return 0;
23 case NO_ERROR:
24 if (len == 0)
25 break;
26 /* fallthrough */
27 default:
28 errno = EINVAL;
29 *mbptr = NULL;
30 if (buflen != NULL) *buflen = 0;
31 return 0;
32 }
33 }
34 buf = calloc(len + 1, sizeof (char)); /* Can we assume sizeof char always = 1? */
35
36 if(!buf) len = 0;
37 else {
38 if (len != 0) {
39 ret = WideCharToMultiByte(CP_UTF8, 0, wptr, -1, buf, len, NULL, NULL); /*Do actual conversion*/
40 if (ret < 0 || (ret == 0 && GetLastError() != NO_ERROR)) {
41 free(buf);
42 errno = EINVAL;
43 *mbptr = NULL;
44 if (buflen != NULL) *buflen = 0;
45 return 0;
46 }
47 }
48 buf[len] = '\0'; /* Must terminate */
49 }
50 *mbptr = buf; /* Set string pointer to allocated buffer */
51 if(buflen != NULL) *buflen = (len) * sizeof (char); /* Give length of allocated memory if needed. */
52 return ret;
53}
54
55int __cdecl __mingw_str_utf8_wide(const char *const mbptr, wchar_t **wptr, size_t *buflen)
56{
57 int len;
58 wchar_t *buf;
59 int ret = 0;
60
61 len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, NULL, 0); /* Get converted size */
62 if (len <= 0) {
63 switch (GetLastError()) {
64 case ERROR_INVALID_PARAMETER: /* CP_UTF8 or MB_ERR_INVALID_CHARS is not supported */
65 case ERROR_INVALID_FLAGS: /* CP_UTF8 or MB_ERR_INVALID_CHARS is not supported */
66 errno = ENOSYS;
67 *wptr = NULL;
68 if (buflen != NULL) *buflen = 0;
69 return 0;
70 case NO_ERROR:
71 if (len == 0)
72 break;
73 /* fallthrough */
74 default:
75 errno = EINVAL;
76 *wptr = NULL;
77 if (buflen != NULL) *buflen = 0;
78 return 0;
79 }
80 }
81 buf = calloc(len + 1, sizeof (wchar_t)); /* Allocate memory accordingly */
82
83 if(!buf) len = 0;
84 else {
85 if (len != 0) {
86 ret = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS, mbptr, -1, buf, len); /* Do conversion */
87 if (ret < 0 || (ret == 0 && GetLastError() != NO_ERROR)) {
88 free(buf);
89 errno = EINVAL;
90 *wptr = NULL;
91 if (buflen != NULL) *buflen = 0;
92 return 0;
93 }
94 }
95 buf[len] = L'\0'; /* Must terminate */
96 }
97 *wptr = buf; /* Set string pointer to allocated buffer */
98 if (buflen != NULL) *buflen = len * sizeof (wchar_t); /* Give length of allocated memory if needed. */
99 return ret; /* Number of characters written */
100}
101
102void __cdecl __mingw_str_free(void *ptr)
103{
104 if (ptr) free(ptr);
105}