Skip to Content.
Sympa Menu

freetds - Re: [freetds] iconv message suppression

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Alex Kiesel <kiesel AT schlund.de>
  • To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
  • Subject: Re: [freetds] iconv message suppression
  • Date: Sun, 30 Nov 2003 12:03:39 +0100

On Sun, 2003-11-23 at 10:18, Frediano Ziglio wrote:

> >I committed the ct-lib univarchar patch separately. On faith. No way for
> >me to test.
> >
>
> The same. I don't like some thing in implementation
> - Sybase do not have CS_UNIVARCHAR_TYPE constant but only CS_UNICHAR_TYPE
> - SYBUNIVARCHAR it's not a server type
> - there are no conversion from UTF16 to client

Hi all,

the attached patch improves the uni(var)char support:
. a new TDS_USER_TYPE enum has been added (it contains the usertypes
USER_UNICHAR_TYPE and USER_UNIVARCHAR_TYPE)
. removed the constant SYBUNIVARCHAR
. the columns data now gets properly decoded from UTF-16 to the client
charset (successfully tested with iso-8859-1 and UTF-8).

I'd be happy if someone could look into it.

Thanks,
Alex
? univarchar.diff
Index: include/cspublic.h
===================================================================
RCS file: /home/cvs/mirror/freetds/freetds/include/cspublic.h,v
retrieving revision 1.43
diff -u -r1.43 cspublic.h
--- include/cspublic.h	22 Nov 2003 23:05:09 -0000	1.43
+++ include/cspublic.h	30 Nov 2003 10:56:13 -0000
@@ -737,7 +737,7 @@
 #define CS_VOID_TYPE	25
 #define CS_USHORT_TYPE	26
 #define CS_UNIQUE_TYPE	27
-#define CS_UNIVARCHAR_TYPE  28
+#define CS_UNICHAR_TYPE	28
 
 /* cs_dt_info type values */
 enum
Index: include/tds.h
===================================================================
RCS file: /home/cvs/mirror/freetds/freetds/include/tds.h,v
retrieving revision 1.157
diff -u -r1.157 tds.h
--- include/tds.h	28 Nov 2003 16:53:14 -0000	1.157
+++ include/tds.h	30 Nov 2003 10:56:14 -0000
@@ -415,9 +415,14 @@
 #define SYBUNIQUE	SYBUNIQUE
 	SYBVARIANT = 98, 	/* 0x62 */
 #define SYBVARIANT	SYBVARIANT
-	SYBUNIVARCHAR = -1001
-#define SYBUNIVARCHAR	SYBUNIVARCHAR
 } TDS_SERVER_TYPE;
+
+
+typedef enum
+{
+	USER_UNICHAR_TYPE = 34,		/* 0x22 */
+	USER_UNIVARCHAR_TYPE = 35	/* 0x23 */
+} TDS_USER_TYPE;
 
 #define SYBAOPCNT  0x4b
 #define SYBAOPCNTU 0x4c
Index: src/ctlib/cs.c
===================================================================
RCS file: /home/cvs/mirror/freetds/freetds/src/ctlib/cs.c,v
retrieving revision 1.43
diff -u -r1.43 cs.c
--- src/ctlib/cs.c	22 Nov 2003 23:05:09 -0000	1.43
+++ src/ctlib/cs.c	30 Nov 2003 10:56:15 -0000
@@ -342,7 +342,7 @@
 
 		tdsdump_log(TDS_DBG_FUNC, "%L cs_convert() srctype = desttype\n");
 		switch (desttype) {
-
+		case SYBLONGBINARY:
 		case SYBBINARY:
 		case SYBVARBINARY:
 		case SYBIMAGE:
@@ -371,7 +371,7 @@
 				}
 			}
 			break;
-		case SYBUNIVARCHAR:
+
 		case SYBCHAR:
 		case SYBVARCHAR:
 		case SYBTEXT:
Index: src/ctlib/ct.c
===================================================================
RCS file: /home/cvs/mirror/freetds/freetds/src/ctlib/ct.c,v
retrieving revision 1.108
diff -u -r1.108 ct.c
--- src/ctlib/ct.c	22 Nov 2003 23:05:09 -0000	1.108
+++ src/ctlib/ct.c	30 Nov 2003 10:56:16 -0000
@@ -1575,9 +1575,9 @@
 		return CS_UNIQUE_TYPE;
 		break;
 	case SYBLONGBINARY:
-		if (usertype == 35)
-			return CS_UNIVARCHAR_TYPE;
-		return CS_BINARY_TYPE;
+		if (usertype == USER_UNICHAR_TYPE || usertype == USER_UNIVARCHAR_TYPE)
+			return CS_UNICHAR_TYPE;
+		return CS_CHAR_TYPE;
 		break;
 	}
 
@@ -1646,8 +1646,8 @@
 	case CS_LONGBINARY_TYPE:	/* vicm */
 		return SYBLONGBINARY;
 		break;
-	case CS_UNIVARCHAR_TYPE:
-		return SYBUNIVARCHAR;
+	case CS_UNICHAR_TYPE:
+		return SYBVARCHAR;
 	default:
 		return -1;
 		break;
Index: src/tds/convert.c
===================================================================
RCS file: /home/cvs/mirror/freetds/freetds/src/tds/convert.c,v
retrieving revision 1.126
diff -u -r1.126 convert.c
--- src/tds/convert.c	22 Nov 2003 23:05:09 -0000	1.126
+++ src/tds/convert.c	30 Nov 2003 10:56:17 -0000
@@ -1608,7 +1608,6 @@
 	assert(srclen >= 0 && srclen <= 2147483647u);
 
 	switch (srctype) {
-	case SYBUNIVARCHAR:
 	case CASE_ALL_CHAR:
 		length = tds_convert_char(srctype, src, srclen, desttype, cr);
 		break;
@@ -1650,6 +1649,7 @@
 	case SYBDATETIME4:
 		length = tds_convert_datetime4(tds_ctx, srctype, src, desttype, cr);
 		break;
+	case SYBLONGBINARY:
 	case CASE_ALL_BINARY:
 		length = tds_convert_binary(srctype, (const TDS_UCHAR *) src, srclen, desttype, cr);
 		break;
@@ -3221,9 +3221,6 @@
 		break;
 	case SYBLONGBINARY:
 		result = "SYBLONGBINARY";
-		break;
-	case SYBUNIVARCHAR:
-		result = "SYBUNIVARCHAR";
 		break;
 	default:
 		break;
Index: src/tds/token.c
===================================================================
RCS file: /home/cvs/mirror/freetds/freetds/src/tds/token.c,v
retrieving revision 1.229
diff -u -r1.229 token.c
--- src/tds/token.c	28 Nov 2003 16:53:14 -0000	1.229
+++ src/tds/token.c	30 Nov 2003 10:56:18 -0000
@@ -1977,11 +1977,18 @@
 			if (tds_get_char_data(tds, (char *) dest, colsize, curcol) == TDS_FAIL)
 				return TDS_FAIL;
 		} else {
-			if (colsize > curcol->column_size)
-				return TDS_FAIL;
-			if (tds_get_n(tds, dest, colsize) == NULL)
-				return TDS_FAIL;
-			curcol->column_cur_size = colsize;
+			if (is_binary_type (curcol->column_type) && (
+				curcol->column_usertype == USER_UNICHAR_TYPE ||
+				curcol->column_usertype == USER_UNIVARCHAR_TYPE)) {
+				if (tds_get_char_data(tds, (char *) dest, colsize, curcol) == TDS_FAIL)
+					return TDS_FAIL;
+			} else {
+				if (colsize > curcol->column_size)
+					return TDS_FAIL;
+				if (tds_get_n(tds, dest, colsize) == NULL)
+					return TDS_FAIL;
+				curcol->column_cur_size = colsize;
+			}
 		}
 
 		/* pad CHAR and BINARY types */
@@ -1993,11 +2000,6 @@
 				break;
 			/* FIXME use client charset */
 			fillchar = ' ';
-		/* just to prevent \0 to interrupt display, as long as we cannot decode utf-16 */
-		case SYBLONGBINARY:
-			for (pos= 0; pos < colsize; pos++) {
-				if (dest[pos] == '\0') { dest[pos]= '.'; }
-			}
 		case SYBBINARY:
 		case XSYBBINARY:
 			if (colsize < curcol->column_size)
@@ -2005,6 +2007,12 @@
 			colsize = curcol->column_size;
 			break;
 		}
+		
+		/* extra handling for SYBLONGBINARY */
+		if (curcol->column_type == SYBLONGBINARY) {
+			if (curcol->column_usertype == USER_UNICHAR_TYPE)
+				fillchar= ' ';
+		}
 
 		if (curcol->column_type == SYBDATETIME4) {
 			tdsdump_log(TDS_DBG_INFO1, "%L datetime4 %d %d %d %d\n", dest[0], dest[1], dest[2], dest[3]);
@@ -3322,6 +3330,13 @@
 	/* FIXME: and sybase ?? and single char to utf8 ??? */
 	if (is_unicode_type(curcol->on_server.column_type))
 		curcol->iconv_info = tds->iconv_info[client2ucs2];
+	
+	/* Sybase UNI(VAR)CHAR fields are transmitted via SYBLONGBINARY and in UTF-16*/
+	if (curcol->on_server.column_type == SYBLONGBINARY && (
+		curcol->column_usertype == USER_UNICHAR_TYPE ||
+		curcol->column_usertype == USER_UNIVARCHAR_TYPE)) {
+		curcol->iconv_info = tds->iconv_info[client2ucs2];
+	}
 
 	if (!curcol->iconv_info && IS_TDS7_PLUS(tds) && is_ascii_type(curcol->on_server.column_type))
 		curcol->iconv_info = tds->iconv_info[client2server_chardata];



Archive powered by MHonArc 2.6.24.

Top of Page