I tested this with unixODBC 2.2.7 on SuSE Linux 8.2. I built unixODBC --with-iconv-ucode-enc=UCS-4LE and with SQL_WCHART_CONVERT defined, so that SQLWCHAR is wchar_t. I have not tested it with UCS-2 / unsigned short.
I also tested this with iODBC 3.51.1, which always uses wchar_t on Unix.
One caveat, if anyone actually plays with this: sqlext.h should include sqlucode.h, so I haven't patched psqlodbc to do so. The next release of unixODBC will contain this fix, and I've mentioned it to the iODBC maintainer.
#
# Makefile.am for psqlodbc (PostgreSQL ODBC driver)
#
-# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.9 2003/12/09 10:01:37 hinoue Exp $
+# $Header: /home/heikki/psqlodbc-cvs-copy/psqlodbc/Makefile.am,v 1.10 2004/02/04 08:55:28 dpage Exp $
#
#-------------------------------------------------------------------------
psqlodbc.h qresult.h resource.h socket.h statement.h tuple.h \
tuplelist.h version.h
+if enable_unicode
+psqlodbc_la_SOURCES += \
+ odbcapi30w.c odbcapiw.c win_unicode.c
+endif
+
EXTRA_psqlodbc_la_SOURCES = md5.c
if with_unixodbc
EXTRA_DIST = README.unix license.txt notice.txt readme.txt odbcinst.ini \
libtool.m4 psqlodbc_win32.def psqlodbc_apiw.def psqlodbc_api30w.def \
psqlodbc_api25.def win32.mak win32_30w.mak win32_25.mak \
- dlg_wingui.c win_unicode.c win_setup.h win_md5.c setup.c \
+ dlg_wingui.c win_setup.h win_md5.c setup.c \
psqlodbc.reg psqlodbc25.reg psqlodbc30w.reg
MAINTAINERCLEANFILES = odbc-drop.sql \
Makefile.in config.guess config.h.in config.sub configure \
PGAC_ARG_BOOL(with, unixodbc, no,
[ --with-unixodbc build ODBC driver for unixODBC],
[AC_DEFINE(WITH_UNIXODBC, 1,
- [Define to 1 to build with unixODBC support (--with-unixodbc)])])
+ [Define to 1 to build with unixODBC support (--with-unixodbc)])
+ AC_DEFINE(SQL_WCHART_CONVERT, [], [Define to use wchar_t as SQLWCHAR in unixODBC])])
PGAC_ARG_BOOL(with, iodbc, no,
[ --with-iodbc build ODBC driver for iODBC],
[Define to ODBC version (--with-odbcver)])])
AC_MSG_RESULT([$with_odbcver])
+# to implement the Unicode driver
+AC_ARG_ENABLE(unicode,
+ [ --enable-unicode build ODBC driver for Unicode],
+ [AC_DEFINE(UNICODE_SUPPORT, 1,
+ [Define to 1 to build with Unicode support (--enable-unicode)])
+ AC_DEFINE(UNICODE, [],
+ [Define to use wide APIs])
+ AC_DEFINE(SQL_NOUNICODEMAP, [],
+ [Define to disable mapping SQL* to SQL*W])
+ AC_CHECK_FUNCS(iswascii)])
+
AM_CONDITIONAL(with_unixodbc, [test $with_unixodbc = yes])
AM_CONDITIONAL(with_iodbc, [test $with_iodbc = yes])
+AM_CONDITIONAL(enable_unicode, [test x"$enable_unicode" = xyes])
AC_CHECK_FUNCS(strtoul strtoll)
AC_CHECK_LIB(socket, socket)
if (fCType == SQL_C_WCHAR)
{
len = utf8_to_ucs2_lf(neut_str, -1, lf_conv, NULL, 0);
- len *= 2;
+ len *= WCLEN;
wchanged = changed = TRUE;
}
else
#ifdef UNICODE_SUPPORT
if (fCType == SQL_C_WCHAR)
{
- utf8_to_ucs2_lf(neut_str, -1, lf_conv, (SQLWCHAR *) pgdc->ttlbuf, len / 2);
+ utf8_to_ucs2_lf(neut_str, -1, lf_conv, (SQLWCHAR *) pgdc->ttlbuf, len / WCLEN);
}
else
#endif /* UNICODE_SUPPORT */
#ifdef UNICODE_SUPPORT
if (SQL_C_WCHAR == fCType && ! wchanged)
{
- if (cbValueMax > 2 * len)
+ if (cbValueMax > WCLEN * len)
{
char *str = strdup(rgbValueBindRow);
- UInt4 ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / 2);
- if (cbValueMax < 2 * (SDWORD) ucount)
+ UInt4 ucount = utf8_to_ucs2(str, len, (SQLWCHAR *) rgbValueBindRow, cbValueMax / WCLEN);
+ if (cbValueMax < WCLEN * (SDWORD) ucount)
result = COPY_RESULT_TRUNCATED;
- len = ucount * 2;
+ len = ucount * WCLEN;
free(str);
}
else
{
- len *= 2;
+ len *= WCLEN;
result = COPY_RESULT_TRUNCATED;
}
}
#ifdef UNICODE_SUPPORT
case SQL_C_WCHAR:
- buf = allocbuf = ucs2_to_utf8((SQLWCHAR *) buffer, used / 2, &used, FALSE);
- used *= 2;
+ buf = allocbuf = ucs2_to_utf8((SQLWCHAR *) buffer, used / WCLEN, &used, FALSE);
+ used *= WCLEN;
break;
#endif /* UNICODE_SUPPORT */
#ifdef UNICODE_SUPPORT
if (SQL_C_WCHAR == ctype)
{
- putlen = 2 * ucs2strlen((SQLWCHAR *) rgbValue);
+ putlen = WCLEN * ucs2strlen((SQLWCHAR *) rgbValue);
lenset = TRUE;
}
else
if (conn->unicode)
{
len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2);
- len *= 2;
+ len *= WCLEN;
}
else
#endif /* UNICODE_SUPPORT */
if (conn->unicode)
{
len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / 2);
- len *= 2;
+ len *= WCLEN;
}
else
#endif /* UNICODE_SUPPORT */
*
* Comments: See "notice.txt" for copyright and license information.
*
- * $Id: psqlodbc.h,v 1.81 2003/12/09 10:01:38 hinoue Exp $
+ * $Id: psqlodbc.h,v 1.82 2004/02/04 08:55:28 dpage Exp $
*
*/
const pthread_mutexattr_t *getMutexAttr(void);
#endif /* POSIX_THREADMUTEX_SUPPORT */
#ifdef UNICODE_SUPPORT
+#define WCLEN sizeof(SQLWCHAR)
UInt4 ucs2strlen(const SQLWCHAR *ucs2str);
char *ucs2_to_utf8(const SQLWCHAR *ucs2str, Int4 ilen, UInt4 *olen, BOOL tolower);
UInt4 utf8_to_ucs2_lf(const char * utf8str, Int4 ilen, BOOL lfconv, SQLWCHAR *ucs2str, UInt4 buflen);
#include <stdio.h>
#include <string.h>
-#define byte3check 0xf800
+#define byte3check 0xfffff800
#define byte2_base 0x80c0
#define byte2_mask1 0x07c0
#define byte2_mask2 0x003f
#define byte3_mask2 0x0fc0
#define byte3_mask3 0x003f
+#ifndef WIN32
+#ifdef HAVE_ISWASCII
+#include <wctype.h>
+#else
+#include <wchar.h>
+#include <ctype.h>
+int iswascii(wchar_t c)
+{
+ return isascii(wctob(c));
+}
+#endif /* HAVE_ISWASCII */
+#endif /* WIN32 */
+
UInt4 ucs2strlen(const SQLWCHAR *ucs2str)
{
UInt4 len;
{
if (!*wstr)
break;
- else if (0 == (*wstr & 0xff80)) /* ASCII */
+ else if (0 == (*wstr & 0xffffff80)) /* ASCII */
{
if (lower_identifier)
utf8str[len++] = (char) tolower(*wstr);