39 #include <freetds/tds.h>
40 #include <freetds/iconv.h>
45 #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
46 (charset)->min_bytes_per_char : 0 )
64 #define TDS_ICONV_ENCODING_TABLES
68 static const char *
iconv_names[
sizeof(canonic_charsets) /
sizeof(canonic_charsets[0])];
102 for (
i = 0; iconv_aliases[
i].alias; ++
i) {
105 if (iconv_aliases[
i].canonic !=
POS_ISO1)
107 for (j = 0; iconv_aliases[j].alias; ++j) {
108 if (iconv_aliases[j].canonic !=
POS_UTF8)
141 for (
i = 0; iconv_aliases[
i].alias; ++
i) {
142 if (
strncmp(canonic_charsets[iconv_aliases[
i].canonic].name,
"UCS-2", 5) != 0)
152 int byte_sequence = 0;
161 if (
tds_sys_iconv(cd, &pib, &il, &pob, &ol) != (
size_t) - 1) {
187 for (
i = 0;
i < 4; ++
i)
204 #ifdef TDS_HAVE_MUTEX
212 iconv_names[charset] = canonic_charsets[charset].name;
214 #ifdef TDS_HAVE_MUTEX
221 iconv_names[charset] = canonic_charsets[charset].name;
223 #ifdef TDS_HAVE_MUTEX
230 for (
i = 0; iconv_aliases[
i].alias; ++
i) {
231 if (iconv_aliases[
i].canonic != charset)
238 #ifdef TDS_HAVE_MUTEX
248 #ifdef TDS_HAVE_MUTEX
257 #ifdef TDS_HAVE_MUTEX
270 conv->to.charset.min_bytes_per_char = 1;
271 conv->to.charset.max_bytes_per_char = 1;
302 conn->char_convs[
i] = &char_conv[
i];
337 static const char UCS_2LE[] =
"UCS-2LE";
349 #ifdef TDS_HAVE_MUTEX
354 static const char names[][12] = {
"ISO 8859-1",
"UTF-8" };
357 "could not find a name for %s that your iconv accepts.\n"
358 "use: \"configure --disable-libiconv\"", ret,
names[ret-1]);
359 #ifdef TDS_HAVE_MUTEX
366 #ifdef TDS_HAVE_MUTEX
395 client->max_bytes_per_char = 3;
404 if (canonic_env_charset >= 0) {
436 if (client_canonical < 0) {
441 if (server_canonical < 0) {
446 *
client = canonic_charsets[client_canonical];
447 *server = canonic_charsets[server_canonical];
450 if (client_canonical == server_canonical) {
451 char_conv->to.cd = (
iconv_t) -1;
457 char_conv->
flags = 0;
475 if (char_conv->to.cd == (
iconv_t) -1) {
497 if (*cd != invalid) {
515 for (
i = 0;
i <
conn->char_conv_count; ++
i)
519 #define CHUNK_ALLOC 4
526 if (!
conn->char_convs)
534 conn->char_conv_count = 0;
577 const char **
inbuf,
size_t * inbytesleft,
char **
outbuf,
size_t * outbytesleft)
585 char quest_mark[] =
"?";
589 size_t one_character;
590 int eilseq_raised = 0;
602 if (*inbytesleft == 0)
622 size_t len = *inbytesleft < *outbytesleft ? *inbytesleft : *outbytesleft;
625 errno = *inbytesleft > *outbytesleft ? E2BIG : 0;
627 *outbytesleft -=
len;
641 if (irreversible != (
size_t) - 1) {
642 if (irreversible > 0) {
680 if (error_cd == invalid) {
682 if (error_cd == invalid) {
688 pquest_mark = quest_mark;
692 if (irreversible == (
size_t) - 1)
699 if (eilseq_raised && !suppress->
eilseq) {
702 if (irreversible == (
size_t) - 1) {
714 switch (conv_errno) {
732 if (error_cd != invalid) {
751 if (canonic_client ==
conn->char_convs[
i]->from.charset.canonic
752 && canonic_server ==
conn->char_convs[
i]->to.charset.canonic)
753 return conn->char_convs[
i];
768 conn->char_convs = p;
771 conn->char_convs[
i +
conn->char_conv_count] = &infos[
i];
782 --
conn->char_conv_count;
792 if (canonic_client_charset_num < 0) {
796 if (canonic_server_charset_num < 0) {
813 tdsdump_log(
TDS_DBG_FUNC,
"setting server single-byte charset to \"%s\"\n", canonic_charsets[canonic_charset_num].name);
815 if (canonic_charset_num == char_conv->to.charset.canonic)
854 unsigned charsize =
CHARSIZE(charset);
865 if (charsize > *input_size)
868 *input_size -= charsize;
886 }
while ((c <<= 1) & 0x80);
887 if (charsize > *input_size)
890 *input_size -= charsize;
909 if (il > *input_size)
912 memcpy(ib +
l, *
input, il);
934 il =
sizeof(ib) - ol;
949 for (
i = 0; aliases[
i].
alias; ++
i) {
950 if (0 ==
strcmp(charset_name, aliases[
i].alias))
989 return canonic_charsets[res].name;
1004 switch (sql_collate) {
1050 switch (lcid & 0xffff) {
1237 const int sql_collate = collate[4];
1238 const int lcid = collate[1] * 256 + collate[0];
static CS_CONNECTION * conn
static const struct name_t names[]
#define TDS_ENCODING_MEMCPY
@ initial_char_conv_count
#define tds_new0(type, n)
#define tds_mutex_lock(x)
#define tds_mutex_unlock(x)
static const char * tds_set_iconv_name(int charset)
Get iconv name given canonic.
int tds_iconv_alloc(TDSCONNECTION *conn)
Allocate iconv stuff.
static void tds_iconv_reset(TDSICONV *conv)
static const char * iconv_names[sizeof(canonic_charsets)/sizeof(canonic_charsets[0])]
static const char * ucs2name
static int tds_iconv_init(void)
Initialize charset searching for UTF-8, UCS-2 and ISO8859-1.
static int iconv_initialized
#define CHARSIZE(charset)
#define TDS_MUTEX_INITIALIZER
static tds_mutex iconv_mtx
static int collate2charset(int sql_collate, int lcid)
TDSRET tds_iconv_open(TDSCONNECTION *conn, const char *charset, int use_utf16)
static size_t skip_one_input_sequence(iconv_t cd, const TDS_ENCODING *charset, const char **input, size_t *input_size)
Move the input sequence pointer to the next valid position.
static int tds_canonical_charset(const char *charset_name)
Determine canonical iconv character set.
static int tds_iconv_info_init(TDSICONV *char_conv, int client_canonic, int server_canonic)
Open iconv descriptors to convert between character sets (both directions).
void tds_iconv_close(TDSCONNECTION *conn)
void tds_srv_charset_changed(TDSCONNECTION *conn, const char *charset)
const char * tds_canonical_charset_name(const char *charset_name)
Determine canonical iconv character set name.
size_t tds_sys_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
size_t tds_iconv(TDSSOCKET *tds, TDSICONV *conv, TDS_ICONV_DIRECTION io, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Wrapper around iconv(3).
iconv_t tds_sys_iconv_open(const char *tocode, const char *fromcode)
Inputs are FreeTDS canonical names, no other.
TDSICONV * tds_iconv_get(TDSCONNECTION *conn, const char *client_charset, const char *server_charset)
static void tds_srv_charset_changed_num(TDSCONNECTION *conn, int canonic_charset_num)
static void _iconv_close(iconv_t *cd)
static TDSICONV * tds_iconv_get_info(TDSCONNECTION *conn, int canonic_client, int canonic_server)
Get a iconv info structure, allocate and initialize if needed.
static void tds_iconv_info_close(TDSICONV *char_conv)
static int lookup_canonic(const CHARACTER_SET_ALIAS aliases[], const char *charset_name)
void tds7_srv_charset_changed(TDSCONNECTION *conn, int sql_collate, int lcid)
void tds_iconv_free(TDSCONNECTION *conn)
static void tds_iconv_err(TDSSOCKET *tds, int err)
int tds_sys_iconv_close(iconv_t cd)
TDSICONV * tds_iconv_from_collate(TDSCONNECTION *conn, TDS_UCHAR collate[5])
Get iconv information from a LCID (to support different column encoding under MSSQL2K)
int strncmp(const char *str1, const char *str2, size_t count)
int strcmp(const char *str1, const char *str2)
static SLJIT_INLINE sljit_ins l(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
static CNamedPipeClient * client
Information relevant to libiconv.
unsigned char max_bytes_per_char
const char * name
name of the encoding (ie UTF-8)
unsigned char min_bytes_per_char
unsigned char canonic
internal numeric index into array of all encodings
Information for a server connection.
struct tdsiconvdir to from
TDS_ERRNO_MESSAGE_FLAGS suppress
uchar outbuf[(1000000+1000000)]