xref: /third_party/curl/lib/curl_multibyte.c (revision 13498266)
1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25/*
26 * This file is 'mem-include-scan' clean, which means memdebug.h and
27 * curl_memory.h are purposely not included in this file. See test 1132.
28 *
29 * The functions in this file are curlx functions which are not tracked by the
30 * curl memory tracker memdebug.
31 */
32
33#include "curl_setup.h"
34
35#if defined(_WIN32)
36
37#include "curl_multibyte.h"
38
39/*
40 * MultiByte conversions using Windows kernel32 library.
41 */
42
43wchar_t *curlx_convert_UTF8_to_wchar(const char *str_utf8)
44{
45  wchar_t *str_w = NULL;
46
47  if(str_utf8) {
48    int str_w_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
49                                        str_utf8, -1, NULL, 0);
50    if(str_w_len > 0) {
51      str_w = malloc(str_w_len * sizeof(wchar_t));
52      if(str_w) {
53        if(MultiByteToWideChar(CP_UTF8, 0, str_utf8, -1, str_w,
54                               str_w_len) == 0) {
55          free(str_w);
56          return NULL;
57        }
58      }
59    }
60  }
61
62  return str_w;
63}
64
65char *curlx_convert_wchar_to_UTF8(const wchar_t *str_w)
66{
67  char *str_utf8 = NULL;
68
69  if(str_w) {
70    int bytes = WideCharToMultiByte(CP_UTF8, 0, str_w, -1,
71                                    NULL, 0, NULL, NULL);
72    if(bytes > 0) {
73      str_utf8 = malloc(bytes);
74      if(str_utf8) {
75        if(WideCharToMultiByte(CP_UTF8, 0, str_w, -1, str_utf8, bytes,
76                               NULL, NULL) == 0) {
77          free(str_utf8);
78          return NULL;
79        }
80      }
81    }
82  }
83
84  return str_utf8;
85}
86
87#endif /* _WIN32 */
88
89#if defined(USE_WIN32_LARGE_FILES) || defined(USE_WIN32_SMALL_FILES)
90
91int curlx_win32_open(const char *filename, int oflag, ...)
92{
93  int pmode = 0;
94
95#ifdef _UNICODE
96  int result = -1;
97  wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
98#endif
99
100  va_list param;
101  va_start(param, oflag);
102  if(oflag & O_CREAT)
103    pmode = va_arg(param, int);
104  va_end(param);
105
106#ifdef _UNICODE
107  if(filename_w) {
108    result = _wopen(filename_w, oflag, pmode);
109    curlx_unicodefree(filename_w);
110  }
111  else
112    errno = EINVAL;
113  return result;
114#else
115  return (_open)(filename, oflag, pmode);
116#endif
117}
118
119FILE *curlx_win32_fopen(const char *filename, const char *mode)
120{
121#ifdef _UNICODE
122  FILE *result = NULL;
123  wchar_t *filename_w = curlx_convert_UTF8_to_wchar(filename);
124  wchar_t *mode_w = curlx_convert_UTF8_to_wchar(mode);
125  if(filename_w && mode_w)
126    result = _wfopen(filename_w, mode_w);
127  else
128    errno = EINVAL;
129  curlx_unicodefree(filename_w);
130  curlx_unicodefree(mode_w);
131  return result;
132#else
133  return (fopen)(filename, mode);
134#endif
135}
136
137int curlx_win32_stat(const char *path, struct_stat *buffer)
138{
139#ifdef _UNICODE
140  int result = -1;
141  wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
142  if(path_w) {
143#if defined(USE_WIN32_SMALL_FILES)
144    result = _wstat(path_w, buffer);
145#else
146    result = _wstati64(path_w, buffer);
147#endif
148    curlx_unicodefree(path_w);
149  }
150  else
151    errno = EINVAL;
152  return result;
153#else
154#if defined(USE_WIN32_SMALL_FILES)
155  return _stat(path, buffer);
156#else
157  return _stati64(path, buffer);
158#endif
159#endif
160}
161
162int curlx_win32_access(const char *path, int mode)
163{
164#if defined(_UNICODE)
165  int result = -1;
166  wchar_t *path_w = curlx_convert_UTF8_to_wchar(path);
167  if(path_w) {
168    result = _waccess(path_w, mode);
169    curlx_unicodefree(path_w);
170  }
171  else
172    errno = EINVAL;
173  return result;
174#else
175  return _access(path, mode);
176#endif
177}
178
179#endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
180