Files correlati : Commento : Spostamento in libraries delle librerie esterne di Campo per una maggiore pulizia e organizzazione git-svn-id: svn://10.65.10.50/branches/R_10_00@24150 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			323 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			323 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***************************************************************************
 | |
|  *                                  _   _ ____  _
 | |
|  *  Project                     ___| | | |  _ \| |
 | |
|  *                             / __| | | | |_) | |
 | |
|  *                            | (__| |_| |  _ <| |___
 | |
|  *                             \___|\___/|_| \_\_____|
 | |
|  *
 | |
|  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
 | |
|  *
 | |
|  * This software is licensed as described in the file COPYING, which
 | |
|  * you should have received as part of this distribution. The terms
 | |
|  * are also available at https://curl.haxx.se/docs/copyright.html.
 | |
|  *
 | |
|  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 | |
|  * copies of the Software, and permit persons to whom the Software is
 | |
|  * furnished to do so, under the terms of the COPYING file.
 | |
|  *
 | |
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 | |
|  * KIND, either express or implied.
 | |
|  *
 | |
|  ***************************************************************************/
 | |
| 
 | |
| #include "curl_setup.h"
 | |
| 
 | |
| #ifdef CURL_DOES_CONVERSIONS
 | |
| 
 | |
| #include <curl/curl.h>
 | |
| 
 | |
| #include "non-ascii.h"
 | |
| #include "formdata.h"
 | |
| #include "sendf.h"
 | |
| #include "urldata.h"
 | |
| 
 | |
| #include "curl_memory.h"
 | |
| /* The last #include file should be: */
 | |
| #include "memdebug.h"
 | |
| 
 | |
| #ifdef HAVE_ICONV
 | |
| #include <iconv.h>
 | |
| /* set default codesets for iconv */
 | |
| #ifndef CURL_ICONV_CODESET_OF_NETWORK
 | |
| #define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
 | |
| #endif
 | |
| #ifndef CURL_ICONV_CODESET_FOR_UTF8
 | |
| #define CURL_ICONV_CODESET_FOR_UTF8   "UTF-8"
 | |
| #endif
 | |
| #define ICONV_ERROR  (size_t)-1
 | |
| #endif /* HAVE_ICONV */
 | |
| 
 | |
| /*
 | |
|  * Curl_convert_clone() returns a malloced copy of the source string (if
 | |
|  * returning CURLE_OK), with the data converted to network format.
 | |
|  */
 | |
| CURLcode Curl_convert_clone(struct Curl_easy *data,
 | |
|                            const char *indata,
 | |
|                            size_t insize,
 | |
|                            char **outbuf)
 | |
| {
 | |
|   char *convbuf;
 | |
|   CURLcode result;
 | |
| 
 | |
|   convbuf = malloc(insize);
 | |
|   if(!convbuf)
 | |
|     return CURLE_OUT_OF_MEMORY;
 | |
| 
 | |
|   memcpy(convbuf, indata, insize);
 | |
|   result = Curl_convert_to_network(data, convbuf, insize);
 | |
|   if(result) {
 | |
|     free(convbuf);
 | |
|     return result;
 | |
|   }
 | |
| 
 | |
|   *outbuf = convbuf; /* return the converted buffer */
 | |
| 
 | |
|   return CURLE_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Curl_convert_to_network() is an internal function for performing ASCII
 | |
|  * conversions on non-ASCII platforms. It convers the buffer _in place_.
 | |
|  */
 | |
| CURLcode Curl_convert_to_network(struct Curl_easy *data,
 | |
|                                  char *buffer, size_t length)
 | |
| {
 | |
|   if(data && data->set.convtonetwork) {
 | |
|     /* use translation callback */
 | |
|     CURLcode result = data->set.convtonetwork(buffer, length);
 | |
|     if(result) {
 | |
|       failf(data,
 | |
|             "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
 | |
|             (int)result, curl_easy_strerror(result));
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
|   }
 | |
|   else {
 | |
| #ifdef HAVE_ICONV
 | |
|     /* do the translation ourselves */
 | |
|     iconv_t tmpcd = (iconv_t) -1;
 | |
|     iconv_t *cd = &tmpcd;
 | |
|     char *input_ptr, *output_ptr;
 | |
|     size_t in_bytes, out_bytes, rc;
 | |
| 
 | |
|     /* open an iconv conversion descriptor if necessary */
 | |
|     if(data)
 | |
|       cd = &data->outbound_cd;
 | |
|     if(*cd == (iconv_t)-1) {
 | |
|       *cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
 | |
|                        CURL_ICONV_CODESET_OF_HOST);
 | |
|       if(*cd == (iconv_t)-1) {
 | |
|         failf(data,
 | |
|               "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
 | |
|               CURL_ICONV_CODESET_OF_NETWORK,
 | |
|               CURL_ICONV_CODESET_OF_HOST,
 | |
|               errno, strerror(errno));
 | |
|         return CURLE_CONV_FAILED;
 | |
|       }
 | |
|     }
 | |
|     /* call iconv */
 | |
|     input_ptr = output_ptr = buffer;
 | |
|     in_bytes = out_bytes = length;
 | |
|     rc = iconv(*cd, &input_ptr, &in_bytes,
 | |
|                &output_ptr, &out_bytes);
 | |
|     if(!data)
 | |
|       iconv_close(tmpcd);
 | |
|     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
 | |
|       failf(data,
 | |
|             "The Curl_convert_to_network iconv call failed with errno %i: %s",
 | |
|             errno, strerror(errno));
 | |
|       return CURLE_CONV_FAILED;
 | |
|     }
 | |
| #else
 | |
|     failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
 | |
|     return CURLE_CONV_REQD;
 | |
| #endif /* HAVE_ICONV */
 | |
|   }
 | |
| 
 | |
|   return CURLE_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Curl_convert_from_network() is an internal function for performing ASCII
 | |
|  * conversions on non-ASCII platforms. It convers the buffer _in place_.
 | |
|  */
 | |
| CURLcode Curl_convert_from_network(struct Curl_easy *data,
 | |
|                                    char *buffer, size_t length)
 | |
| {
 | |
|   if(data && data->set.convfromnetwork) {
 | |
|     /* use translation callback */
 | |
|     CURLcode result = data->set.convfromnetwork(buffer, length);
 | |
|     if(result) {
 | |
|       failf(data,
 | |
|             "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
 | |
|             (int)result, curl_easy_strerror(result));
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
|   }
 | |
|   else {
 | |
| #ifdef HAVE_ICONV
 | |
|     /* do the translation ourselves */
 | |
|     iconv_t tmpcd = (iconv_t) -1;
 | |
|     iconv_t *cd = &tmpcd;
 | |
|     char *input_ptr, *output_ptr;
 | |
|     size_t in_bytes, out_bytes, rc;
 | |
| 
 | |
|     /* open an iconv conversion descriptor if necessary */
 | |
|     if(data)
 | |
|       cd = &data->inbound_cd;
 | |
|     if(*cd == (iconv_t)-1) {
 | |
|       *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 | |
|                        CURL_ICONV_CODESET_OF_NETWORK);
 | |
|       if(*cd == (iconv_t)-1) {
 | |
|         failf(data,
 | |
|               "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
 | |
|               CURL_ICONV_CODESET_OF_HOST,
 | |
|               CURL_ICONV_CODESET_OF_NETWORK,
 | |
|               errno, strerror(errno));
 | |
|         return CURLE_CONV_FAILED;
 | |
|       }
 | |
|     }
 | |
|     /* call iconv */
 | |
|     input_ptr = output_ptr = buffer;
 | |
|     in_bytes = out_bytes = length;
 | |
|     rc = iconv(*cd, &input_ptr, &in_bytes,
 | |
|                &output_ptr, &out_bytes);
 | |
|     if(!data)
 | |
|       iconv_close(tmpcd);
 | |
|     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
 | |
|       failf(data,
 | |
|             "Curl_convert_from_network iconv call failed with errno %i: %s",
 | |
|             errno, strerror(errno));
 | |
|       return CURLE_CONV_FAILED;
 | |
|     }
 | |
| #else
 | |
|     failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
 | |
|     return CURLE_CONV_REQD;
 | |
| #endif /* HAVE_ICONV */
 | |
|   }
 | |
| 
 | |
|   return CURLE_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Curl_convert_from_utf8() is an internal function for performing UTF-8
 | |
|  * conversions on non-ASCII platforms.
 | |
|  */
 | |
| CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
 | |
|                                 char *buffer, size_t length)
 | |
| {
 | |
|   if(data && data->set.convfromutf8) {
 | |
|     /* use translation callback */
 | |
|     CURLcode result = data->set.convfromutf8(buffer, length);
 | |
|     if(result) {
 | |
|       failf(data,
 | |
|             "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
 | |
|             (int)result, curl_easy_strerror(result));
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
|   }
 | |
|   else {
 | |
| #ifdef HAVE_ICONV
 | |
|     /* do the translation ourselves */
 | |
|     iconv_t tmpcd = (iconv_t) -1;
 | |
|     iconv_t *cd = &tmpcd;
 | |
|     char *input_ptr;
 | |
|     char *output_ptr;
 | |
|     size_t in_bytes, out_bytes, rc;
 | |
| 
 | |
|     /* open an iconv conversion descriptor if necessary */
 | |
|     if(data)
 | |
|       cd = &data->utf8_cd;
 | |
|     if(*cd == (iconv_t)-1) {
 | |
|       *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 | |
|                        CURL_ICONV_CODESET_FOR_UTF8);
 | |
|       if(*cd == (iconv_t)-1) {
 | |
|         failf(data,
 | |
|               "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
 | |
|               CURL_ICONV_CODESET_OF_HOST,
 | |
|               CURL_ICONV_CODESET_FOR_UTF8,
 | |
|               errno, strerror(errno));
 | |
|         return CURLE_CONV_FAILED;
 | |
|       }
 | |
|     }
 | |
|     /* call iconv */
 | |
|     input_ptr = output_ptr = buffer;
 | |
|     in_bytes = out_bytes = length;
 | |
|     rc = iconv(*cd, &input_ptr, &in_bytes,
 | |
|                &output_ptr, &out_bytes);
 | |
|     if(!data)
 | |
|       iconv_close(tmpcd);
 | |
|     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
 | |
|       failf(data,
 | |
|             "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
 | |
|             errno, strerror(errno));
 | |
|       return CURLE_CONV_FAILED;
 | |
|     }
 | |
|     if(output_ptr < input_ptr) {
 | |
|       /* null terminate the now shorter output string */
 | |
|       *output_ptr = 0x00;
 | |
|     }
 | |
| #else
 | |
|     failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
 | |
|     return CURLE_CONV_REQD;
 | |
| #endif /* HAVE_ICONV */
 | |
|   }
 | |
| 
 | |
|   return CURLE_OK;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Init conversion stuff for a Curl_easy
 | |
|  */
 | |
| void Curl_convert_init(struct Curl_easy *data)
 | |
| {
 | |
| #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
 | |
|   /* conversion descriptors for iconv calls */
 | |
|   data->outbound_cd = (iconv_t)-1;
 | |
|   data->inbound_cd  = (iconv_t)-1;
 | |
|   data->utf8_cd     = (iconv_t)-1;
 | |
| #else
 | |
|   (void)data;
 | |
| #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Setup conversion stuff for a Curl_easy
 | |
|  */
 | |
| void Curl_convert_setup(struct Curl_easy *data)
 | |
| {
 | |
|   data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 | |
|                                 CURL_ICONV_CODESET_OF_NETWORK);
 | |
|   data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
 | |
|                                  CURL_ICONV_CODESET_OF_HOST);
 | |
|   data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
 | |
|                              CURL_ICONV_CODESET_FOR_UTF8);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Close conversion stuff for a Curl_easy
 | |
|  */
 | |
| 
 | |
| void Curl_convert_close(struct Curl_easy *data)
 | |
| {
 | |
| #ifdef HAVE_ICONV
 | |
|   /* close iconv conversion descriptors */
 | |
|   if(data->inbound_cd != (iconv_t)-1) {
 | |
|     iconv_close(data->inbound_cd);
 | |
|   }
 | |
|   if(data->outbound_cd != (iconv_t)-1) {
 | |
|     iconv_close(data->outbound_cd);
 | |
|   }
 | |
|   if(data->utf8_cd != (iconv_t)-1) {
 | |
|     iconv_close(data->utf8_cd);
 | |
|   }
 | |
| #else
 | |
|   (void)data;
 | |
| #endif /* HAVE_ICONV */
 | |
| }
 | |
| 
 | |
| #endif /* CURL_DOES_CONVERSIONS */
 |