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