xref: /curl/lib/curl_multibyte.c (revision 22cde3ba)
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 
curlx_convert_UTF8_to_wchar(const char * str_utf8)43 wchar_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 
curlx_convert_wchar_to_UTF8(const wchar_t * str_w)65 char *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 
curlx_win32_open(const char * filename,int oflag,...)91 int 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 
curlx_win32_fopen(const char * filename,const char * mode)119 FILE *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 
curlx_win32_stat(const char * path,struct_stat * buffer)137 int 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 
162 #endif /* USE_WIN32_LARGE_FILES || USE_WIN32_SMALL_FILES */
163