|
Packit Service |
17f749 |
/****************************************************************************
|
|
Packit Service |
17f749 |
Copyright (C) 2012, 2020, MariaDB Corporation.
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
This library is free software; you can redistribute it and/or
|
|
Packit Service |
17f749 |
modify it under the terms of the GNU Library General Public
|
|
Packit Service |
17f749 |
License as published by the Free Software Foundation; either
|
|
Packit Service |
17f749 |
version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
This library is distributed in the hope that it will be useful,
|
|
Packit Service |
17f749 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
17f749 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
17f749 |
Library General Public License for more details.
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
You should have received a copy of the GNU Library General Public
|
|
Packit Service |
17f749 |
License along with this library; if not see <http://www.gnu.org/licenses>
|
|
Packit Service |
17f749 |
or write to the Free Software Foundation, Inc.,
|
|
Packit Service |
17f749 |
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
Part of this code includes code from the PHP project which
|
|
Packit Service |
17f749 |
is freely available from http://www.php.net
|
|
Packit Service |
17f749 |
*****************************************************************************/
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
#ifndef _WIN32
|
|
Packit Service |
17f749 |
#include <strings.h>
|
|
Packit Service |
17f749 |
#include <string.h>
|
|
Packit Service |
17f749 |
#include <iconv.h>
|
|
Packit Service |
17f749 |
#include <errno.h>
|
|
Packit Service |
17f749 |
#else
|
|
Packit Service |
17f749 |
#include <string.h>
|
|
Packit Service |
17f749 |
#endif
|
|
Packit Service |
17f749 |
#include <ma_odbc.h>
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
#if defined(SOLARIS) || defined(__sun)
|
|
Packit Service |
17f749 |
#define IF_SOLARIS(A,B) A
|
|
Packit Service |
17f749 |
#else
|
|
Packit Service |
17f749 |
#define IF_SOLARIS(A,B) B
|
|
Packit Service |
17f749 |
#endif
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
#define HAVE_ICONV
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
#ifdef HAVE_ICONV
|
|
Packit Service |
17f749 |
/* {{{ MADB_MapCharsetName
|
|
Packit Service |
17f749 |
Changing charset name into something iconv understands, if necessary.
|
|
Packit Service |
17f749 |
Another purpose it to avoid BOMs in result string, adding BE if necessary
|
|
Packit Service |
17f749 |
e.g.UTF16 does not work form iconv, while UTF-16 does.
|
|
Packit Service |
17f749 |
*/
|
|
Packit Service |
17f749 |
static void MADB_MapCharsetName(const char *cs_name, my_bool target_cs, char *buffer, size_t buff_len)
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
char digits[3], endianness[3]= "BE";
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
if (sscanf(cs_name, "UTF%2[0-9]%2[LBE]", digits, endianness))
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
/* We should have at least digits. Endianness we write either default(BE), or what we found in the string */
|
|
Packit Service |
17f749 |
snprintf(buffer, buff_len, "UTF-%s%s", digits, endianness);
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
else
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
/* Not our client - copy as is*/
|
|
Packit Service |
17f749 |
strncpy(buffer, cs_name, buff_len - 1);
|
|
Packit Service |
17f749 |
buffer[buff_len - 1]= '\0';
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
if (target_cs)
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
strncat(buffer, "//TRANSLIT", buff_len - strlen(buffer));
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
/* }}} */
|
|
Packit Service |
17f749 |
#endif
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
/* {{{ MADB_ConvertString
|
|
Packit Service |
17f749 |
Converts string from one charset to another, and writes converted string to given buffer
|
|
Packit Service |
17f749 |
@param[in] from
|
|
Packit Service |
17f749 |
@param[in/out] from_len
|
|
Packit Service |
17f749 |
@param[in] from_cs
|
|
Packit Service |
17f749 |
@param[out] to
|
|
Packit Service |
17f749 |
@param[in/out] to_len
|
|
Packit Service |
17f749 |
@param[in] to_cs
|
|
Packit Service |
17f749 |
@param[out] errorcode
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
@return -1 in case of error, bytes used in the "to" buffer, otherwise
|
|
Packit Service |
17f749 |
*/
|
|
Packit Service |
17f749 |
size_t STDCALL MADB_ConvertString(const char *from __attribute__((unused)),
|
|
Packit Service |
17f749 |
size_t *from_len __attribute__((unused)),
|
|
Packit Service |
17f749 |
MARIADB_CHARSET_INFO *from_cs __attribute__((unused)),
|
|
Packit Service |
17f749 |
char *to __attribute__((unused)),
|
|
Packit Service |
17f749 |
size_t *to_len __attribute__((unused)),
|
|
Packit Service |
17f749 |
MARIADB_CHARSET_INFO *to_cs __attribute__((unused)), int *errorcode)
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
#ifndef HAVE_ICONV
|
|
Packit Service |
17f749 |
*errorcode= ENOTSUP;
|
|
Packit Service |
17f749 |
return -1;
|
|
Packit Service |
17f749 |
#else
|
|
Packit Service |
17f749 |
iconv_t conv= 0;
|
|
Packit Service |
17f749 |
size_t rc= -1;
|
|
Packit Service |
17f749 |
size_t save_len= *to_len;
|
|
Packit Service |
17f749 |
char to_encoding[128], from_encoding[128];
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
*errorcode= 0;
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
/* check if conversion is supported */
|
|
Packit Service |
17f749 |
if (!from_cs || !from_cs->encoding || !from_cs->encoding[0] ||
|
|
Packit Service |
17f749 |
!to_cs || !to_cs->encoding || !to_cs->encoding[0])
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
*errorcode= EINVAL;
|
|
Packit Service |
17f749 |
return rc;
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
MADB_MapCharsetName(to_cs->encoding, 1, to_encoding, sizeof(to_encoding));
|
|
Packit Service |
17f749 |
MADB_MapCharsetName(from_cs->encoding, 0, from_encoding, sizeof(from_encoding));
|
|
Packit Service |
17f749 |
|
|
Packit Service |
17f749 |
if ((conv= iconv_open(to_encoding, from_encoding)) == (iconv_t)-1)
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
*errorcode= errno;
|
|
Packit Service |
17f749 |
goto error;
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
if ((rc= iconv(conv, IF_SOLARIS(,(char **))&from, from_len, &to, to_len)) == (size_t)-1)
|
|
Packit Service |
17f749 |
{
|
|
Packit Service |
17f749 |
*errorcode= errno;
|
|
Packit Service |
17f749 |
goto error;
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
rc= save_len - *to_len;
|
|
Packit Service |
17f749 |
error:
|
|
Packit Service |
17f749 |
if (conv != (iconv_t)-1)
|
|
Packit Service |
17f749 |
iconv_close(conv);
|
|
Packit Service |
17f749 |
return rc;
|
|
Packit Service |
17f749 |
#endif
|
|
Packit Service |
17f749 |
}
|
|
Packit Service |
17f749 |
/* }}} */
|
|
Packit Service |
17f749 |
|