source: azure_iot_hub/trunk/curl-7.57.0/lib/non-ascii.c@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 9.3 KB
Line 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2017, 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.haxx.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 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#ifdef CURL_DOES_CONVERSIONS
26
27#include <curl/curl.h>
28
29#include "non-ascii.h"
30#include "formdata.h"
31#include "sendf.h"
32#include "urldata.h"
33
34#include "curl_memory.h"
35/* The last #include file should be: */
36#include "memdebug.h"
37
38#ifdef HAVE_ICONV
39#include <iconv.h>
40/* set default codesets for iconv */
41#ifndef CURL_ICONV_CODESET_OF_NETWORK
42#define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
43#endif
44#ifndef CURL_ICONV_CODESET_FOR_UTF8
45#define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
46#endif
47#define ICONV_ERROR (size_t)-1
48#endif /* HAVE_ICONV */
49
50/*
51 * Curl_convert_clone() returns a malloced copy of the source string (if
52 * returning CURLE_OK), with the data converted to network format.
53 */
54CURLcode Curl_convert_clone(struct Curl_easy *data,
55 const char *indata,
56 size_t insize,
57 char **outbuf)
58{
59 char *convbuf;
60 CURLcode result;
61
62 convbuf = malloc(insize);
63 if(!convbuf)
64 return CURLE_OUT_OF_MEMORY;
65
66 memcpy(convbuf, indata, insize);
67 result = Curl_convert_to_network(data, convbuf, insize);
68 if(result) {
69 free(convbuf);
70 return result;
71 }
72
73 *outbuf = convbuf; /* return the converted buffer */
74
75 return CURLE_OK;
76}
77
78/*
79 * Curl_convert_to_network() is an internal function for performing ASCII
80 * conversions on non-ASCII platforms. It convers the buffer _in place_.
81 */
82CURLcode Curl_convert_to_network(struct Curl_easy *data,
83 char *buffer, size_t length)
84{
85 if(data && data->set.convtonetwork) {
86 /* use translation callback */
87 CURLcode result = data->set.convtonetwork(buffer, length);
88 if(result) {
89 failf(data,
90 "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
91 (int)result, curl_easy_strerror(result));
92 }
93
94 return result;
95 }
96 else {
97#ifdef HAVE_ICONV
98 /* do the translation ourselves */
99 iconv_t tmpcd = (iconv_t) -1;
100 iconv_t *cd = &tmpcd;
101 char *input_ptr, *output_ptr;
102 size_t in_bytes, out_bytes, rc;
103
104 /* open an iconv conversion descriptor if necessary */
105 if(data)
106 cd = &data->outbound_cd;
107 if(*cd == (iconv_t)-1) {
108 *cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
109 CURL_ICONV_CODESET_OF_HOST);
110 if(*cd == (iconv_t)-1) {
111 failf(data,
112 "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
113 CURL_ICONV_CODESET_OF_NETWORK,
114 CURL_ICONV_CODESET_OF_HOST,
115 errno, strerror(errno));
116 return CURLE_CONV_FAILED;
117 }
118 }
119 /* call iconv */
120 input_ptr = output_ptr = buffer;
121 in_bytes = out_bytes = length;
122 rc = iconv(*cd, &input_ptr, &in_bytes,
123 &output_ptr, &out_bytes);
124 if(!data)
125 iconv_close(tmpcd);
126 if((rc == ICONV_ERROR) || (in_bytes != 0)) {
127 failf(data,
128 "The Curl_convert_to_network iconv call failed with errno %i: %s",
129 errno, strerror(errno));
130 return CURLE_CONV_FAILED;
131 }
132#else
133 failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
134 return CURLE_CONV_REQD;
135#endif /* HAVE_ICONV */
136 }
137
138 return CURLE_OK;
139}
140
141/*
142 * Curl_convert_from_network() is an internal function for performing ASCII
143 * conversions on non-ASCII platforms. It convers the buffer _in place_.
144 */
145CURLcode Curl_convert_from_network(struct Curl_easy *data,
146 char *buffer, size_t length)
147{
148 if(data && data->set.convfromnetwork) {
149 /* use translation callback */
150 CURLcode result = data->set.convfromnetwork(buffer, length);
151 if(result) {
152 failf(data,
153 "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
154 (int)result, curl_easy_strerror(result));
155 }
156
157 return result;
158 }
159 else {
160#ifdef HAVE_ICONV
161 /* do the translation ourselves */
162 iconv_t tmpcd = (iconv_t) -1;
163 iconv_t *cd = &tmpcd;
164 char *input_ptr, *output_ptr;
165 size_t in_bytes, out_bytes, rc;
166
167 /* open an iconv conversion descriptor if necessary */
168 if(data)
169 cd = &data->inbound_cd;
170 if(*cd == (iconv_t)-1) {
171 *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
172 CURL_ICONV_CODESET_OF_NETWORK);
173 if(*cd == (iconv_t)-1) {
174 failf(data,
175 "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
176 CURL_ICONV_CODESET_OF_HOST,
177 CURL_ICONV_CODESET_OF_NETWORK,
178 errno, strerror(errno));
179 return CURLE_CONV_FAILED;
180 }
181 }
182 /* call iconv */
183 input_ptr = output_ptr = buffer;
184 in_bytes = out_bytes = length;
185 rc = iconv(*cd, &input_ptr, &in_bytes,
186 &output_ptr, &out_bytes);
187 if(!data)
188 iconv_close(tmpcd);
189 if((rc == ICONV_ERROR) || (in_bytes != 0)) {
190 failf(data,
191 "Curl_convert_from_network iconv call failed with errno %i: %s",
192 errno, strerror(errno));
193 return CURLE_CONV_FAILED;
194 }
195#else
196 failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
197 return CURLE_CONV_REQD;
198#endif /* HAVE_ICONV */
199 }
200
201 return CURLE_OK;
202}
203
204/*
205 * Curl_convert_from_utf8() is an internal function for performing UTF-8
206 * conversions on non-ASCII platforms.
207 */
208CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
209 char *buffer, size_t length)
210{
211 if(data && data->set.convfromutf8) {
212 /* use translation callback */
213 CURLcode result = data->set.convfromutf8(buffer, length);
214 if(result) {
215 failf(data,
216 "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
217 (int)result, curl_easy_strerror(result));
218 }
219
220 return result;
221 }
222 else {
223#ifdef HAVE_ICONV
224 /* do the translation ourselves */
225 iconv_t tmpcd = (iconv_t) -1;
226 iconv_t *cd = &tmpcd;
227 char *input_ptr;
228 char *output_ptr;
229 size_t in_bytes, out_bytes, rc;
230
231 /* open an iconv conversion descriptor if necessary */
232 if(data)
233 cd = &data->utf8_cd;
234 if(*cd == (iconv_t)-1) {
235 *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
236 CURL_ICONV_CODESET_FOR_UTF8);
237 if(*cd == (iconv_t)-1) {
238 failf(data,
239 "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
240 CURL_ICONV_CODESET_OF_HOST,
241 CURL_ICONV_CODESET_FOR_UTF8,
242 errno, strerror(errno));
243 return CURLE_CONV_FAILED;
244 }
245 }
246 /* call iconv */
247 input_ptr = output_ptr = buffer;
248 in_bytes = out_bytes = length;
249 rc = iconv(*cd, &input_ptr, &in_bytes,
250 &output_ptr, &out_bytes);
251 if(!data)
252 iconv_close(tmpcd);
253 if((rc == ICONV_ERROR) || (in_bytes != 0)) {
254 failf(data,
255 "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
256 errno, strerror(errno));
257 return CURLE_CONV_FAILED;
258 }
259 if(output_ptr < input_ptr) {
260 /* null terminate the now shorter output string */
261 *output_ptr = 0x00;
262 }
263#else
264 failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
265 return CURLE_CONV_REQD;
266#endif /* HAVE_ICONV */
267 }
268
269 return CURLE_OK;
270}
271
272/*
273 * Init conversion stuff for a Curl_easy
274 */
275void Curl_convert_init(struct Curl_easy *data)
276{
277#if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
278 /* conversion descriptors for iconv calls */
279 data->outbound_cd = (iconv_t)-1;
280 data->inbound_cd = (iconv_t)-1;
281 data->utf8_cd = (iconv_t)-1;
282#else
283 (void)data;
284#endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
285}
286
287/*
288 * Setup conversion stuff for a Curl_easy
289 */
290void Curl_convert_setup(struct Curl_easy *data)
291{
292 data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
293 CURL_ICONV_CODESET_OF_NETWORK);
294 data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
295 CURL_ICONV_CODESET_OF_HOST);
296 data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
297 CURL_ICONV_CODESET_FOR_UTF8);
298}
299
300/*
301 * Close conversion stuff for a Curl_easy
302 */
303
304void Curl_convert_close(struct Curl_easy *data)
305{
306#ifdef HAVE_ICONV
307 /* close iconv conversion descriptors */
308 if(data->inbound_cd != (iconv_t)-1) {
309 iconv_close(data->inbound_cd);
310 }
311 if(data->outbound_cd != (iconv_t)-1) {
312 iconv_close(data->outbound_cd);
313 }
314 if(data->utf8_cd != (iconv_t)-1) {
315 iconv_close(data->utf8_cd);
316 }
317#else
318 (void)data;
319#endif /* HAVE_ICONV */
320}
321
322#endif /* CURL_DOES_CONVERSIONS */
Note: See TracBrowser for help on using the repository browser.